mirror of
https://github.com/JulianGro/overte.git
synced 2025-05-07 15:39:51 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into 19483
This commit is contained in:
commit
b17d4a3ec9
107 changed files with 1112 additions and 2030 deletions
|
@ -598,10 +598,10 @@ void* animateVoxels(void* args) {
|
||||||
|
|
||||||
bool firstTime = true;
|
bool firstTime = true;
|
||||||
|
|
||||||
qDebug() << "Setting PPS to " << ::packetsPerSecond << "\n";
|
qDebug() << "Setting PPS to " << ::packetsPerSecond;
|
||||||
::voxelEditPacketSender->setPacketsPerSecond(::packetsPerSecond);
|
::voxelEditPacketSender->setPacketsPerSecond(::packetsPerSecond);
|
||||||
|
|
||||||
qDebug() << "PPS set to " << ::voxelEditPacketSender->getPacketsPerSecond() << "\n";
|
qDebug() << "PPS set to " << ::voxelEditPacketSender->getPacketsPerSecond();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ void Agent::run() {
|
||||||
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
|
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
|
||||||
QNetworkReply *reply = networkManager->get(QNetworkRequest(QUrl(scriptURLString)));
|
QNetworkReply *reply = networkManager->get(QNetworkRequest(QUrl(scriptURLString)));
|
||||||
|
|
||||||
qDebug() << "Downloading script at" << scriptURLString << "\n";
|
qDebug() << "Downloading script at" << scriptURLString;
|
||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||||
|
@ -76,7 +76,7 @@ void Agent::run() {
|
||||||
|
|
||||||
QString scriptContents(reply->readAll());
|
QString scriptContents(reply->readAll());
|
||||||
|
|
||||||
qDebug() << "Downloaded script:" << scriptContents << "\n";
|
qDebug() << "Downloaded script:" << scriptContents;
|
||||||
|
|
||||||
timeval startTime;
|
timeval startTime;
|
||||||
gettimeofday(&startTime, NULL);
|
gettimeofday(&startTime, NULL);
|
||||||
|
|
|
@ -83,7 +83,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required
|
// call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required
|
||||||
qDebug() << "Waiting for assignment -" << _requestAssignment << "\n";
|
qDebug() << "Waiting for assignment -" << _requestAssignment;
|
||||||
|
|
||||||
QTimer* timer = new QTimer(this);
|
QTimer* timer = new QTimer(this);
|
||||||
connect(timer, SIGNAL(timeout()), SLOT(sendAssignmentRequest()));
|
connect(timer, SIGNAL(timeout()), SLOT(sendAssignmentRequest()));
|
||||||
|
@ -121,20 +121,19 @@ void AssignmentClient::readPendingDatagrams() {
|
||||||
} else if (packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT || packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
} else if (packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT || packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
||||||
|
|
||||||
if (_currentAssignment) {
|
if (_currentAssignment) {
|
||||||
qDebug() << "Dropping received assignment since we are currently running one.\n";
|
qDebug() << "Dropping received assignment since we are currently running one.";
|
||||||
} else {
|
} else {
|
||||||
// construct the deployed assignment from the packet data
|
// construct the deployed assignment from the packet data
|
||||||
_currentAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes);
|
_currentAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes);
|
||||||
|
|
||||||
qDebug() << "Received an assignment -" << *_currentAssignment << "\n";
|
qDebug() << "Received an assignment -" << *_currentAssignment;
|
||||||
|
|
||||||
// switch our nodelist domain IP and port to whoever sent us the assignment
|
// switch our nodelist domain IP and port to whoever sent us the assignment
|
||||||
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
||||||
nodeList->setDomainSockAddr(senderSockAddr);
|
nodeList->setDomainSockAddr(senderSockAddr);
|
||||||
nodeList->setOwnerUUID(_currentAssignment->getUUID());
|
nodeList->setOwnerUUID(_currentAssignment->getUUID());
|
||||||
|
|
||||||
qDebug("Destination IP for assignment is %s\n",
|
qDebug() << "Destination IP for assignment is" << nodeList->getDomainIP().toString();
|
||||||
nodeList->getDomainIP().toString().toStdString().c_str());
|
|
||||||
|
|
||||||
// start the deployed assignment
|
// start the deployed assignment
|
||||||
QThread* workerThread = new QThread(this);
|
QThread* workerThread = new QThread(this);
|
||||||
|
@ -148,10 +147,13 @@ void AssignmentClient::readPendingDatagrams() {
|
||||||
|
|
||||||
_currentAssignment->moveToThread(workerThread);
|
_currentAssignment->moveToThread(workerThread);
|
||||||
|
|
||||||
|
// move the NodeList to the thread used for the _current assignment
|
||||||
|
nodeList->moveToThread(workerThread);
|
||||||
|
|
||||||
// Starts an event loop, and emits workerThread->started()
|
// Starts an event loop, and emits workerThread->started()
|
||||||
workerThread->start();
|
workerThread->start();
|
||||||
} else {
|
} else {
|
||||||
qDebug("Received a bad destination socket for assignment.\n");
|
qDebug("Received a bad destination socket for assignment.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -166,12 +168,15 @@ void AssignmentClient::assignmentCompleted() {
|
||||||
// reset the logging target to the the CHILD_TARGET_NAME
|
// reset the logging target to the the CHILD_TARGET_NAME
|
||||||
Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
|
Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
|
||||||
|
|
||||||
qDebug("Assignment finished or never started - waiting for new assignment\n");
|
qDebug("Assignment finished or never started - waiting for new assignment.");
|
||||||
|
|
||||||
_currentAssignment = NULL;
|
_currentAssignment = NULL;
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
// move the NodeList back to our thread
|
||||||
|
nodeList->moveToThread(thread());
|
||||||
|
|
||||||
// reset our NodeList by switching back to unassigned and clearing the list
|
// reset our NodeList by switching back to unassigned and clearing the list
|
||||||
nodeList->setOwnerType(NODE_TYPE_UNASSIGNED);
|
nodeList->setOwnerType(NODE_TYPE_UNASSIGNED);
|
||||||
nodeList->reset();
|
nodeList->reset();
|
||||||
|
|
|
@ -47,10 +47,10 @@ void AssignmentClientMonitor::spawnChildClient() {
|
||||||
connect(assignmentClient, SIGNAL(finished(int, QProcess::ExitStatus)), this,
|
connect(assignmentClient, SIGNAL(finished(int, QProcess::ExitStatus)), this,
|
||||||
SLOT(childProcessFinished(int, QProcess::ExitStatus)));
|
SLOT(childProcessFinished(int, QProcess::ExitStatus)));
|
||||||
|
|
||||||
qDebug() << "Spawned a child client with PID" << assignmentClient->pid() << "\n";
|
qDebug() << "Spawned a child client with PID" << assignmentClient->pid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignmentClientMonitor::childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) {
|
void AssignmentClientMonitor::childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) {
|
||||||
qDebug() << "Replacing dead child assignment client with a new one.\n";
|
qDebug("Replacing dead child assignment client with a new one");
|
||||||
spawnChildClient();
|
spawnChildClient();
|
||||||
}
|
}
|
|
@ -182,15 +182,13 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixer::prepareMixForListeningNode(Node* node) {
|
void AudioMixer::prepareMixForListeningNode(Node* node) {
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
|
|
||||||
AvatarAudioRingBuffer* nodeRingBuffer = ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer();
|
AvatarAudioRingBuffer* nodeRingBuffer = ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer();
|
||||||
|
|
||||||
// zero out the client mix for this node
|
// zero out the client mix for this node
|
||||||
memset(_clientSamples, 0, sizeof(_clientSamples));
|
memset(_clientSamples, 0, sizeof(_clientSamples));
|
||||||
|
|
||||||
// loop through all other nodes that have sufficient audio to mix
|
// loop through all other nodes that have sufficient audio to mix
|
||||||
for (NodeList::iterator otherNode = nodeList->begin(); otherNode != nodeList->end(); otherNode++) {
|
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
|
||||||
if (otherNode->getLinkedData()) {
|
if (otherNode->getLinkedData()) {
|
||||||
|
|
||||||
AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData();
|
AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData();
|
||||||
|
@ -200,7 +198,7 @@ void AudioMixer::prepareMixForListeningNode(Node* node) {
|
||||||
PositionalAudioRingBuffer* otherNodeBuffer = otherNodeClientData->getRingBuffers()[i];
|
PositionalAudioRingBuffer* otherNodeBuffer = otherNodeClientData->getRingBuffers()[i];
|
||||||
|
|
||||||
if ((*otherNode != *node
|
if ((*otherNode != *node
|
||||||
|| otherNodeBuffer->shouldLoopbackForNode())
|
|| otherNodeBuffer->shouldLoopbackForNode())
|
||||||
&& otherNodeBuffer->willBeAddedToMix()) {
|
&& otherNodeBuffer->willBeAddedToMix()) {
|
||||||
addBufferToMixForListeningNodeWithBuffer(otherNodeBuffer, nodeRingBuffer);
|
addBufferToMixForListeningNodeWithBuffer(otherNodeBuffer, nodeRingBuffer);
|
||||||
}
|
}
|
||||||
|
@ -220,10 +218,10 @@ void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSock
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
Node* matchingNode = nodeList->nodeWithUUID(nodeUUID);
|
SharedNodePointer matchingNode = nodeList->nodeWithUUID(nodeUUID);
|
||||||
|
|
||||||
if (matchingNode) {
|
if (matchingNode) {
|
||||||
nodeList->updateNodeWithData(matchingNode, senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
nodeList->updateNodeWithData(matchingNode.data(), senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||||
|
|
||||||
if (!matchingNode->getActiveSocket()) {
|
if (!matchingNode->getActiveSocket()) {
|
||||||
// we don't have an active socket for this node, but they're talking to us
|
// we don't have an active socket for this node, but they're talking to us
|
||||||
|
@ -264,17 +262,17 @@ void AudioMixer::run() {
|
||||||
if (_isFinished) {
|
if (_isFinished) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES);
|
((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getType() == NODE_TYPE_AGENT && node->getActiveSocket() && node->getLinkedData()
|
if (node->getType() == NODE_TYPE_AGENT && node->getActiveSocket() && node->getLinkedData()
|
||||||
&& ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) {
|
&& ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) {
|
||||||
prepareMixForListeningNode(&(*node));
|
prepareMixForListeningNode(node.data());
|
||||||
|
|
||||||
memcpy(clientPacket + numBytesPacketHeader, _clientSamples, sizeof(_clientSamples));
|
memcpy(clientPacket + numBytesPacketHeader, _clientSamples, sizeof(_clientSamples));
|
||||||
nodeList->getNodeSocket().writeDatagram((char*) clientPacket, sizeof(clientPacket),
|
nodeList->getNodeSocket().writeDatagram((char*) clientPacket, sizeof(clientPacket),
|
||||||
|
@ -284,18 +282,19 @@ void AudioMixer::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// push forward the next output pointers for any audio buffers we used
|
// push forward the next output pointers for any audio buffers we used
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
((AudioMixerClientData*) node->getLinkedData())->pushBuffersAfterFrameSend();
|
((AudioMixerClientData*) node->getLinkedData())->pushBuffersAfterFrameSend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow();
|
int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow();
|
||||||
|
|
||||||
if (usecToSleep > 0) {
|
if (usecToSleep > 0) {
|
||||||
usleep(usecToSleep);
|
usleep(usecToSleep);
|
||||||
} else {
|
} else {
|
||||||
qDebug("Took too much time, not sleeping!\n");
|
qDebug() << "AudioMixer loop took" << -usecToSleep << "of extra time. Not sleeping.";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ void broadcastAvatarData() {
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT && node->getActiveSocket()) {
|
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT && node->getActiveSocket()) {
|
||||||
|
|
||||||
// reset packet pointers for this node
|
// reset packet pointers for this node
|
||||||
|
@ -76,11 +76,11 @@ void broadcastAvatarData() {
|
||||||
|
|
||||||
// this is an AGENT we have received head data from
|
// this is an AGENT we have received head data from
|
||||||
// send back a packet with other active node data to this node
|
// send back a packet with other active node data to this node
|
||||||
for (NodeList::iterator otherNode = nodeList->begin(); otherNode != nodeList->end(); otherNode++) {
|
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
|
||||||
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()) {
|
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()) {
|
||||||
|
|
||||||
unsigned char* avatarDataEndpoint = addNodeToBroadcastPacket((unsigned char*)&avatarDataBuffer[0],
|
unsigned char* avatarDataEndpoint = addNodeToBroadcastPacket((unsigned char*)&avatarDataBuffer[0],
|
||||||
&*otherNode);
|
otherNode.data());
|
||||||
int avatarDataLength = avatarDataEndpoint - (unsigned char*)&avatarDataBuffer;
|
int avatarDataLength = avatarDataEndpoint - (unsigned char*)&avatarDataBuffer;
|
||||||
|
|
||||||
if (avatarDataLength + packetLength <= MAX_PACKET_SIZE) {
|
if (avatarDataLength + packetLength <= MAX_PACKET_SIZE) {
|
||||||
|
@ -109,13 +109,11 @@ void broadcastAvatarData() {
|
||||||
|
|
||||||
packetsSent++;
|
packetsSent++;
|
||||||
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
|
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
|
||||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket,
|
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket,
|
||||||
node->getActiveSocket()->getAddress(),
|
node->getActiveSocket()->getAddress(),
|
||||||
node->getActiveSocket()->getPort());
|
node->getActiveSocket()->getPort());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
||||||
|
@ -128,11 +126,11 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc
|
||||||
NUM_BYTES_RFC4122_UUID));
|
NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
// add or update the node in our list
|
// add or update the node in our list
|
||||||
Node* avatarNode = nodeList->nodeWithUUID(nodeUUID);
|
SharedNodePointer avatarNode = nodeList->nodeWithUUID(nodeUUID);
|
||||||
|
|
||||||
if (avatarNode) {
|
if (avatarNode) {
|
||||||
// parse positional data from an node
|
// parse positional data from an node
|
||||||
nodeList->updateNodeWithData(avatarNode, senderSockAddr,
|
nodeList->updateNodeWithData(avatarNode.data(), senderSockAddr,
|
||||||
(unsigned char*) dataByteArray.data(), dataByteArray.size());
|
(unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -144,7 +142,7 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc
|
||||||
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader((unsigned char*) dataByteArray.data()),
|
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader((unsigned char*) dataByteArray.data()),
|
||||||
NUM_BYTES_RFC4122_UUID));
|
NUM_BYTES_RFC4122_UUID));
|
||||||
// let everyone else know about the update
|
// let everyone else know about the update
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getActiveSocket() && node->getUUID() != nodeUUID) {
|
if (node->getActiveSocket() && node->getUUID() != nodeUUID) {
|
||||||
nodeList->getNodeSocket().writeDatagram(dataByteArray,
|
nodeList->getNodeSocket().writeDatagram(dataByteArray,
|
||||||
node->getActiveSocket()->getAddress(),
|
node->getActiveSocket()->getAddress(),
|
||||||
|
@ -189,7 +187,7 @@ void AvatarMixer::run() {
|
||||||
if (usecToSleep > 0) {
|
if (usecToSleep > 0) {
|
||||||
usleep(usecToSleep);
|
usleep(usecToSleep);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Took too much time, not sleeping!\n";
|
qDebug() << "AvatarMixer loop took too" << -usecToSleep << "of extra time. Won't sleep.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,10 @@ void MetavoxelServer::removeSession(const QUuid& sessionId) {
|
||||||
delete _sessions.take(sessionId);
|
delete _sessions.take(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char METAVOXEL_SERVER_LOGGING_NAME[] = "avatar-mixer";
|
||||||
|
|
||||||
void MetavoxelServer::run() {
|
void MetavoxelServer::run() {
|
||||||
commonInit("metavoxel-server", NODE_TYPE_METAVOXEL_SERVER);
|
commonInit(METAVOXEL_SERVER_LOGGING_NAME, NODE_TYPE_METAVOXEL_SERVER);
|
||||||
|
|
||||||
_lastSend = QDateTime::currentMSecsSinceEpoch();
|
_lastSend = QDateTime::currentMSecsSinceEpoch();
|
||||||
_sendTimer.start(SEND_INTERVAL);
|
_sendTimer.start(SEND_INTERVAL);
|
||||||
|
@ -121,7 +123,7 @@ void MetavoxelSession::sendDelta() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelSession::timedOut() {
|
void MetavoxelSession::timedOut() {
|
||||||
qDebug() << "Session timed out [sessionId=" << _sessionId << ", sender=" << _sender << "]\n";
|
qDebug() << "Session timed out [sessionId=" << _sessionId << ", sender=" << _sender << "]";
|
||||||
_server->removeSession(_sessionId);
|
_server->removeSession(_sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
// Start the web server.
|
// Start the web server.
|
||||||
mg_start(&callbacks, NULL, options);
|
mg_start(&callbacks, NULL, options);
|
||||||
|
|
||||||
nodeList->addHook(this);
|
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), this, SLOT(nodeKilled(SharedNodePointer)));
|
||||||
|
|
||||||
if (!_staticAssignmentFile.exists() || _voxelServerConfig) {
|
if (!_staticAssignmentFile.exists() || _voxelServerConfig) {
|
||||||
|
|
||||||
|
@ -171,10 +171,10 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
nodeLocalAddress,
|
nodeLocalAddress,
|
||||||
nodeUUID)))
|
nodeUUID)))
|
||||||
{
|
{
|
||||||
Node* checkInNode = nodeList->addOrUpdateNode(nodeUUID,
|
SharedNodePointer checkInNode = nodeList->addOrUpdateNode(nodeUUID,
|
||||||
nodeType,
|
nodeType,
|
||||||
nodePublicAddress,
|
nodePublicAddress,
|
||||||
nodeLocalAddress);
|
nodeLocalAddress);
|
||||||
|
|
||||||
if (matchingStaticAssignment) {
|
if (matchingStaticAssignment) {
|
||||||
// this was a newly added node with a matching static assignment
|
// this was a newly added node with a matching static assignment
|
||||||
|
@ -201,13 +201,13 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
|
|
||||||
if (numInterestTypes > 0) {
|
if (numInterestTypes > 0) {
|
||||||
// if the node has sent no types of interest, assume they want nothing but their own ID back
|
// 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++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getUUID() != nodeUUID &&
|
if (node->getUUID() != nodeUUID &&
|
||||||
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
||||||
|
|
||||||
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
||||||
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
||||||
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node));
|
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, node.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,8 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
// construct the requested assignment from the packet data
|
// construct the requested assignment from the packet data
|
||||||
Assignment requestAssignment(packetData, receivedBytes);
|
Assignment requestAssignment(packetData, receivedBytes);
|
||||||
|
|
||||||
qDebug("Received a request for assignment type %i from %s.\n", requestAssignment.getType(), qPrintable(senderSockAddr.getAddress().toString()));
|
qDebug("Received a request for assignment type %i from %s.",
|
||||||
|
requestAssignment.getType(), qPrintable(senderSockAddr.getAddress().toString()));
|
||||||
|
|
||||||
Assignment* assignmentToDeploy = deployableAssignmentForRequest(requestAssignment);
|
Assignment* assignmentToDeploy = deployableAssignmentForRequest(requestAssignment);
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
qDebug("Received an invalid assignment request from %s.\n", qPrintable(senderSockAddr.getAddress().toString()));
|
qDebug() << "Received an invalid assignment request from" << senderSockAddr.getAddress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,13 +319,11 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
||||||
QJsonObject assignedNodesJSON;
|
QJsonObject assignedNodesJSON;
|
||||||
|
|
||||||
// enumerate the NodeList to find the assigned nodes
|
// enumerate the NodeList to find the assigned nodes
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
// add the node using the UUID as the key
|
// add the node using the UUID as the key
|
||||||
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||||
assignedNodesJSON[uuidString] = jsonObjectForNode(&(*node));
|
assignedNodesJSON[uuidString] = jsonObjectForNode(node.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,10 +371,10 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
||||||
// enumerate the NodeList to find the assigned nodes
|
// enumerate the NodeList to find the assigned nodes
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
// add the node using the UUID as the key
|
// add the node using the UUID as the key
|
||||||
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||||
nodesJSON[uuidString] = jsonObjectForNode(&(*node));
|
nodesJSON[uuidString] = jsonObjectForNode(node.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
rootJSON["nodes"] = nodesJSON;
|
rootJSON["nodes"] = nodesJSON;
|
||||||
|
@ -410,14 +409,14 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
||||||
QUuid deleteUUID = QUuid(QString(ri->uri + strlen(URI_NODE) + sizeof('/')));
|
QUuid deleteUUID = QUuid(QString(ri->uri + strlen(URI_NODE) + sizeof('/')));
|
||||||
|
|
||||||
if (!deleteUUID.isNull()) {
|
if (!deleteUUID.isNull()) {
|
||||||
Node *nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);
|
SharedNodePointer nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);
|
||||||
|
|
||||||
if (nodeToKill) {
|
if (nodeToKill) {
|
||||||
// start with a 200 response
|
// start with a 200 response
|
||||||
mg_printf(connection, "%s", RESPONSE_200);
|
mg_printf(connection, "%s", RESPONSE_200);
|
||||||
|
|
||||||
// we have a valid UUID and node - kill the node that has this assignment
|
// we have a valid UUID and node - kill the node that has this assignment
|
||||||
NodeList::getInstance()->killNode(nodeToKill);
|
NodeList::getInstance()->killNodeWithUUID(deleteUUID);
|
||||||
|
|
||||||
// successfully processed request
|
// successfully processed request
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -464,7 +463,7 @@ void DomainServer::civetwebUploadHandler(struct mg_connection *connection, const
|
||||||
// rename the saved script to the GUID of the assignment and move it to the script host locaiton
|
// rename the saved script to the GUID of the assignment and move it to the script host locaiton
|
||||||
rename(path, newPath.toLocal8Bit().constData());
|
rename(path, newPath.toLocal8Bit().constData());
|
||||||
|
|
||||||
qDebug("Saved a script for assignment at %s\n", newPath.toLocal8Bit().constData());
|
qDebug("Saved a script for assignment at %s", newPath.toLocal8Bit().constData());
|
||||||
|
|
||||||
// add the script assigment to the assignment queue
|
// add the script assigment to the assignment queue
|
||||||
// lock the assignment queue mutex since we're operating on a different thread than DS main
|
// lock the assignment queue mutex since we're operating on a different thread than DS main
|
||||||
|
@ -474,7 +473,7 @@ void DomainServer::civetwebUploadHandler(struct mg_connection *connection, const
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::addReleasedAssignmentBackToQueue(Assignment* releasedAssignment) {
|
void DomainServer::addReleasedAssignmentBackToQueue(Assignment* releasedAssignment) {
|
||||||
qDebug() << "Adding assignment" << *releasedAssignment << " back to queue.\n";
|
qDebug() << "Adding assignment" << *releasedAssignment << " back to queue.";
|
||||||
|
|
||||||
// find this assignment in the static file
|
// find this assignment in the static file
|
||||||
for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) {
|
for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) {
|
||||||
|
@ -494,11 +493,7 @@ void DomainServer::addReleasedAssignmentBackToQueue(Assignment* releasedAssignme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::nodeAdded(Node* node) {
|
void DomainServer::nodeKilled(SharedNodePointer node) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void DomainServer::nodeKilled(Node* node) {
|
|
||||||
// if this node has linked data it was from an assignment
|
// if this node has linked data it was from an assignment
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
Assignment* nodeAssignment = (Assignment*) node->getLinkedData();
|
Assignment* nodeAssignment = (Assignment*) node->getLinkedData();
|
||||||
|
@ -535,8 +530,8 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
||||||
|
|
||||||
// Handle Domain/Voxel Server configuration command line arguments
|
// Handle Domain/Voxel Server configuration command line arguments
|
||||||
if (_voxelServerConfig) {
|
if (_voxelServerConfig) {
|
||||||
qDebug("Reading Voxel Server Configuration.\n");
|
qDebug("Reading Voxel Server Configuration.");
|
||||||
qDebug() << "config: " << _voxelServerConfig << "\n";
|
qDebug() << "config: " << _voxelServerConfig;
|
||||||
|
|
||||||
QString multiConfig((const char*) _voxelServerConfig);
|
QString multiConfig((const char*) _voxelServerConfig);
|
||||||
QStringList multiConfigList = multiConfig.split(";");
|
QStringList multiConfigList = multiConfig.split(";");
|
||||||
|
@ -545,7 +540,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
||||||
for (int i = 0; i < multiConfigList.size(); i++) {
|
for (int i = 0; i < multiConfigList.size(); i++) {
|
||||||
QString config = multiConfigList.at(i);
|
QString config = multiConfigList.at(i);
|
||||||
|
|
||||||
qDebug("config[%d]=%s\n", i, config.toLocal8Bit().constData());
|
qDebug("config[%d]=%s", i, config.toLocal8Bit().constData());
|
||||||
|
|
||||||
// Now, parse the config to check for a pool
|
// Now, parse the config to check for a pool
|
||||||
const char ASSIGNMENT_CONFIG_POOL_OPTION[] = "--pool";
|
const char ASSIGNMENT_CONFIG_POOL_OPTION[] = "--pool";
|
||||||
|
@ -558,7 +553,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
||||||
int spaceAfterPoolIndex = config.indexOf(' ', spaceBeforePoolIndex);
|
int spaceAfterPoolIndex = config.indexOf(' ', spaceBeforePoolIndex);
|
||||||
|
|
||||||
assignmentPool = config.mid(spaceBeforePoolIndex + 1, spaceAfterPoolIndex);
|
assignmentPool = config.mid(spaceBeforePoolIndex + 1, spaceAfterPoolIndex);
|
||||||
qDebug() << "The pool for this voxel-assignment is" << assignmentPool << "\n";
|
qDebug() << "The pool for this voxel-assignment is" << assignmentPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assignment voxelServerAssignment(Assignment::CreateCommand,
|
Assignment voxelServerAssignment(Assignment::CreateCommand,
|
||||||
|
@ -577,8 +572,8 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
||||||
|
|
||||||
// Handle Domain/Particle Server configuration command line arguments
|
// Handle Domain/Particle Server configuration command line arguments
|
||||||
if (_particleServerConfig) {
|
if (_particleServerConfig) {
|
||||||
qDebug("Reading Particle Server Configuration.\n");
|
qDebug("Reading Particle Server Configuration.");
|
||||||
qDebug() << "config: " << _particleServerConfig << "\n";
|
qDebug() << "config: " << _particleServerConfig;
|
||||||
|
|
||||||
QString multiConfig((const char*) _particleServerConfig);
|
QString multiConfig((const char*) _particleServerConfig);
|
||||||
QStringList multiConfigList = multiConfig.split(";");
|
QStringList multiConfigList = multiConfig.split(";");
|
||||||
|
@ -587,7 +582,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
||||||
for (int i = 0; i < multiConfigList.size(); i++) {
|
for (int i = 0; i < multiConfigList.size(); i++) {
|
||||||
QString config = multiConfigList.at(i);
|
QString config = multiConfigList.at(i);
|
||||||
|
|
||||||
qDebug("config[%d]=%s\n", i, config.toLocal8Bit().constData());
|
qDebug("config[%d]=%s", i, config.toLocal8Bit().constData());
|
||||||
|
|
||||||
// Now, parse the config to check for a pool
|
// Now, parse the config to check for a pool
|
||||||
const char ASSIGNMENT_CONFIG_POOL_OPTION[] = "--pool";
|
const char ASSIGNMENT_CONFIG_POOL_OPTION[] = "--pool";
|
||||||
|
@ -600,7 +595,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
||||||
int spaceAfterPoolIndex = config.indexOf(' ', spaceBeforePoolIndex);
|
int spaceAfterPoolIndex = config.indexOf(' ', spaceBeforePoolIndex);
|
||||||
|
|
||||||
assignmentPool = config.mid(spaceBeforePoolIndex + 1, spaceAfterPoolIndex);
|
assignmentPool = config.mid(spaceBeforePoolIndex + 1, spaceAfterPoolIndex);
|
||||||
qDebug() << "The pool for this particle-assignment is" << assignmentPool << "\n";
|
qDebug() << "The pool for this particle-assignment is" << assignmentPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assignment particleServerAssignment(Assignment::CreateCommand,
|
Assignment particleServerAssignment(Assignment::CreateCommand,
|
||||||
|
@ -624,7 +619,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
||||||
metavoxelAssignment.setPayload((const unsigned char*)_metavoxelServerConfig, strlen(_metavoxelServerConfig));
|
metavoxelAssignment.setPayload((const unsigned char*)_metavoxelServerConfig, strlen(_metavoxelServerConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Adding" << numFreshStaticAssignments << "static assignments to fresh file.\n";
|
qDebug() << "Adding" << numFreshStaticAssignments << "static assignments to fresh file.";
|
||||||
|
|
||||||
_staticAssignmentFile.open(QIODevice::WriteOnly);
|
_staticAssignmentFile.open(QIODevice::WriteOnly);
|
||||||
_staticAssignmentFile.write((char*) &freshStaticAssignments, sizeof(freshStaticAssignments));
|
_staticAssignmentFile.write((char*) &freshStaticAssignments, sizeof(freshStaticAssignments));
|
||||||
|
@ -741,7 +736,7 @@ bool DomainServer::checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePu
|
||||||
const QUuid& checkInUUID) {
|
const QUuid& checkInUUID) {
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getLinkedData()
|
if (node->getLinkedData()
|
||||||
&& nodePublicSocket == node->getPublicSocket()
|
&& nodePublicSocket == node->getPublicSocket()
|
||||||
&& nodeLocalSocket == node->getLocalSocket()
|
&& nodeLocalSocket == node->getLocalSocket()
|
||||||
|
@ -773,7 +768,7 @@ void DomainServer::addStaticAssignmentsBackToQueueAfterRestart() {
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
// enumerate the nodes and check if there is one with an attached assignment with matching UUID
|
// enumerate the nodes and check if there is one with an attached assignment with matching UUID
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
Assignment* linkedAssignment = (Assignment*) node->getLinkedData();
|
Assignment* linkedAssignment = (Assignment*) node->getLinkedData();
|
||||||
if (linkedAssignment->getUUID() == _staticAssignments[i].getUUID()) {
|
if (linkedAssignment->getUUID() == _staticAssignments[i].getUUID()) {
|
||||||
|
@ -787,7 +782,7 @@ void DomainServer::addStaticAssignmentsBackToQueueAfterRestart() {
|
||||||
// this assignment has not been fulfilled - reset the UUID and add it to the assignment queue
|
// this assignment has not been fulfilled - reset the UUID and add it to the assignment queue
|
||||||
_staticAssignments[i].resetUUID();
|
_staticAssignments[i].resetUUID();
|
||||||
|
|
||||||
qDebug() << "Adding static assignment to queue -" << _staticAssignments[i] << "\n";
|
qDebug() << "Adding static assignment to queue -" << _staticAssignments[i];
|
||||||
|
|
||||||
_assignmentQueueMutex.lock();
|
_assignmentQueueMutex.lock();
|
||||||
_assignmentQueue.push_back(&_staticAssignments[i]);
|
_assignmentQueue.push_back(&_staticAssignments[i]);
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
const int MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS = 1000;
|
const int MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS = 1000;
|
||||||
|
|
||||||
class DomainServer : public QCoreApplication, public NodeListHook {
|
class DomainServer : public QCoreApplication {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DomainServer(int argc, char* argv[]);
|
DomainServer(int argc, char* argv[]);
|
||||||
|
@ -31,10 +31,10 @@ public:
|
||||||
|
|
||||||
static void setDomainServerInstance(DomainServer* domainServer);
|
static void setDomainServerInstance(DomainServer* domainServer);
|
||||||
|
|
||||||
/// Called by NodeList to inform us that a node has been added.
|
public slots:
|
||||||
void nodeAdded(Node* node);
|
|
||||||
/// Called by NodeList to inform us that a node has been killed.
|
/// Called by NodeList to inform us that a node has been killed.
|
||||||
void nodeKilled(Node* node);
|
void nodeKilled(SharedNodePointer node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int civetwebRequestHandler(struct mg_connection *connection);
|
static int civetwebRequestHandler(struct mg_connection *connection);
|
||||||
static void civetwebUploadHandler(struct mg_connection *connection, const char *path);
|
static void civetwebUploadHandler(struct mg_connection *connection, const char *path);
|
||||||
|
|
|
@ -86,15 +86,15 @@ const float MIRROR_REARVIEW_DISTANCE = 0.65f;
|
||||||
const float MIRROR_REARVIEW_BODY_DISTANCE = 2.3f;
|
const float MIRROR_REARVIEW_BODY_DISTANCE = 2.3f;
|
||||||
|
|
||||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) {
|
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) {
|
||||||
fprintf(stdout, "%s", message.toLocal8Bit().constData());
|
QString messageWithNewLine = message + "\n";
|
||||||
Application::getInstance()->getLogger()->addMessage(message.toLocal8Bit().constData());
|
fprintf(stdout, "%s", messageWithNewLine.toLocal8Bit().constData());
|
||||||
|
Application::getInstance()->getLogger()->addMessage(messageWithNewLine.toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::Application(int& argc, char** argv, timeval &startup_time) :
|
Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
QApplication(argc, argv),
|
QApplication(argc, argv),
|
||||||
_window(new QMainWindow(desktop())),
|
_window(new QMainWindow(desktop())),
|
||||||
_glWidget(new GLCanvas()),
|
_glWidget(new GLCanvas()),
|
||||||
_displayLevels(false),
|
|
||||||
_frameCount(0),
|
_frameCount(0),
|
||||||
_fps(120.0f),
|
_fps(120.0f),
|
||||||
_justStarted(true),
|
_justStarted(true),
|
||||||
|
@ -128,7 +128,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
_perfStatsOn(false),
|
_perfStatsOn(false),
|
||||||
_chatEntryOn(false),
|
_chatEntryOn(false),
|
||||||
_audio(&_audioScope, STARTUP_JITTER_SAMPLES),
|
_audio(&_audioScope, STARTUP_JITTER_SAMPLES),
|
||||||
_stopNetworkReceiveThread(false),
|
_enableProcessVoxelsThread(true),
|
||||||
_voxelProcessor(),
|
_voxelProcessor(),
|
||||||
_voxelHideShowThread(&_voxels),
|
_voxelHideShowThread(&_voxels),
|
||||||
_voxelEditSender(this),
|
_voxelEditSender(this),
|
||||||
|
@ -155,7 +155,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
// call Menu getInstance static method to set up the menu
|
// call Menu getInstance static method to set up the menu
|
||||||
_window->setMenuBar(Menu::getInstance());
|
_window->setMenuBar(Menu::getInstance());
|
||||||
|
|
||||||
qDebug("[VERSION] Build sequence: %i\n", BUILD_VERSION);
|
qDebug("[VERSION] Build sequence: %i", BUILD_VERSION);
|
||||||
|
|
||||||
unsigned int listenPort = 0; // bind to an ephemeral port by default
|
unsigned int listenPort = 0; // bind to an ephemeral port by default
|
||||||
const char** constArgv = const_cast<const char**>(argv);
|
const char** constArgv = const_cast<const char**>(argv);
|
||||||
|
@ -165,6 +165,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
|
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
|
||||||
|
|
||||||
|
// connect our processDatagrams slot to the QUDPSocket readyRead() signal
|
||||||
|
connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), SLOT(processDatagrams()));
|
||||||
|
|
||||||
// put the audio processing on a separate thread
|
// put the audio processing on a separate thread
|
||||||
QThread* audioThread = new QThread(this);
|
QThread* audioThread = new QThread(this);
|
||||||
|
@ -173,13 +176,12 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
connect(audioThread, SIGNAL(started()), &_audio, SLOT(start()));
|
connect(audioThread, SIGNAL(started()), &_audio, SLOT(start()));
|
||||||
|
|
||||||
audioThread->start();
|
audioThread->start();
|
||||||
|
|
||||||
|
connect(nodeList, SIGNAL(domainChanged(const QString&)), SLOT(domainChanged(const QString&)));
|
||||||
|
|
||||||
nodeList->addHook(&_voxels);
|
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||||
nodeList->addHook(this);
|
connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), &_voxels, SLOT(nodeAdded(SharedNodePointer)));
|
||||||
nodeList->addDomainListener(this);
|
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), &_voxels, SLOT(nodeKilled(SharedNodePointer)));
|
||||||
|
|
||||||
// network receive thread and voxel parsing thread are both controlled by the --nonblocking command line
|
|
||||||
_enableProcessVoxelsThread = _enableNetworkThread = !cmdOptionExists(argc, constArgv, "--nonblocking");
|
|
||||||
|
|
||||||
// read the ApplicationInfo.ini file for Name/Version/Domain information
|
// read the ApplicationInfo.ini file for Name/Version/Domain information
|
||||||
QSettings applicationInfo("resources/info/ApplicationInfo.ini", QSettings::IniFormat);
|
QSettings applicationInfo("resources/info/ApplicationInfo.ini", QSettings::IniFormat);
|
||||||
|
@ -263,9 +265,6 @@ Application::~Application() {
|
||||||
_audio.thread()->wait();
|
_audio.thread()->wait();
|
||||||
|
|
||||||
storeSizeAndPosition();
|
storeSizeAndPosition();
|
||||||
NodeList::getInstance()->removeHook(&_voxels);
|
|
||||||
NodeList::getInstance()->removeHook(this);
|
|
||||||
NodeList::getInstance()->removeDomainListener(this);
|
|
||||||
|
|
||||||
_sharedVoxelSystem.changeTree(new VoxelTree);
|
_sharedVoxelSystem.changeTree(new VoxelTree);
|
||||||
|
|
||||||
|
@ -274,7 +273,6 @@ Application::~Application() {
|
||||||
|
|
||||||
delete _logger;
|
delete _logger;
|
||||||
delete _settings;
|
delete _settings;
|
||||||
delete _followMode;
|
|
||||||
delete _glWidget;
|
delete _glWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +308,7 @@ void Application::storeSizeAndPosition() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::initializeGL() {
|
void Application::initializeGL() {
|
||||||
qDebug( "Created Display Window.\n" );
|
qDebug( "Created Display Window.");
|
||||||
|
|
||||||
// initialize glut for shape drawing; Qt apparently initializes it on OS X
|
// initialize glut for shape drawing; Qt apparently initializes it on OS X
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
|
@ -325,16 +323,10 @@ void Application::initializeGL() {
|
||||||
_viewFrustumOffsetCamera.setFarClip(500.0 * TREE_SCALE);
|
_viewFrustumOffsetCamera.setFarClip(500.0 * TREE_SCALE);
|
||||||
|
|
||||||
initDisplay();
|
initDisplay();
|
||||||
qDebug( "Initialized Display.\n" );
|
qDebug( "Initialized Display.");
|
||||||
|
|
||||||
init();
|
init();
|
||||||
qDebug( "Init() complete.\n" );
|
qDebug( "init() complete.");
|
||||||
|
|
||||||
// create thread for receipt of data via UDP
|
|
||||||
if (_enableNetworkThread) {
|
|
||||||
pthread_create(&_networkReceiveThread, NULL, networkReceive, NULL);
|
|
||||||
qDebug("Network receive thread created.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// create thread for parsing of voxel data independent of the main network and rendering threads
|
// create thread for parsing of voxel data independent of the main network and rendering threads
|
||||||
_voxelProcessor.initialize(_enableProcessVoxelsThread);
|
_voxelProcessor.initialize(_enableProcessVoxelsThread);
|
||||||
|
@ -342,7 +334,7 @@ void Application::initializeGL() {
|
||||||
_voxelHideShowThread.initialize(_enableProcessVoxelsThread);
|
_voxelHideShowThread.initialize(_enableProcessVoxelsThread);
|
||||||
_particleEditSender.initialize(_enableProcessVoxelsThread);
|
_particleEditSender.initialize(_enableProcessVoxelsThread);
|
||||||
if (_enableProcessVoxelsThread) {
|
if (_enableProcessVoxelsThread) {
|
||||||
qDebug("Voxel parsing thread created.\n");
|
qDebug("Voxel parsing thread created.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// call terminate before exiting
|
// call terminate before exiting
|
||||||
|
@ -362,9 +354,7 @@ void Application::initializeGL() {
|
||||||
if (_justStarted) {
|
if (_justStarted) {
|
||||||
float startupTime = (usecTimestampNow() - usecTimestamp(&_applicationStartupTime)) / 1000000.0;
|
float startupTime = (usecTimestampNow() - usecTimestamp(&_applicationStartupTime)) / 1000000.0;
|
||||||
_justStarted = false;
|
_justStarted = false;
|
||||||
char title[50];
|
qDebug("Startup time: %4.2f seconds.", startupTime);
|
||||||
sprintf(title, "Interface: %4.2f seconds\n", startupTime);
|
|
||||||
qDebug("%s", title);
|
|
||||||
const char LOGSTASH_INTERFACE_START_TIME_KEY[] = "interface-start-time";
|
const char LOGSTASH_INTERFACE_START_TIME_KEY[] = "interface-start-time";
|
||||||
|
|
||||||
// ask the Logstash class to record the startup time
|
// ask the Logstash class to record the startup time
|
||||||
|
@ -671,9 +661,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
_audioScope.inputPaused = !_audioScope.inputPaused;
|
_audioScope.inputPaused = !_audioScope.inputPaused;
|
||||||
break;
|
break;
|
||||||
case Qt::Key_L:
|
case Qt::Key_L:
|
||||||
if (!isShifted && !isMeta) {
|
if (isShifted) {
|
||||||
_displayLevels = !_displayLevels;
|
|
||||||
} else if (isShifted) {
|
|
||||||
Menu::getInstance()->triggerOption(MenuOption::LodTools);
|
Menu::getInstance()->triggerOption(MenuOption::LodTools);
|
||||||
} else if (isMeta) {
|
} else if (isMeta) {
|
||||||
Menu::getInstance()->triggerOption(MenuOption::Log);
|
Menu::getInstance()->triggerOption(MenuOption::Log);
|
||||||
|
@ -1016,6 +1004,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
case Qt::Key_Minus:
|
case Qt::Key_Minus:
|
||||||
_myAvatar.decreaseSize();
|
_myAvatar.decreaseSize();
|
||||||
break;
|
break;
|
||||||
|
case Qt::Key_Equal:
|
||||||
|
_myAvatar.resetSize();
|
||||||
|
break;
|
||||||
|
|
||||||
case Qt::Key_1:
|
case Qt::Key_1:
|
||||||
case Qt::Key_2:
|
case Qt::Key_2:
|
||||||
|
@ -1121,7 +1112,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_isHoverVoxel) {
|
if (_isHoverVoxel) {
|
||||||
_myAvatar.orbit(glm::vec3(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z) * (float)TREE_SCALE, deltaX, deltaY);
|
_myAvatar.orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1339,11 +1330,6 @@ void Application::timer() {
|
||||||
|
|
||||||
gettimeofday(&_timerStart, NULL);
|
gettimeofday(&_timerStart, NULL);
|
||||||
|
|
||||||
// if we haven't detected gyros, check for them now
|
|
||||||
if (!_serialHeadSensor.isActive()) {
|
|
||||||
_serialHeadSensor.pair();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ask the node list to check in with the domain server
|
// ask the node list to check in with the domain server
|
||||||
NodeList::getInstance()->sendDomainServerCheckIn();
|
NodeList::getInstance()->sendDomainServerCheckIn();
|
||||||
|
|
||||||
|
@ -1426,11 +1412,6 @@ void Application::terminate() {
|
||||||
// let the avatar mixer know we're out
|
// let the avatar mixer know we're out
|
||||||
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
|
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
|
||||||
|
|
||||||
if (_enableNetworkThread) {
|
|
||||||
_stopNetworkReceiveThread = true;
|
|
||||||
pthread_join(_networkReceiveThread, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("");
|
printf("");
|
||||||
_voxelProcessor.terminate();
|
_voxelProcessor.terminate();
|
||||||
_voxelHideShowThread.terminate();
|
_voxelHideShowThread.terminate();
|
||||||
|
@ -1443,7 +1424,7 @@ void Application::terminate() {
|
||||||
static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) {
|
static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) {
|
||||||
// record the packet for stats-tracking
|
// record the packet for stats-tracking
|
||||||
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AVATARS).updateValue(dataBytes);
|
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AVATARS).updateValue(dataBytes);
|
||||||
Node* avatarMixerNode = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
SharedNodePointer avatarMixerNode = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||||
if (avatarMixerNode) {
|
if (avatarMixerNode) {
|
||||||
avatarMixerNode->recordBytesReceived(dataBytes);
|
avatarMixerNode->recordBytesReceived(dataBytes);
|
||||||
}
|
}
|
||||||
|
@ -1460,7 +1441,7 @@ static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& da
|
||||||
dataBytes -= NUM_BYTES_RFC4122_UUID;
|
dataBytes -= NUM_BYTES_RFC4122_UUID;
|
||||||
|
|
||||||
// make sure the node exists
|
// make sure the node exists
|
||||||
Node* node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
||||||
if (!node || !node->getLinkedData()) {
|
if (!node || !node->getLinkedData()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1619,10 +1600,9 @@ void Application::makeVoxel(glm::vec3 position,
|
||||||
isDestructive);
|
isDestructive);
|
||||||
}
|
}
|
||||||
|
|
||||||
const glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel) {
|
glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVoxel) {
|
||||||
return glm::vec3((_mouseVoxel.x + _mouseVoxel.s / 2.f) * TREE_SCALE,
|
return glm::vec3((mouseVoxel.x + mouseVoxel.s / 2.f) * TREE_SCALE, (mouseVoxel.y + mouseVoxel.s / 2.f) * TREE_SCALE,
|
||||||
(_mouseVoxel.y + _mouseVoxel.s / 2.f) * TREE_SCALE,
|
(mouseVoxel.z + mouseVoxel.s / 2.f) * TREE_SCALE);
|
||||||
(_mouseVoxel.z + _mouseVoxel.s / 2.f) * TREE_SCALE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const float NUDGE_PRECISION_MIN = 1 / pow(2.0, 12.0);
|
const float NUDGE_PRECISION_MIN = 1 / pow(2.0, 12.0);
|
||||||
|
@ -1709,9 +1689,9 @@ void Application::exportVoxels() {
|
||||||
|
|
||||||
void Application::importVoxels() {
|
void Application::importVoxels() {
|
||||||
if (_voxelImporter.exec()) {
|
if (_voxelImporter.exec()) {
|
||||||
qDebug("[DEBUG] Import succedded.\n");
|
qDebug("[DEBUG] Import succeeded.");
|
||||||
} else {
|
} else {
|
||||||
qDebug("[DEBUG] Import failed.\n");
|
qDebug("[DEBUG] Import failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore the main window's active state
|
// restore the main window's active state
|
||||||
|
@ -1892,7 +1872,7 @@ void Application::init() {
|
||||||
if (Menu::getInstance()->getAudioJitterBufferSamples() != 0) {
|
if (Menu::getInstance()->getAudioJitterBufferSamples() != 0) {
|
||||||
_audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());
|
_audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());
|
||||||
}
|
}
|
||||||
qDebug("Loaded settings.\n");
|
qDebug("Loaded settings");
|
||||||
|
|
||||||
if (!_profile.getUsername().isEmpty()) {
|
if (!_profile.getUsername().isEmpty()) {
|
||||||
// we have a username for this avatar, ask the data-server for the mesh URL for this avatar
|
// we have a username for this avatar, ask the data-server for the mesh URL for this avatar
|
||||||
|
@ -1926,10 +1906,6 @@ void Application::init() {
|
||||||
_glWidget->width(),
|
_glWidget->width(),
|
||||||
_glWidget->height());
|
_glWidget->height());
|
||||||
|
|
||||||
_followMode = new QAction(this);
|
|
||||||
connect(_followMode, SIGNAL(triggered()), this, SLOT(toggleFollowMode()));
|
|
||||||
_pieMenu.addAction(_followMode);
|
|
||||||
|
|
||||||
_audio.init(_glWidget);
|
_audio.init(_glWidget);
|
||||||
|
|
||||||
_rearMirrorTools = new RearMirrorTools(_glWidget, _mirrorViewRect, _settings);
|
_rearMirrorTools = new RearMirrorTools(_glWidget, _mirrorViewRect, _settings);
|
||||||
|
@ -1987,16 +1963,16 @@ void Application::updateLookatTargetAvatar(const glm::vec3& mouseRayOrigin, cons
|
||||||
Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
|
||||||
glm::vec3& eyePosition, QUuid& nodeUUID = DEFAULT_NODE_ID_REF) {
|
glm::vec3& eyePosition, QUuid& nodeUUID = DEFAULT_NODE_ID_REF) {
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||||
Avatar* avatar = (Avatar*)node->getLinkedData();
|
Avatar* avatar = (Avatar*)node->getLinkedData();
|
||||||
float distance;
|
float distance;
|
||||||
|
|
||||||
if (avatar->findRayIntersection(mouseRayOrigin, mouseRayDirection, distance)) {
|
if (avatar->findRayIntersection(mouseRayOrigin, mouseRayDirection, distance)) {
|
||||||
// rescale to compensate for head embiggening
|
// rescale to compensate for head embiggening
|
||||||
eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) *
|
eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) *
|
||||||
(avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot();
|
(avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot();
|
||||||
|
|
||||||
_lookatIndicatorScale = avatar->getHead().getScale();
|
_lookatIndicatorScale = avatar->getHead().getScale();
|
||||||
_lookatOtherPosition = avatar->getHead().getPosition();
|
_lookatOtherPosition = avatar->getHead().getPosition();
|
||||||
nodeUUID = avatar->getOwningNode()->getUUID();
|
nodeUUID = avatar->getOwningNode()->getUUID();
|
||||||
|
@ -2004,6 +1980,7 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2028,71 +2005,6 @@ void Application::renderLookatIndicator(glm::vec3 pointOfInterest) {
|
||||||
renderCircle(haloOrigin, INDICATOR_RADIUS, IDENTITY_UP, NUM_SEGMENTS);
|
renderCircle(haloOrigin, INDICATOR_RADIUS, IDENTITY_UP, NUM_SEGMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void maybeBeginFollowIndicator(bool& began) {
|
|
||||||
if (!began) {
|
|
||||||
Application::getInstance()->getGlowEffect()->begin();
|
|
||||||
glLineWidth(5);
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
began = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::renderFollowIndicator() {
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
|
|
||||||
// initialize lazily so that we don't enable the glow effect unnecessarily
|
|
||||||
bool began = false;
|
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); ++node) {
|
|
||||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
|
||||||
Avatar* avatar = (Avatar *) node->getLinkedData();
|
|
||||||
Avatar* leader = NULL;
|
|
||||||
|
|
||||||
if (!avatar->getLeaderUUID().isNull()) {
|
|
||||||
if (avatar->getLeaderUUID() == NodeList::getInstance()->getOwnerUUID()) {
|
|
||||||
leader = &_myAvatar;
|
|
||||||
} else {
|
|
||||||
for (NodeList::iterator it = nodeList->begin(); it != nodeList->end(); ++it) {
|
|
||||||
if(it->getUUID() == avatar->getLeaderUUID()
|
|
||||||
&& it->getType() == NODE_TYPE_AGENT) {
|
|
||||||
leader = (Avatar*) it->getLinkedData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leader != NULL) {
|
|
||||||
maybeBeginFollowIndicator(began);
|
|
||||||
glColor3f(1.f, 0.f, 0.f);
|
|
||||||
glVertex3f((avatar->getHead().getPosition().x + avatar->getPosition().x) / 2.f,
|
|
||||||
(avatar->getHead().getPosition().y + avatar->getPosition().y) / 2.f,
|
|
||||||
(avatar->getHead().getPosition().z + avatar->getPosition().z) / 2.f);
|
|
||||||
glColor3f(0.f, 1.f, 0.f);
|
|
||||||
glVertex3f((leader->getHead().getPosition().x + leader->getPosition().x) / 2.f,
|
|
||||||
(leader->getHead().getPosition().y + leader->getPosition().y) / 2.f,
|
|
||||||
(leader->getHead().getPosition().z + leader->getPosition().z) / 2.f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_myAvatar.getLeadingAvatar() != NULL) {
|
|
||||||
maybeBeginFollowIndicator(began);
|
|
||||||
glColor3f(1.f, 0.f, 0.f);
|
|
||||||
glVertex3f((_myAvatar.getHead().getPosition().x + _myAvatar.getPosition().x) / 2.f,
|
|
||||||
(_myAvatar.getHead().getPosition().y + _myAvatar.getPosition().y) / 2.f,
|
|
||||||
(_myAvatar.getHead().getPosition().z + _myAvatar.getPosition().z) / 2.f);
|
|
||||||
glColor3f(0.f, 1.f, 0.f);
|
|
||||||
glVertex3f((_myAvatar.getLeadingAvatar()->getHead().getPosition().x + _myAvatar.getLeadingAvatar()->getPosition().x) / 2.f,
|
|
||||||
(_myAvatar.getLeadingAvatar()->getHead().getPosition().y + _myAvatar.getLeadingAvatar()->getPosition().y) / 2.f,
|
|
||||||
(_myAvatar.getLeadingAvatar()->getHead().getPosition().z + _myAvatar.getLeadingAvatar()->getPosition().z) / 2.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (began) {
|
|
||||||
glEnd();
|
|
||||||
_glowEffect.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::renderHighlightVoxel(VoxelDetail voxel) {
|
void Application::renderHighlightVoxel(VoxelDetail voxel) {
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -2110,10 +2022,9 @@ void Application::renderHighlightVoxel(VoxelDetail voxel) {
|
||||||
void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection) {
|
void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
|
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
for(NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
QMutexLocker(&node->getMutex());
|
||||||
node->lock();
|
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
Avatar *avatar = (Avatar *)node->getLinkedData();
|
Avatar *avatar = (Avatar *)node->getLinkedData();
|
||||||
if (!avatar->isInitialized()) {
|
if (!avatar->isInitialized()) {
|
||||||
|
@ -2122,7 +2033,6 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::
|
||||||
avatar->simulate(deltaTime, NULL);
|
avatar->simulate(deltaTime, NULL);
|
||||||
avatar->setMouseRay(mouseRayOrigin, mouseRayDirection);
|
avatar->setMouseRay(mouseRayOrigin, mouseRayDirection);
|
||||||
}
|
}
|
||||||
node->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulate avatar fades
|
// simulate avatar fades
|
||||||
|
@ -2382,21 +2292,12 @@ void Application::updateSixense(float deltaTime) {
|
||||||
void Application::updateSerialDevices(float deltaTime) {
|
void Application::updateSerialDevices(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateSerialDevices()");
|
PerformanceWarning warn(showWarnings, "Application::updateSerialDevices()");
|
||||||
|
|
||||||
if (_serialHeadSensor.isActive()) {
|
|
||||||
_serialHeadSensor.readData(deltaTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateThreads(float deltaTime) {
|
void Application::updateThreads(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateThreads()");
|
PerformanceWarning warn(showWarnings, "Application::updateThreads()");
|
||||||
|
|
||||||
// read incoming packets from network
|
|
||||||
if (!_enableNetworkThread) {
|
|
||||||
networkReceive(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse voxel packets
|
// parse voxel packets
|
||||||
if (!_enableProcessVoxelsThread) {
|
if (!_enableProcessVoxelsThread) {
|
||||||
_voxelProcessor.threadRoutine();
|
_voxelProcessor.threadRoutine();
|
||||||
|
@ -2629,41 +2530,6 @@ void Application::updateAvatar(float deltaTime) {
|
||||||
_headMouseY -= headVelocity.x * HEADMOUSE_FACESHIFT_PITCH_SCALE;
|
_headMouseY -= headVelocity.x * HEADMOUSE_FACESHIFT_PITCH_SCALE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_serialHeadSensor.isActive()) {
|
|
||||||
|
|
||||||
// Grab latest readings from the gyros
|
|
||||||
float measuredPitchRate = _serialHeadSensor.getLastPitchRate();
|
|
||||||
float measuredYawRate = _serialHeadSensor.getLastYawRate();
|
|
||||||
|
|
||||||
// Update gyro-based mouse (X,Y on screen)
|
|
||||||
const float MIN_MOUSE_RATE = 3.0;
|
|
||||||
const float HORIZONTAL_PIXELS_PER_DEGREE = 2880.f / 45.f;
|
|
||||||
const float VERTICAL_PIXELS_PER_DEGREE = 1800.f / 30.f;
|
|
||||||
if (powf(measuredYawRate * measuredYawRate +
|
|
||||||
measuredPitchRate * measuredPitchRate, 0.5) > MIN_MOUSE_RATE) {
|
|
||||||
_headMouseX -= measuredYawRate * HORIZONTAL_PIXELS_PER_DEGREE * deltaTime;
|
|
||||||
_headMouseY -= measuredPitchRate * VERTICAL_PIXELS_PER_DEGREE * deltaTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float MIDPOINT_OF_SCREEN = 0.5;
|
|
||||||
|
|
||||||
// Only use gyro to set lookAt if mouse hasn't selected an avatar
|
|
||||||
if (!_lookatTargetAvatar) {
|
|
||||||
|
|
||||||
// Set lookAtPosition if an avatar is at the center of the screen
|
|
||||||
glm::vec3 screenCenterRayOrigin, screenCenterRayDirection;
|
|
||||||
_viewFrustum.computePickRay(MIDPOINT_OF_SCREEN, MIDPOINT_OF_SCREEN, screenCenterRayOrigin, screenCenterRayDirection);
|
|
||||||
|
|
||||||
glm::vec3 eyePosition;
|
|
||||||
updateLookatTargetAvatar(screenCenterRayOrigin, screenCenterRayDirection, eyePosition);
|
|
||||||
if (_lookatTargetAvatar) {
|
|
||||||
glm::vec3 myLookAtFromMouse(eyePosition);
|
|
||||||
_myAvatar.getHead().setLookAtPosition(myLookAtFromMouse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constrain head-driven mouse to edges of screen
|
// Constrain head-driven mouse to edges of screen
|
||||||
_headMouseX = glm::clamp(_headMouseX, 0, _glWidget->width());
|
_headMouseX = glm::clamp(_headMouseX, 0, _glWidget->width());
|
||||||
_headMouseY = glm::clamp(_headMouseY, 0, _glWidget->height());
|
_headMouseY = glm::clamp(_headMouseY, 0, _glWidget->height());
|
||||||
|
@ -2744,39 +2610,36 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
||||||
|
|
||||||
unsigned char voxelQueryPacket[MAX_PACKET_SIZE];
|
unsigned char voxelQueryPacket[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
|
|
||||||
// Iterate all of the nodes, and get a count of how many voxel servers we have...
|
// Iterate all of the nodes, and get a count of how many voxel servers we have...
|
||||||
int totalServers = 0;
|
int totalServers = 0;
|
||||||
int inViewServers = 0;
|
int inViewServers = 0;
|
||||||
int unknownJurisdictionServers = 0;
|
int unknownJurisdictionServers = 0;
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
|
|
||||||
// only send to the NodeTypes that are serverType
|
// only send to the NodeTypes that are serverType
|
||||||
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
|
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
|
||||||
totalServers++;
|
totalServers++;
|
||||||
|
|
||||||
// get the server bounds for this server
|
// get the server bounds for this server
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
|
||||||
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||||
// can get the jurisdiction...
|
// can get the jurisdiction...
|
||||||
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||||
unknownJurisdictionServers++;
|
unknownJurisdictionServers++;
|
||||||
} else {
|
} else {
|
||||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||||
|
|
||||||
unsigned char* rootCode = map.getRootOctalCode();
|
unsigned char* rootCode = map.getRootOctalCode();
|
||||||
|
|
||||||
if (rootCode) {
|
if (rootCode) {
|
||||||
VoxelPositionSize rootDetails;
|
VoxelPositionSize rootDetails;
|
||||||
voxelDetailsForCode(rootCode, rootDetails);
|
voxelDetailsForCode(rootCode, rootDetails);
|
||||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||||
serverBounds.scale(TREE_SCALE);
|
serverBounds.scale(TREE_SCALE);
|
||||||
|
|
||||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
||||||
|
|
||||||
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||||
inViewServers++;
|
inViewServers++;
|
||||||
}
|
}
|
||||||
|
@ -2786,7 +2649,7 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantExtraDebugging && unknownJurisdictionServers > 0) {
|
if (wantExtraDebugging && unknownJurisdictionServers > 0) {
|
||||||
qDebug("Servers: total %d, in view %d, unknown jurisdiction %d \n",
|
qDebug("Servers: total %d, in view %d, unknown jurisdiction %d",
|
||||||
totalServers, inViewServers, unknownJurisdictionServers);
|
totalServers, inViewServers, unknownJurisdictionServers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2807,38 +2670,40 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantExtraDebugging && unknownJurisdictionServers > 0) {
|
if (wantExtraDebugging && unknownJurisdictionServers > 0) {
|
||||||
qDebug("perServerPPS: %d perUnknownServer: %d\n", perServerPPS, perUnknownServer);
|
qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
// only send to the NodeTypes that are serverType
|
// only send to the NodeTypes that are serverType
|
||||||
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
|
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
|
||||||
|
|
||||||
|
|
||||||
// get the server bounds for this server
|
// get the server bounds for this server
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
|
||||||
bool inView = false;
|
bool inView = false;
|
||||||
bool unknownView = false;
|
bool unknownView = false;
|
||||||
|
|
||||||
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||||
// can get the jurisdiction...
|
// can get the jurisdiction...
|
||||||
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||||
unknownView = true; // assume it's in view
|
unknownView = true; // assume it's in view
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
qDebug() << "no known jurisdiction for node " << *node << ", assume it's visible.\n";
|
qDebug() << "no known jurisdiction for node " << *node << ", assume it's visible.";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||||
|
|
||||||
unsigned char* rootCode = map.getRootOctalCode();
|
unsigned char* rootCode = map.getRootOctalCode();
|
||||||
|
|
||||||
if (rootCode) {
|
if (rootCode) {
|
||||||
VoxelPositionSize rootDetails;
|
VoxelPositionSize rootDetails;
|
||||||
voxelDetailsForCode(rootCode, rootDetails);
|
voxelDetailsForCode(rootCode, rootDetails);
|
||||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||||
serverBounds.scale(TREE_SCALE);
|
serverBounds.scale(TREE_SCALE);
|
||||||
|
|
||||||
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
||||||
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||||
inView = true;
|
inView = true;
|
||||||
|
@ -2847,19 +2712,19 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
qDebug() << "Jurisdiction without RootCode for node " << *node << ". That's unusual!\n";
|
qDebug() << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inView) {
|
if (inView) {
|
||||||
_voxelQuery.setMaxOctreePacketsPerSecond(perServerPPS);
|
_voxelQuery.setMaxOctreePacketsPerSecond(perServerPPS);
|
||||||
} else if (unknownView) {
|
} else if (unknownView) {
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
qDebug() << "no known jurisdiction for node " << *node << ", give it budget of "
|
qDebug() << "no known jurisdiction for node " << *node << ", give it budget of "
|
||||||
<< perUnknownServer << " to send us jurisdiction.\n";
|
<< perUnknownServer << " to send us jurisdiction.";
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly
|
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly
|
||||||
// If there's only one server, then don't do this, and just let the normal voxel query pass through
|
// If there's only one server, then don't do this, and just let the normal voxel query pass through
|
||||||
// as expected... this way, we will actually get a valid scene if there is one to be seen
|
// as expected... this way, we will actually get a valid scene if there is one to be seen
|
||||||
|
@ -2870,11 +2735,11 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
||||||
_voxelQuery.setCameraNearClip(0.1);
|
_voxelQuery.setCameraNearClip(0.1);
|
||||||
_voxelQuery.setCameraFarClip(0.1);
|
_voxelQuery.setCameraFarClip(0.1);
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
qDebug() << "Using 'minimal' camera position for node " << *node << "\n";
|
qDebug() << "Using 'minimal' camera position for node" << *node;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
qDebug() << "Using regular camera position for node " << *node << "\n";
|
qDebug() << "Using regular camera position for node" << *node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_voxelQuery.setMaxOctreePacketsPerSecond(perUnknownServer);
|
_voxelQuery.setMaxOctreePacketsPerSecond(perUnknownServer);
|
||||||
|
@ -2883,24 +2748,24 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
||||||
}
|
}
|
||||||
// set up the packet for sending...
|
// set up the packet for sending...
|
||||||
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
|
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
|
||||||
|
|
||||||
// insert packet type/version and node UUID
|
// insert packet type/version and node UUID
|
||||||
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType);
|
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType);
|
||||||
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
|
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
|
||||||
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
|
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
|
||||||
endOfVoxelQueryPacket += ownerUUID.size();
|
endOfVoxelQueryPacket += ownerUUID.size();
|
||||||
|
|
||||||
// encode the query data...
|
// encode the query data...
|
||||||
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
|
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
|
||||||
|
|
||||||
int packetLength = endOfVoxelQueryPacket - voxelQueryPacket;
|
int packetLength = endOfVoxelQueryPacket - voxelQueryPacket;
|
||||||
|
|
||||||
// make sure we still have an active socket
|
// make sure we still have an active socket
|
||||||
if (node->getActiveSocket()) {
|
if (node->getActiveSocket()) {
|
||||||
nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength,
|
nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength,
|
||||||
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feed number of bytes to corresponding channel of the bandwidth meter
|
// Feed number of bytes to corresponding channel of the bandwidth meter
|
||||||
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
|
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
|
||||||
}
|
}
|
||||||
|
@ -3257,12 +3122,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
|
||||||
"Application::displaySide() ... renderFollowIndicator...");
|
|
||||||
renderFollowIndicator();
|
|
||||||
}
|
|
||||||
|
|
||||||
// render transmitter pick ray, if non-empty
|
// render transmitter pick ray, if non-empty
|
||||||
if (_transmitterPickStart != _transmitterPickEnd) {
|
if (_transmitterPickStart != _transmitterPickEnd) {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
|
@ -3330,8 +3189,7 @@ void Application::displayOverlay() {
|
||||||
|
|
||||||
//noiseTest(_glWidget->width(), _glWidget->height());
|
//noiseTest(_glWidget->width(), _glWidget->height());
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)
|
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {
|
||||||
&& USING_INVENSENSE_MPU9150) {
|
|
||||||
// Display small target box at center or head mouse target that can also be used to measure LOD
|
// Display small target box at center or head mouse target that can also be used to measure LOD
|
||||||
glColor3f(1.0, 1.0, 1.0);
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
glDisable(GL_LINE_SMOOTH);
|
glDisable(GL_LINE_SMOOTH);
|
||||||
|
@ -3367,9 +3225,6 @@ void Application::displayOverlay() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show detected levels from the serial I/O ADC channel sensors
|
|
||||||
if (_displayLevels) _serialHeadSensor.renderLevels(_glWidget->width(), _glWidget->height());
|
|
||||||
|
|
||||||
// Show hand transmitter data if detected
|
// Show hand transmitter data if detected
|
||||||
if (_myTransmitter.isConnected()) {
|
if (_myTransmitter.isConnected()) {
|
||||||
_myTransmitter.renderLevels(_glWidget->width(), _glWidget->height());
|
_myTransmitter.renderLevels(_glWidget->width(), _glWidget->height());
|
||||||
|
@ -3389,12 +3244,12 @@ void Application::displayOverlay() {
|
||||||
glPointSize(1.0f);
|
glPointSize(1.0f);
|
||||||
char nodes[100];
|
char nodes[100];
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
int totalAvatars = 0, totalServers = 0;
|
int totalAvatars = 0, totalServers = 0;
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++;
|
node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(nodes, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars);
|
sprintf(nodes, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars);
|
||||||
drawtext(_glWidget->width() - 150, 20, 0.10, 0, 1.0, 0, nodes, 1, 0, 0);
|
drawtext(_glWidget->width() - 150, 20, 0.10, 0, 1.0, 0, nodes, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -3494,8 +3349,8 @@ void Application::displayStats() {
|
||||||
int pingAudio = 0, pingAvatar = 0, pingVoxel = 0, pingVoxelMax = 0;
|
int pingAudio = 0, pingAvatar = 0, pingVoxel = 0, pingVoxelMax = 0;
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
Node* audioMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||||
Node* avatarMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||||
|
|
||||||
pingAudio = audioMixerNode ? audioMixerNode->getPingMs() : 0;
|
pingAudio = audioMixerNode ? audioMixerNode->getPingMs() : 0;
|
||||||
pingAvatar = avatarMixerNode ? avatarMixerNode->getPingMs() : 0;
|
pingAvatar = avatarMixerNode ? avatarMixerNode->getPingMs() : 0;
|
||||||
|
@ -3504,7 +3359,8 @@ void Application::displayStats() {
|
||||||
// Now handle voxel servers, since there could be more than one, we average their ping times
|
// Now handle voxel servers, since there could be more than one, we average their ping times
|
||||||
unsigned long totalPingVoxel = 0;
|
unsigned long totalPingVoxel = 0;
|
||||||
int voxelServerCount = 0;
|
int voxelServerCount = 0;
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||||
totalPingVoxel += node->getPingMs();
|
totalPingVoxel += node->getPingMs();
|
||||||
voxelServerCount++;
|
voxelServerCount++;
|
||||||
|
@ -3513,6 +3369,7 @@ void Application::displayStats() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (voxelServerCount) {
|
if (voxelServerCount) {
|
||||||
pingVoxel = totalPingVoxel/voxelServerCount;
|
pingVoxel = totalPingVoxel/voxelServerCount;
|
||||||
}
|
}
|
||||||
|
@ -3529,7 +3386,7 @@ void Application::displayStats() {
|
||||||
sprintf(avatarStats, "Avatar: pos %.3f, %.3f, %.3f, vel %.1f, yaw = %.2f", avatarPos.x, avatarPos.y, avatarPos.z, glm::length(_myAvatar.getVelocity()), _myAvatar.getBodyYaw());
|
sprintf(avatarStats, "Avatar: pos %.3f, %.3f, %.3f, vel %.1f, yaw = %.2f", avatarPos.x, avatarPos.y, avatarPos.z, glm::length(_myAvatar.getVelocity()), _myAvatar.getBodyYaw());
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats);
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats);
|
||||||
|
|
||||||
Node* avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||||
char avatarMixerStats[200];
|
char avatarMixerStats[200];
|
||||||
if (avatarMixer) {
|
if (avatarMixer) {
|
||||||
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
|
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
|
||||||
|
@ -3731,9 +3588,6 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
|
||||||
|
|
||||||
// render the coverage map on screen
|
// render the coverage map on screen
|
||||||
void Application::renderCoverageMapV2() {
|
void Application::renderCoverageMapV2() {
|
||||||
|
|
||||||
//qDebug("renderCoverageMap()\n");
|
|
||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glLineWidth(2.0);
|
glLineWidth(2.0);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
|
@ -3777,8 +3631,6 @@ void Application::renderCoverageMapsV2Recursively(CoverageMapV2* map) {
|
||||||
// render the coverage map on screen
|
// render the coverage map on screen
|
||||||
void Application::renderCoverageMap() {
|
void Application::renderCoverageMap() {
|
||||||
|
|
||||||
//qDebug("renderCoverageMap()\n");
|
|
||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glLineWidth(2.0);
|
glLineWidth(2.0);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
|
@ -3853,10 +3705,10 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
||||||
if (!selfAvatarOnly) {
|
if (!selfAvatarOnly) {
|
||||||
// Render avatars of other nodes
|
// Render avatars of other nodes
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
node->lock();
|
QMutexLocker(&node->getMutex());
|
||||||
|
|
||||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||||
Avatar *avatar = (Avatar *)node->getLinkedData();
|
Avatar *avatar = (Avatar *)node->getLinkedData();
|
||||||
if (!avatar->isInitialized()) {
|
if (!avatar->isInitialized()) {
|
||||||
|
@ -3865,8 +3717,6 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
||||||
avatar->render(false);
|
avatar->render(false);
|
||||||
avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors));
|
||||||
}
|
}
|
||||||
|
|
||||||
node->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// render avatar fades
|
// render avatar fades
|
||||||
|
@ -4111,25 +3961,10 @@ void Application::eyedropperVoxelUnderCursor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::toggleFollowMode() {
|
|
||||||
glm::vec3 mouseRayOrigin, mouseRayDirection;
|
|
||||||
_viewFrustum.computePickRay(_pieMenu.getX() / (float)_glWidget->width(),
|
|
||||||
_pieMenu.getY() / (float)_glWidget->height(),
|
|
||||||
mouseRayOrigin, mouseRayDirection);
|
|
||||||
glm::vec3 eyePositionIgnored;
|
|
||||||
QUuid nodeUUIDIgnored;
|
|
||||||
Avatar* leadingAvatar = findLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, eyePositionIgnored, nodeUUIDIgnored);
|
|
||||||
|
|
||||||
_myAvatar.follow(leadingAvatar);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::resetSensors() {
|
void Application::resetSensors() {
|
||||||
_headMouseX = _mouseX = _glWidget->width() / 2;
|
_headMouseX = _mouseX = _glWidget->width() / 2;
|
||||||
_headMouseY = _mouseY = _glWidget->height() / 2;
|
_headMouseY = _mouseY = _glWidget->height() / 2;
|
||||||
|
|
||||||
if (_serialHeadSensor.isActive()) {
|
|
||||||
_serialHeadSensor.resetAverages();
|
|
||||||
}
|
|
||||||
_webcam.reset();
|
_webcam.reset();
|
||||||
_faceshift.reset();
|
_faceshift.reset();
|
||||||
|
|
||||||
|
@ -4182,13 +4017,13 @@ void Application::updateWindowTitle(){
|
||||||
title += _profile.getLastDomain();
|
title += _profile.getLastDomain();
|
||||||
title += buildVersion;
|
title += buildVersion;
|
||||||
|
|
||||||
qDebug("Application title set to: %s.\n", title.toStdString().c_str());
|
qDebug("Application title set to: %s", title.toStdString().c_str());
|
||||||
_window->setWindowTitle(title);
|
_window->setWindowTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::domainChanged(QString domain) {
|
void Application::domainChanged(const QString& domainHostname) {
|
||||||
// update the user's last domain in their Profile (which will propagate to data-server)
|
// update the user's last domain in their Profile (which will propagate to data-server)
|
||||||
_profile.updateDomain(domain);
|
_profile.updateDomain(domainHostname);
|
||||||
|
|
||||||
updateWindowTitle();
|
updateWindowTitle();
|
||||||
|
|
||||||
|
@ -4201,15 +4036,11 @@ void Application::domainChanged(QString domain) {
|
||||||
_particleServerJurisdictions.clear();
|
_particleServerJurisdictions.clear();
|
||||||
|
|
||||||
// reset our persist thread
|
// reset our persist thread
|
||||||
qDebug() << "domainChanged()... domain=" << domain << " swapping persist cache\n";
|
qDebug() << "Domain changed to" << domainHostname << ". Swapping persist cache.";
|
||||||
updateLocalOctreeCache();
|
updateLocalOctreeCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::nodeAdded(Node* node) {
|
void Application::nodeKilled(SharedNodePointer node) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::nodeKilled(Node* node) {
|
|
||||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
// see if this is the first we've heard of this node...
|
// see if this is the first we've heard of this node...
|
||||||
|
@ -4289,7 +4120,7 @@ void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t m
|
||||||
const HifiSockAddr& senderSockAddr, bool wasStatsPacket) {
|
const HifiSockAddr& senderSockAddr, bool wasStatsPacket) {
|
||||||
|
|
||||||
// Attempt to identify the sender from it's address.
|
// Attempt to identify the sender from it's address.
|
||||||
Node* serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
SharedNodePointer serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||||
if (serverNode) {
|
if (serverNode) {
|
||||||
QUuid nodeUUID = serverNode->getUUID();
|
QUuid nodeUUID = serverNode->getUUID();
|
||||||
|
|
||||||
|
@ -4306,7 +4137,7 @@ void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t m
|
||||||
int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderSockAddr) {
|
int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderSockAddr) {
|
||||||
|
|
||||||
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
||||||
Node* server = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
SharedNodePointer server = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||||
|
|
||||||
// parse the incoming stats datas stick it in a temporary object for now, while we
|
// parse the incoming stats datas stick it in a temporary object for now, while we
|
||||||
// determine which server it belongs to
|
// determine which server it belongs to
|
||||||
|
@ -4363,105 +4194,95 @@ int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLen
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive packets from other nodes/servers and decide what to do with them!
|
// Receive packets from other nodes/servers and decide what to do with them!
|
||||||
void* Application::networkReceive(void* args) {
|
void Application::processDatagrams() {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
"Application::networkReceive()");
|
"Application::networkReceive()");
|
||||||
|
|
||||||
HifiSockAddr senderSockAddr;
|
HifiSockAddr senderSockAddr;
|
||||||
ssize_t bytesReceived;
|
ssize_t bytesReceived;
|
||||||
|
|
||||||
Application* app = Application::getInstance();
|
while (NodeList::getInstance()->getNodeSocket().hasPendingDatagrams() &&
|
||||||
while (!app->_stopNetworkReceiveThread) {
|
(bytesReceived = NodeList::getInstance()->getNodeSocket().readDatagram((char*) _incomingPacket,
|
||||||
if (NodeList::getInstance()->getNodeSocket().hasPendingDatagrams() &&
|
MAX_PACKET_SIZE,
|
||||||
(bytesReceived = NodeList::getInstance()->getNodeSocket().readDatagram((char*) app->_incomingPacket,
|
senderSockAddr.getAddressPointer(),
|
||||||
MAX_PACKET_SIZE,
|
senderSockAddr.getPortPointer()))) {
|
||||||
senderSockAddr.getAddressPointer(),
|
|
||||||
senderSockAddr.getPortPointer()))) {
|
_packetCount++;
|
||||||
|
_bytesCount += bytesReceived;
|
||||||
app->_packetCount++;
|
|
||||||
app->_bytesCount += bytesReceived;
|
if (packetVersionMatch(_incomingPacket)) {
|
||||||
|
// only process this packet if we have a match on the packet version
|
||||||
if (packetVersionMatch(app->_incomingPacket)) {
|
switch (_incomingPacket[0]) {
|
||||||
// only process this packet if we have a match on the packet version
|
case PACKET_TYPE_TRANSMITTER_DATA_V2:
|
||||||
switch (app->_incomingPacket[0]) {
|
// V2 = IOS transmitter app
|
||||||
case PACKET_TYPE_TRANSMITTER_DATA_V2:
|
_myTransmitter.processIncomingData(_incomingPacket, bytesReceived);
|
||||||
// V2 = IOS transmitter app
|
|
||||||
app->_myTransmitter.processIncomingData(app->_incomingPacket, bytesReceived);
|
break;
|
||||||
|
case PACKET_TYPE_MIXED_AUDIO:
|
||||||
break;
|
QMetaObject::invokeMethod(&_audio, "addReceivedAudioToBuffer", Qt::QueuedConnection,
|
||||||
case PACKET_TYPE_MIXED_AUDIO:
|
Q_ARG(QByteArray, QByteArray((char*) _incomingPacket, bytesReceived)));
|
||||||
QMetaObject::invokeMethod(&app->_audio, "addReceivedAudioToBuffer", Qt::QueuedConnection,
|
break;
|
||||||
Q_ARG(QByteArray, QByteArray((char*) app->_incomingPacket, bytesReceived)));
|
|
||||||
break;
|
case PACKET_TYPE_PARTICLE_ADD_RESPONSE:
|
||||||
|
// look up our ParticleEditHanders....
|
||||||
case PACKET_TYPE_PARTICLE_ADD_RESPONSE:
|
ParticleEditHandle::handleAddResponse(_incomingPacket, bytesReceived);
|
||||||
// look up our ParticleEditHanders....
|
break;
|
||||||
ParticleEditHandle::handleAddResponse(app->_incomingPacket, bytesReceived);
|
|
||||||
break;
|
case PACKET_TYPE_PARTICLE_DATA:
|
||||||
|
case PACKET_TYPE_VOXEL_DATA:
|
||||||
case PACKET_TYPE_PARTICLE_DATA:
|
case PACKET_TYPE_VOXEL_ERASE:
|
||||||
case PACKET_TYPE_VOXEL_DATA:
|
case PACKET_TYPE_OCTREE_STATS:
|
||||||
case PACKET_TYPE_VOXEL_ERASE:
|
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
||||||
case PACKET_TYPE_OCTREE_STATS:
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
"Application::networkReceive()... _voxelProcessor.queueReceivedPacket()");
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
|
||||||
"Application::networkReceive()... _voxelProcessor.queueReceivedPacket()");
|
bool wantExtraDebugging = getLogger()->extraDebugging();
|
||||||
|
if (wantExtraDebugging && _incomingPacket[0] == PACKET_TYPE_VOXEL_DATA) {
|
||||||
bool wantExtraDebugging = app->getLogger()->extraDebugging();
|
int numBytesPacketHeader = numBytesForPacketHeader(_incomingPacket);
|
||||||
if (wantExtraDebugging && app->_incomingPacket[0] == PACKET_TYPE_VOXEL_DATA) {
|
unsigned char* dataAt = _incomingPacket + numBytesPacketHeader;
|
||||||
int numBytesPacketHeader = numBytesForPacketHeader(app->_incomingPacket);
|
dataAt += sizeof(VOXEL_PACKET_FLAGS);
|
||||||
unsigned char* dataAt = app->_incomingPacket + numBytesPacketHeader;
|
VOXEL_PACKET_SEQUENCE sequence = (*(VOXEL_PACKET_SEQUENCE*)dataAt);
|
||||||
dataAt += sizeof(VOXEL_PACKET_FLAGS);
|
dataAt += sizeof(VOXEL_PACKET_SEQUENCE);
|
||||||
VOXEL_PACKET_SEQUENCE sequence = (*(VOXEL_PACKET_SEQUENCE*)dataAt);
|
VOXEL_PACKET_SENT_TIME sentAt = (*(VOXEL_PACKET_SENT_TIME*)dataAt);
|
||||||
dataAt += sizeof(VOXEL_PACKET_SEQUENCE);
|
dataAt += sizeof(VOXEL_PACKET_SENT_TIME);
|
||||||
VOXEL_PACKET_SENT_TIME sentAt = (*(VOXEL_PACKET_SENT_TIME*)dataAt);
|
VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow();
|
||||||
dataAt += sizeof(VOXEL_PACKET_SENT_TIME);
|
int flightTime = arrivedAt - sentAt;
|
||||||
VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow();
|
|
||||||
int flightTime = arrivedAt - sentAt;
|
printf("got PACKET_TYPE_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime);
|
||||||
|
|
||||||
printf("got PACKET_TYPE_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add this packet to our list of voxel packets and process them on the voxel processing
|
|
||||||
app->_voxelProcessor.queueReceivedPacket(senderSockAddr, app->_incomingPacket, bytesReceived);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case PACKET_TYPE_METAVOXEL_DATA:
|
|
||||||
app->_metavoxels.processData(QByteArray((const char*)app->_incomingPacket, bytesReceived),
|
// add this packet to our list of voxel packets and process them on the voxel processing
|
||||||
senderSockAddr);
|
_voxelProcessor.queueReceivedPacket(senderSockAddr, _incomingPacket, bytesReceived);
|
||||||
break;
|
break;
|
||||||
case PACKET_TYPE_BULK_AVATAR_DATA:
|
|
||||||
NodeList::getInstance()->processBulkNodeData(senderSockAddr,
|
|
||||||
app->_incomingPacket,
|
|
||||||
bytesReceived);
|
|
||||||
getInstance()->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
|
|
||||||
break;
|
|
||||||
case PACKET_TYPE_AVATAR_URLS:
|
|
||||||
processAvatarURLsMessage(app->_incomingPacket, bytesReceived);
|
|
||||||
break;
|
|
||||||
case PACKET_TYPE_AVATAR_FACE_VIDEO:
|
|
||||||
processAvatarFaceVideoMessage(app->_incomingPacket, bytesReceived);
|
|
||||||
break;
|
|
||||||
case PACKET_TYPE_DATA_SERVER_GET:
|
|
||||||
case PACKET_TYPE_DATA_SERVER_PUT:
|
|
||||||
case PACKET_TYPE_DATA_SERVER_SEND:
|
|
||||||
case PACKET_TYPE_DATA_SERVER_CONFIRM:
|
|
||||||
DataServerClient::processMessageFromDataServer(app->_incomingPacket, bytesReceived);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NodeList::getInstance()->processNodeData(senderSockAddr, app->_incomingPacket, bytesReceived);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
case PACKET_TYPE_METAVOXEL_DATA:
|
||||||
|
_metavoxels.processData(QByteArray((const char*) _incomingPacket, bytesReceived),
|
||||||
|
senderSockAddr);
|
||||||
|
break;
|
||||||
|
case PACKET_TYPE_BULK_AVATAR_DATA:
|
||||||
|
NodeList::getInstance()->processBulkNodeData(senderSockAddr,
|
||||||
|
_incomingPacket,
|
||||||
|
bytesReceived);
|
||||||
|
getInstance()->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
|
||||||
|
break;
|
||||||
|
case PACKET_TYPE_AVATAR_URLS:
|
||||||
|
processAvatarURLsMessage(_incomingPacket, bytesReceived);
|
||||||
|
break;
|
||||||
|
case PACKET_TYPE_AVATAR_FACE_VIDEO:
|
||||||
|
processAvatarFaceVideoMessage(_incomingPacket, bytesReceived);
|
||||||
|
break;
|
||||||
|
case PACKET_TYPE_DATA_SERVER_GET:
|
||||||
|
case PACKET_TYPE_DATA_SERVER_PUT:
|
||||||
|
case PACKET_TYPE_DATA_SERVER_SEND:
|
||||||
|
case PACKET_TYPE_DATA_SERVER_CONFIRM:
|
||||||
|
DataServerClient::processMessageFromDataServer(_incomingPacket, bytesReceived);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NodeList::getInstance()->processNodeData(senderSockAddr, _incomingPacket, bytesReceived);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (!app->_enableNetworkThread) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app->_enableNetworkThread) {
|
|
||||||
pthread_exit(0);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::packetSentNotification(ssize_t length) {
|
void Application::packetSentNotification(ssize_t length) {
|
||||||
|
@ -4478,14 +4299,12 @@ void Application::loadScript() {
|
||||||
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
|
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
|
||||||
const char* fileName = fileNameAscii.data();
|
const char* fileName = fileNameAscii.data();
|
||||||
|
|
||||||
printf("fileName:%s\n",fileName);
|
|
||||||
|
|
||||||
std::ifstream file(fileName, std::ios::in|std::ios::binary|std::ios::ate);
|
std::ifstream file(fileName, std::ios::in|std::ios::binary|std::ios::ate);
|
||||||
if(!file.is_open()) {
|
if(!file.is_open()) {
|
||||||
printf("error loading file\n");
|
qDebug("Error loading file %s", fileName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug("loading file %s...\n", fileName);
|
qDebug("Loading file %s...", fileName);
|
||||||
|
|
||||||
// get file length....
|
// get file length....
|
||||||
unsigned long fileLength = file.tellg();
|
unsigned long fileLength = file.tellg();
|
||||||
|
@ -4577,7 +4396,7 @@ void Application::updateLocalOctreeCache(bool firstTime) {
|
||||||
_persistThread = new OctreePersistThread(_voxels.getTree(),
|
_persistThread = new OctreePersistThread(_voxels.getTree(),
|
||||||
localVoxelCacheFileName.toLocal8Bit().constData(),LOCAL_CACHE_PERSIST_INTERVAL);
|
localVoxelCacheFileName.toLocal8Bit().constData(),LOCAL_CACHE_PERSIST_INTERVAL);
|
||||||
|
|
||||||
qDebug() << "updateLocalOctreeCache()... localVoxelCacheFileName=" << localVoxelCacheFileName << "\n";
|
qDebug() << "updateLocalOctreeCache()... localVoxelCacheFileName=" << localVoxelCacheFileName;
|
||||||
|
|
||||||
if (_persistThread) {
|
if (_persistThread) {
|
||||||
_voxels.beginLoadingLocalVoxelCache(); // while local voxels are importing, don't do individual node VBO updates
|
_voxels.beginLoadingLocalVoxelCache(); // while local voxels are importing, don't do individual node VBO updates
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#include "avatar/MyAvatar.h"
|
#include "avatar/MyAvatar.h"
|
||||||
#include "avatar/Profile.h"
|
#include "avatar/Profile.h"
|
||||||
#include "devices/Faceshift.h"
|
#include "devices/Faceshift.h"
|
||||||
#include "devices/SerialInterface.h"
|
|
||||||
#include "devices/SixenseManager.h"
|
#include "devices/SixenseManager.h"
|
||||||
#include "devices/Webcam.h"
|
#include "devices/Webcam.h"
|
||||||
#include "renderer/AmbientOcclusionEffect.h"
|
#include "renderer/AmbientOcclusionEffect.h"
|
||||||
|
@ -95,7 +94,7 @@ static const float NODE_KILLED_RED = 1.0f;
|
||||||
static const float NODE_KILLED_GREEN = 0.0f;
|
static const float NODE_KILLED_GREEN = 0.0f;
|
||||||
static const float NODE_KILLED_BLUE = 0.0f;
|
static const float NODE_KILLED_BLUE = 0.0f;
|
||||||
|
|
||||||
class Application : public QApplication, public NodeListHook, public PacketSenderNotify, public DomainChangeListener {
|
class Application : public QApplication, public PacketSenderNotify {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
friend class VoxelPacketProcessor;
|
friend class VoxelPacketProcessor;
|
||||||
|
@ -142,7 +141,7 @@ public:
|
||||||
|
|
||||||
void removeVoxel(glm::vec3 position, float scale);
|
void removeVoxel(glm::vec3 position, float scale);
|
||||||
|
|
||||||
const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel);
|
glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVoxel);
|
||||||
|
|
||||||
QGLWidget* getGLWidget() { return _glWidget; }
|
QGLWidget* getGLWidget() { return _glWidget; }
|
||||||
MyAvatar* getAvatar() { return &_myAvatar; }
|
MyAvatar* getAvatar() { return &_myAvatar; }
|
||||||
|
@ -155,7 +154,6 @@ public:
|
||||||
VoxelTree* getClipboard() { return &_clipboard; }
|
VoxelTree* getClipboard() { return &_clipboard; }
|
||||||
Environment* getEnvironment() { return &_environment; }
|
Environment* getEnvironment() { return &_environment; }
|
||||||
bool isMouseHidden() const { return _mouseHidden; }
|
bool isMouseHidden() const { return _mouseHidden; }
|
||||||
SerialInterface* getSerialHeadSensor() { return &_serialHeadSensor; }
|
|
||||||
Webcam* getWebcam() { return &_webcam; }
|
Webcam* getWebcam() { return &_webcam; }
|
||||||
Faceshift* getFaceshift() { return &_faceshift; }
|
Faceshift* getFaceshift() { return &_faceshift; }
|
||||||
SixenseManager* getSixenseManager() { return &_sixenseManager; }
|
SixenseManager* getSixenseManager() { return &_sixenseManager; }
|
||||||
|
@ -194,12 +192,9 @@ public:
|
||||||
void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& near,
|
void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& near,
|
||||||
float& far, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const;
|
float& far, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const;
|
||||||
|
|
||||||
virtual void nodeAdded(Node* node);
|
|
||||||
virtual void nodeKilled(Node* node);
|
|
||||||
virtual void packetSentNotification(ssize_t length);
|
virtual void packetSentNotification(ssize_t length);
|
||||||
|
|
||||||
virtual void domainChanged(QString domain);
|
|
||||||
|
|
||||||
VoxelShader& getVoxelShader() { return _voxelShader; }
|
VoxelShader& getVoxelShader() { return _voxelShader; }
|
||||||
PointShader& getPointShader() { return _pointShader; }
|
PointShader& getPointShader() { return _pointShader; }
|
||||||
FileLogger* getLogger() { return _logger; }
|
FileLogger* getLogger() { return _logger; }
|
||||||
|
@ -214,6 +209,11 @@ public:
|
||||||
void setIsHighlightVoxel(bool isHighlightVoxel) { _isHighlightVoxel = isHighlightVoxel; }
|
void setIsHighlightVoxel(bool isHighlightVoxel) { _isHighlightVoxel = isHighlightVoxel; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void domainChanged(const QString& domainHostname);
|
||||||
|
void nodeKilled(SharedNodePointer node);
|
||||||
|
|
||||||
|
void processDatagrams();
|
||||||
|
|
||||||
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
||||||
void exportVoxels();
|
void exportVoxels();
|
||||||
void importVoxels();
|
void importVoxels();
|
||||||
|
@ -250,8 +250,6 @@ private slots:
|
||||||
|
|
||||||
glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint);
|
glm::vec2 getScaledScreenPoint(glm::vec2 projectedPoint);
|
||||||
|
|
||||||
void toggleFollowMode();
|
|
||||||
|
|
||||||
void closeMirrorView();
|
void closeMirrorView();
|
||||||
void restoreMirrorView();
|
void restoreMirrorView();
|
||||||
void shrinkMirrorView();
|
void shrinkMirrorView();
|
||||||
|
@ -301,7 +299,6 @@ private:
|
||||||
bool isLookingAtMyAvatar(Avatar* avatar);
|
bool isLookingAtMyAvatar(Avatar* avatar);
|
||||||
|
|
||||||
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
void renderLookatIndicator(glm::vec3 pointOfInterest);
|
||||||
void renderFollowIndicator();
|
|
||||||
void renderHighlightVoxel(VoxelDetail voxel);
|
void renderHighlightVoxel(VoxelDetail voxel);
|
||||||
|
|
||||||
void updateAvatar(float deltaTime);
|
void updateAvatar(float deltaTime);
|
||||||
|
@ -335,14 +332,10 @@ private:
|
||||||
QMainWindow* _window;
|
QMainWindow* _window;
|
||||||
QGLWidget* _glWidget;
|
QGLWidget* _glWidget;
|
||||||
|
|
||||||
QAction* _followMode;
|
|
||||||
|
|
||||||
BandwidthMeter _bandwidthMeter;
|
BandwidthMeter _bandwidthMeter;
|
||||||
|
|
||||||
SerialInterface _serialHeadSensor;
|
|
||||||
QNetworkAccessManager* _networkAccessManager;
|
QNetworkAccessManager* _networkAccessManager;
|
||||||
QSettings* _settings;
|
QSettings* _settings;
|
||||||
bool _displayLevels;
|
|
||||||
|
|
||||||
glm::vec3 _gravity;
|
glm::vec3 _gravity;
|
||||||
|
|
||||||
|
@ -469,10 +462,6 @@ private:
|
||||||
Audio _audio;
|
Audio _audio;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool _enableNetworkThread;
|
|
||||||
pthread_t _networkReceiveThread;
|
|
||||||
bool _stopNetworkReceiveThread;
|
|
||||||
|
|
||||||
bool _enableProcessVoxelsThread;
|
bool _enableProcessVoxelsThread;
|
||||||
VoxelPacketProcessor _voxelProcessor;
|
VoxelPacketProcessor _voxelProcessor;
|
||||||
VoxelHideShowThread _voxelHideShowThread;
|
VoxelHideShowThread _voxelHideShowThread;
|
||||||
|
|
|
@ -136,8 +136,8 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice,
|
||||||
const QAudioFormat& desiredAudioFormat,
|
const QAudioFormat& desiredAudioFormat,
|
||||||
QAudioFormat& adjustedAudioFormat) {
|
QAudioFormat& adjustedAudioFormat) {
|
||||||
if (!audioDevice.isFormatSupported(desiredAudioFormat)) {
|
if (!audioDevice.isFormatSupported(desiredAudioFormat)) {
|
||||||
qDebug() << "The desired format for audio I/O is" << desiredAudioFormat << "\n";
|
qDebug() << "The desired format for audio I/O is" << desiredAudioFormat;
|
||||||
qDebug() << "The desired audio format is not supported by this device.\n";
|
qDebug("The desired audio format is not supported by this device");
|
||||||
|
|
||||||
if (desiredAudioFormat.channelCount() == 1) {
|
if (desiredAudioFormat.channelCount() == 1) {
|
||||||
adjustedAudioFormat = desiredAudioFormat;
|
adjustedAudioFormat = desiredAudioFormat;
|
||||||
|
@ -244,10 +244,10 @@ void Audio::start() {
|
||||||
|
|
||||||
QAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput);
|
QAudioDeviceInfo inputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioInput);
|
||||||
|
|
||||||
qDebug() << "The audio input device is" << inputDeviceInfo.deviceName() << "\n";
|
qDebug() << "The audio input device is" << inputDeviceInfo.deviceName();
|
||||||
|
|
||||||
if (adjustedFormatForAudioDevice(inputDeviceInfo, _desiredInputFormat, _inputFormat)) {
|
if (adjustedFormatForAudioDevice(inputDeviceInfo, _desiredInputFormat, _inputFormat)) {
|
||||||
qDebug() << "The format to be used for audio input is" << _inputFormat << "\n";
|
qDebug() << "The format to be used for audio input is" << _inputFormat;
|
||||||
|
|
||||||
_audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this);
|
_audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this);
|
||||||
_numInputCallbackBytes = NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL * _inputFormat.channelCount()
|
_numInputCallbackBytes = NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL * _inputFormat.channelCount()
|
||||||
|
@ -257,10 +257,10 @@ void Audio::start() {
|
||||||
|
|
||||||
QAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput);
|
QAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput);
|
||||||
|
|
||||||
qDebug() << "The audio output device is" << outputDeviceInfo.deviceName() << "\n";
|
qDebug() << "The audio output device is" << outputDeviceInfo.deviceName();
|
||||||
|
|
||||||
if (adjustedFormatForAudioDevice(outputDeviceInfo, _desiredOutputFormat, _outputFormat)) {
|
if (adjustedFormatForAudioDevice(outputDeviceInfo, _desiredOutputFormat, _outputFormat)) {
|
||||||
qDebug() << "The format to be used for audio output is" << _outputFormat << "\n";
|
qDebug() << "The format to be used for audio output is" << _outputFormat;
|
||||||
|
|
||||||
_inputRingBuffer.resizeForFrameSize(_numInputCallbackBytes * CALLBACK_ACCELERATOR_RATIO / sizeof(int16_t));
|
_inputRingBuffer.resizeForFrameSize(_numInputCallbackBytes * CALLBACK_ACCELERATOR_RATIO / sizeof(int16_t));
|
||||||
_inputDevice = _audioInput->start();
|
_inputDevice = _audioInput->start();
|
||||||
|
@ -279,7 +279,7 @@ void Audio::start() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Unable to set up audio I/O because of a problem with input or output formats.\n";
|
qDebug() << "Unable to set up audio I/O because of a problem with input or output formats.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::handleAudioInput() {
|
void Audio::handleAudioInput() {
|
||||||
|
@ -365,9 +365,9 @@ void Audio::handleAudioInput() {
|
||||||
NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
Node* audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||||
|
|
||||||
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer)) {
|
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer.data())) {
|
||||||
MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar();
|
MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar();
|
||||||
|
|
||||||
glm::vec3 headPosition = interfaceAvatar->getHeadJointPosition();
|
glm::vec3 headPosition = interfaceAvatar->getHeadJointPosition();
|
||||||
|
@ -448,7 +448,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
|
||||||
if (!_ringBuffer.isNotStarvedOrHasMinimumSamples(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO
|
if (!_ringBuffer.isNotStarvedOrHasMinimumSamples(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO
|
||||||
+ (_jitterBufferSamples * 2))) {
|
+ (_jitterBufferSamples * 2))) {
|
||||||
// starved and we don't have enough to start, keep waiting
|
// starved and we don't have enough to start, keep waiting
|
||||||
qDebug() << "Buffer is starved and doesn't have enough samples to start. Held back.\n";
|
qDebug() << "Buffer is starved and doesn't have enough samples to start. Held back.";
|
||||||
} else {
|
} else {
|
||||||
// We are either already playing back, or we have enough audio to start playing back.
|
// We are either already playing back, or we have enough audio to start playing back.
|
||||||
_ringBuffer.setIsStarved(false);
|
_ringBuffer.setIsStarved(false);
|
||||||
|
@ -518,7 +518,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
|
||||||
} else if (_audioOutput->bytesFree() == _audioOutput->bufferSize()) {
|
} else if (_audioOutput->bytesFree() == _audioOutput->bufferSize()) {
|
||||||
// we don't have any audio data left in the output buffer, and the ring buffer from
|
// we don't have any audio data left in the output buffer, and the ring buffer from
|
||||||
// the network has nothing in it either - we just starved
|
// the network has nothing in it either - we just starved
|
||||||
qDebug() << "Audio output just starved.\n";
|
qDebug() << "Audio output just starved.";
|
||||||
_ringBuffer.setIsStarved(true);
|
_ringBuffer.setIsStarved(true);
|
||||||
_numFramesDisplayStarve = 10;
|
_numFramesDisplayStarve = 10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ BuckyBalls::BuckyBalls() {
|
||||||
colors[1] = glm::vec3(0.64f, 0.16f, 0.16f);
|
colors[1] = glm::vec3(0.64f, 0.16f, 0.16f);
|
||||||
colors[2] = glm::vec3(0.31f, 0.58f, 0.80f);
|
colors[2] = glm::vec3(0.31f, 0.58f, 0.80f);
|
||||||
|
|
||||||
qDebug("Creating buckyballs...\n");
|
qDebug("Creating buckyballs...");
|
||||||
for (int i = 0; i < NUM_BBALLS; i++) {
|
for (int i = 0; i < NUM_BBALLS; i++) {
|
||||||
_bballPosition[i] = CORNER_BBALLS + randVector() * RANGE_BBALLS;
|
_bballPosition[i] = CORNER_BBALLS + randVector() * RANGE_BBALLS;
|
||||||
int element = (rand() % NUM_ELEMENTS);
|
int element = (rand() % NUM_ELEMENTS);
|
||||||
|
|
|
@ -140,18 +140,18 @@ void DataServerClient::processSendFromDataServer(unsigned char* packetData, int
|
||||||
if (keyList[i] == DataServerKey::FaceMeshURL) {
|
if (keyList[i] == DataServerKey::FaceMeshURL) {
|
||||||
|
|
||||||
if (userUUID.isNull() || userUUID == Application::getInstance()->getProfile()->getUUID()) {
|
if (userUUID.isNull() || userUUID == Application::getInstance()->getProfile()->getUUID()) {
|
||||||
qDebug("Changing user's face model URL to %s\n", valueList[i].toLocal8Bit().constData());
|
qDebug("Changing user's face model URL to %s", valueList[i].toLocal8Bit().constData());
|
||||||
Application::getInstance()->getProfile()->setFaceModelURL(QUrl(valueList[i]));
|
Application::getInstance()->getProfile()->setFaceModelURL(QUrl(valueList[i]));
|
||||||
} else {
|
} else {
|
||||||
// mesh URL for a UUID, find avatar in our list
|
// mesh URL for a UUID, find avatar in our list
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||||
Avatar* avatar = (Avatar *) node->getLinkedData();
|
Avatar* avatar = (Avatar *) node->getLinkedData();
|
||||||
|
|
||||||
if (avatar->getUUID() == userUUID) {
|
if (avatar->getUUID() == userUUID) {
|
||||||
QMetaObject::invokeMethod(&avatar->getHead().getFaceModel(),
|
QMetaObject::invokeMethod(&avatar->getHead().getFaceModel(),
|
||||||
"setURL", Q_ARG(QUrl, QUrl(valueList[i])));
|
"setURL", Q_ARG(QUrl, QUrl(valueList[i])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,18 +159,17 @@ void DataServerClient::processSendFromDataServer(unsigned char* packetData, int
|
||||||
} else if (keyList[i] == DataServerKey::SkeletonURL) {
|
} else if (keyList[i] == DataServerKey::SkeletonURL) {
|
||||||
|
|
||||||
if (userUUID.isNull() || userUUID == Application::getInstance()->getProfile()->getUUID()) {
|
if (userUUID.isNull() || userUUID == Application::getInstance()->getProfile()->getUUID()) {
|
||||||
qDebug("Changing user's skeleton URL to %s\n", valueList[i].toLocal8Bit().constData());
|
qDebug("Changing user's skeleton URL to %s", valueList[i].toLocal8Bit().constData());
|
||||||
Application::getInstance()->getProfile()->setSkeletonModelURL(QUrl(valueList[i]));
|
Application::getInstance()->getProfile()->setSkeletonModelURL(QUrl(valueList[i]));
|
||||||
} else {
|
} else {
|
||||||
// skeleton URL for a UUID, find avatar in our list
|
// skeleton URL for a UUID, find avatar in our list
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||||
Avatar* avatar = (Avatar *) node->getLinkedData();
|
Avatar* avatar = (Avatar *) node->getLinkedData();
|
||||||
|
|
||||||
if (avatar->getUUID() == userUUID) {
|
if (avatar->getUUID() == userUUID) {
|
||||||
QMetaObject::invokeMethod(&avatar->getSkeletonModel(), "setURL",
|
QMetaObject::invokeMethod(&avatar->getSkeletonModel(), "setURL",
|
||||||
Q_ARG(QUrl, QUrl(valueList[i])));
|
Q_ARG(QUrl, QUrl(valueList[i])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +189,7 @@ void DataServerClient::processSendFromDataServer(unsigned char* packetData, int
|
||||||
qDebug() << "Changing domain to" << valueList[i].toLocal8Bit().constData() <<
|
qDebug() << "Changing domain to" << valueList[i].toLocal8Bit().constData() <<
|
||||||
", position to" << valueList[i + 1].toLocal8Bit().constData() <<
|
", position to" << valueList[i + 1].toLocal8Bit().constData() <<
|
||||||
", and orientation to" << valueList[i + 2].toLocal8Bit().constData() <<
|
", and orientation to" << valueList[i + 2].toLocal8Bit().constData() <<
|
||||||
"to go to" << userString << "\n";
|
"to go to" << userString;
|
||||||
|
|
||||||
NodeList::getInstance()->setDomainHostname(valueList[i]);
|
NodeList::getInstance()->setDomainHostname(valueList[i]);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ Environment::~Environment() {
|
||||||
|
|
||||||
void Environment::init() {
|
void Environment::init() {
|
||||||
if (_initialized) {
|
if (_initialized) {
|
||||||
qDebug("[ERROR] Environment is already initialized.\n");
|
qDebug("[ERROR] Environment is already initialized.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ Menu* Menu::getInstance() {
|
||||||
menuInstanceMutex.lock();
|
menuInstanceMutex.lock();
|
||||||
|
|
||||||
if (!_instance) {
|
if (!_instance) {
|
||||||
qDebug("First call to Menu::getInstance() - initing menu.\n");
|
qDebug("First call to Menu::getInstance() - initing menu.");
|
||||||
|
|
||||||
_instance = new Menu();
|
_instance = new Menu();
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ Menu::Menu() :
|
||||||
SLOT(decreaseSize()));
|
SLOT(decreaseSize()));
|
||||||
addActionToQMenuAndActionHash(avatarSizeMenu,
|
addActionToQMenuAndActionHash(avatarSizeMenu,
|
||||||
MenuOption::ResetAvatarSize,
|
MenuOption::ResetAvatarSize,
|
||||||
0,
|
Qt::Key_Equal,
|
||||||
appInstance->getAvatar(),
|
appInstance->getAvatar(),
|
||||||
SLOT(resetSize()));
|
SLOT(resetSize()));
|
||||||
|
|
||||||
|
@ -978,7 +978,7 @@ void Menu::goToLocation() {
|
||||||
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
|
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
|
||||||
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
|
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
|
||||||
|
|
||||||
qDebug("Going To Location: %f, %f, %f...\n", x, y, z);
|
qDebug("Going To Location: %f, %f, %f...", x, y, z);
|
||||||
myAvatar->setPosition(newAvatarPos);
|
myAvatar->setPosition(newAvatarPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1027,7 +1027,7 @@ void Menu::pasteToVoxel() {
|
||||||
if (locationToPaste == octalCodeToHexString(octalCodeDestination)) {
|
if (locationToPaste == octalCodeToHexString(octalCodeDestination)) {
|
||||||
Application::getInstance()->pasteVoxelsToOctalCode(octalCodeDestination);
|
Application::getInstance()->pasteVoxelsToOctalCode(octalCodeDestination);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "problem with octcode...\n";
|
qDebug() << "Problem with octcode...";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,6 @@ MetavoxelSystem::MetavoxelSystem() :
|
||||||
_buffer(QOpenGLBuffer::VertexBuffer) {
|
_buffer(QOpenGLBuffer::VertexBuffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelSystem::~MetavoxelSystem() {
|
|
||||||
NodeList::getInstance()->removeHook(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetavoxelSystem::init() {
|
void MetavoxelSystem::init() {
|
||||||
if (!_program.isLinked()) {
|
if (!_program.isLinked()) {
|
||||||
switchToResourcesParentIfRequired();
|
switchToResourcesParentIfRequired();
|
||||||
|
@ -39,7 +35,10 @@ void MetavoxelSystem::init() {
|
||||||
_pointScaleLocation = _program.uniformLocation("pointScale");
|
_pointScaleLocation = _program.uniformLocation("pointScale");
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList::getInstance()->addHook(this);
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(nodeAdded(SharedNodePointer)));
|
||||||
|
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||||
|
|
||||||
AttributeRegistry::getInstance()->configureScriptEngine(&_scriptEngine);
|
AttributeRegistry::getInstance()->configureScriptEngine(&_scriptEngine);
|
||||||
|
|
||||||
|
@ -117,14 +116,14 @@ void MetavoxelSystem::render() {
|
||||||
_program.release();
|
_program.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelSystem::nodeAdded(Node* node) {
|
void MetavoxelSystem::nodeAdded(SharedNodePointer node) {
|
||||||
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
|
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
|
||||||
QMetaObject::invokeMethod(this, "addClient", Q_ARG(const QUuid&, node->getUUID()),
|
QMetaObject::invokeMethod(this, "addClient", Q_ARG(const QUuid&, node->getUUID()),
|
||||||
Q_ARG(const HifiSockAddr&, node->getLocalSocket()));
|
Q_ARG(const HifiSockAddr&, node->getLocalSocket()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelSystem::nodeKilled(Node* node) {
|
void MetavoxelSystem::nodeKilled(SharedNodePointer node) {
|
||||||
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
|
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
|
||||||
QMetaObject::invokeMethod(this, "removeClient", Q_ARG(const QUuid&, node->getUUID()));
|
QMetaObject::invokeMethod(this, "removeClient", Q_ARG(const QUuid&, node->getUUID()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,11 @@
|
||||||
class MetavoxelClient;
|
class MetavoxelClient;
|
||||||
|
|
||||||
/// Renders a metavoxel tree.
|
/// Renders a metavoxel tree.
|
||||||
class MetavoxelSystem : public QObject, public NodeListHook {
|
class MetavoxelSystem : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MetavoxelSystem();
|
MetavoxelSystem();
|
||||||
~MetavoxelSystem();
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
@ -41,9 +39,9 @@ public:
|
||||||
void simulate(float deltaTime);
|
void simulate(float deltaTime);
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
virtual void nodeAdded(Node* node);
|
public slots:
|
||||||
virtual void nodeKilled(Node* node);
|
void nodeAdded(SharedNodePointer node);
|
||||||
|
void nodeKilled(SharedNodePointer node);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Q_INVOKABLE void addClient(const QUuid& uuid, const HifiSockAddr& address);
|
Q_INVOKABLE void addClient(const QUuid& uuid, const HifiSockAddr& address);
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
#include "Oscilloscope.h"
|
#include "Oscilloscope.h"
|
||||||
|
|
|
@ -47,7 +47,7 @@ void PairingHandler::sendPairRequest() {
|
||||||
(localAddress >> 24) & 0xFF,
|
(localAddress >> 24) & 0xFF,
|
||||||
NodeList::getInstance()->getNodeSocket().localPort());
|
NodeList::getInstance()->getNodeSocket().localPort());
|
||||||
|
|
||||||
qDebug("Sending pair packet: %s\n", pairPacket);
|
qDebug("Sending pair packet: %s", pairPacket);
|
||||||
|
|
||||||
HifiSockAddr pairingServerSocket(PAIRING_SERVER_HOSTNAME, PAIRING_SERVER_PORT);
|
HifiSockAddr pairingServerSocket(PAIRING_SERVER_HOSTNAME, PAIRING_SERVER_PORT);
|
||||||
|
|
||||||
|
|
|
@ -610,7 +610,7 @@ void runTimingTests() {
|
||||||
gettimeofday(&endTime, NULL);
|
gettimeofday(&endTime, NULL);
|
||||||
}
|
}
|
||||||
elapsedMsecs = diffclock(&startTime, &endTime);
|
elapsedMsecs = diffclock(&startTime, &endTime);
|
||||||
qDebug("gettimeofday() usecs: %f\n", 1000.0f * elapsedMsecs / (float) numTests);
|
qDebug("gettimeofday() usecs: %f", 1000.0f * elapsedMsecs / (float) numTests);
|
||||||
|
|
||||||
// Random number generation
|
// Random number generation
|
||||||
gettimeofday(&startTime, NULL);
|
gettimeofday(&startTime, NULL);
|
||||||
|
@ -619,7 +619,7 @@ void runTimingTests() {
|
||||||
}
|
}
|
||||||
gettimeofday(&endTime, NULL);
|
gettimeofday(&endTime, NULL);
|
||||||
elapsedMsecs = diffclock(&startTime, &endTime);
|
elapsedMsecs = diffclock(&startTime, &endTime);
|
||||||
qDebug("rand() stored in array usecs: %f\n", 1000.0f * elapsedMsecs / (float) numTests);
|
qDebug("rand() stored in array usecs: %f", 1000.0f * elapsedMsecs / (float) numTests);
|
||||||
|
|
||||||
// Random number generation using randFloat()
|
// Random number generation using randFloat()
|
||||||
gettimeofday(&startTime, NULL);
|
gettimeofday(&startTime, NULL);
|
||||||
|
@ -628,7 +628,7 @@ void runTimingTests() {
|
||||||
}
|
}
|
||||||
gettimeofday(&endTime, NULL);
|
gettimeofday(&endTime, NULL);
|
||||||
elapsedMsecs = diffclock(&startTime, &endTime);
|
elapsedMsecs = diffclock(&startTime, &endTime);
|
||||||
qDebug("randFloat() stored in array usecs: %f\n", 1000.0f * elapsedMsecs / (float) numTests);
|
qDebug("randFloat() stored in array usecs: %f", 1000.0f * elapsedMsecs / (float) numTests);
|
||||||
|
|
||||||
// PowF function
|
// PowF function
|
||||||
fTest = 1145323.2342f;
|
fTest = 1145323.2342f;
|
||||||
|
@ -638,7 +638,7 @@ void runTimingTests() {
|
||||||
}
|
}
|
||||||
gettimeofday(&endTime, NULL);
|
gettimeofday(&endTime, NULL);
|
||||||
elapsedMsecs = diffclock(&startTime, &endTime);
|
elapsedMsecs = diffclock(&startTime, &endTime);
|
||||||
qDebug("powf(f, 0.5) usecs: %f\n", 1000.0f * elapsedMsecs / (float) numTests);
|
qDebug("powf(f, 0.5) usecs: %f", 1000.0f * elapsedMsecs / (float) numTests);
|
||||||
|
|
||||||
// Vector Math
|
// Vector Math
|
||||||
float distance;
|
float distance;
|
||||||
|
@ -651,7 +651,7 @@ void runTimingTests() {
|
||||||
}
|
}
|
||||||
gettimeofday(&endTime, NULL);
|
gettimeofday(&endTime, NULL);
|
||||||
elapsedMsecs = diffclock(&startTime, &endTime);
|
elapsedMsecs = diffclock(&startTime, &endTime);
|
||||||
qDebug("vector math usecs: %f [%f msecs total for %d tests]\n",
|
qDebug("vector math usecs: %f [%f msecs total for %d tests]",
|
||||||
1000.0f * elapsedMsecs / (float) numTests, elapsedMsecs, numTests);
|
1000.0f * elapsedMsecs / (float) numTests, elapsedMsecs, numTests);
|
||||||
|
|
||||||
// Vec3 test
|
// Vec3 test
|
||||||
|
@ -665,7 +665,7 @@ void runTimingTests() {
|
||||||
}
|
}
|
||||||
gettimeofday(&endTime, NULL);
|
gettimeofday(&endTime, NULL);
|
||||||
elapsedMsecs = diffclock(&startTime, &endTime);
|
elapsedMsecs = diffclock(&startTime, &endTime);
|
||||||
qDebug("vec3 assign and dot() usecs: %f\n", 1000.0f * elapsedMsecs / (float) numTests);
|
qDebug("vec3 assign and dot() usecs: %f", 1000.0f * elapsedMsecs / (float) numTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
float loadSetting(QSettings* settings, const char* name, float defaultValue) {
|
float loadSetting(QSettings* settings, const char* name, float defaultValue) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ bool VoxelHideShowThread::process() {
|
||||||
|
|
||||||
bool showExtraDebugging = Application::getInstance()->getLogger()->extraDebugging();
|
bool showExtraDebugging = Application::getInstance()->getLogger()->extraDebugging();
|
||||||
if (showExtraDebugging && elapsed > USECS_PER_FRAME) {
|
if (showExtraDebugging && elapsed > USECS_PER_FRAME) {
|
||||||
qDebug() << "VoxelHideShowThread::process()... checkForCulling took " << elapsed << "\n";
|
qDebug() << "VoxelHideShowThread::process()... checkForCulling took" << elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStillRunning()) {
|
if (isStillRunning()) {
|
||||||
|
|
|
@ -172,7 +172,7 @@ void ImportTask::run() {
|
||||||
} else if (_filename.endsWith(".schematic", Qt::CaseInsensitive)) {
|
} else if (_filename.endsWith(".schematic", Qt::CaseInsensitive)) {
|
||||||
voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data());
|
voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data());
|
||||||
} else {
|
} else {
|
||||||
qDebug("[ERROR] Invalid file extension.\n");
|
qDebug("[ERROR] Invalid file extension.");
|
||||||
}
|
}
|
||||||
|
|
||||||
voxelSystem->getTree()->reaverageOctreeElements();
|
voxelSystem->getTree()->reaverageOctreeElements();
|
||||||
|
|
|
@ -21,7 +21,7 @@ void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, uns
|
||||||
const int WAY_BEHIND = 300;
|
const int WAY_BEHIND = 300;
|
||||||
|
|
||||||
if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) {
|
if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) {
|
||||||
qDebug("VoxelPacketProcessor::processPacket() packets to process=%d\n", packetsToProcessCount());
|
qDebug("VoxelPacketProcessor::processPacket() packets to process=%d", packetsToProcessCount());
|
||||||
}
|
}
|
||||||
ssize_t messageLength = packetLength;
|
ssize_t messageLength = packetLength;
|
||||||
|
|
||||||
|
@ -57,12 +57,13 @@ void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, uns
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||||
app->trackIncomingVoxelPacket(packetData, messageLength, senderSockAddr, wasStatsPacket);
|
app->trackIncomingVoxelPacket(packetData, messageLength, senderSockAddr, wasStatsPacket);
|
||||||
|
|
||||||
Node* serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
SharedNodePointer serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||||
if (serverNode && serverNode->getActiveSocket() && *serverNode->getActiveSocket() == senderSockAddr) {
|
if (serverNode && serverNode->getActiveSocket() && *serverNode->getActiveSocket() == senderSockAddr) {
|
||||||
|
|
||||||
switch(packetData[0]) {
|
switch(packetData[0]) {
|
||||||
case PACKET_TYPE_PARTICLE_DATA: {
|
case PACKET_TYPE_PARTICLE_DATA: {
|
||||||
app->_particles.processDatagram(QByteArray((char*) packetData, messageLength), senderSockAddr, serverNode);
|
app->_particles.processDatagram(QByteArray((char*) packetData, messageLength),
|
||||||
|
senderSockAddr, serverNode.data());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
||||||
|
|
|
@ -204,7 +204,7 @@ glBufferIndex VoxelSystem::getNextBufferIndex() {
|
||||||
// will be "invisible"
|
// will be "invisible"
|
||||||
void VoxelSystem::freeBufferIndex(glBufferIndex index) {
|
void VoxelSystem::freeBufferIndex(glBufferIndex index) {
|
||||||
if (_voxelsInWriteArrays == 0) {
|
if (_voxelsInWriteArrays == 0) {
|
||||||
qDebug() << "freeBufferIndex() called when _voxelsInWriteArrays == 0!!!!\n";
|
qDebug() << "freeBufferIndex() called when _voxelsInWriteArrays == 0!";
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the "freed" index was our max index, then just drop the _voxelsInWriteArrays down one...
|
// if the "freed" index was our max index, then just drop the _voxelsInWriteArrays down one...
|
||||||
|
@ -214,7 +214,7 @@ void VoxelSystem::freeBufferIndex(glBufferIndex index) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AutomaticallyAuditTree)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::AutomaticallyAuditTree)) {
|
||||||
for (long i = 0; i < _freeIndexes.size(); i++) {
|
for (long i = 0; i < _freeIndexes.size(); i++) {
|
||||||
if (_freeIndexes[i] == index) {
|
if (_freeIndexes[i] == index) {
|
||||||
printf("freeBufferIndex(glBufferIndex index)... index=%ld already in free list!\n", index);
|
printf("freeBufferIndex(glBufferIndex index)... index=%ld already in free list!", index);
|
||||||
inList = true;
|
inList = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -615,7 +615,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
if (Application::getInstance()->getLogger()->extraDebugging()) {
|
if (Application::getInstance()->getLogger()->extraDebugging()) {
|
||||||
qDebug("VoxelSystem::parseData() ... Got Packet Section"
|
qDebug("VoxelSystem::parseData() ... Got Packet Section"
|
||||||
" color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"
|
" color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"
|
||||||
" subsection:%d sectionLength:%d uncompressed:%d\n",
|
" subsection:%d sectionLength:%d uncompressed:%d",
|
||||||
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
||||||
sequence, flightTime, numBytes, dataBytes, subsection, sectionLength, packetData.getUncompressedSize());
|
sequence, flightTime, numBytes, dataBytes, subsection, sectionLength, packetData.getUncompressedSize());
|
||||||
}
|
}
|
||||||
|
@ -704,7 +704,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
||||||
|
|
||||||
bool extraDebugging = Application::getInstance()->getLogger()->extraDebugging();
|
bool extraDebugging = Application::getInstance()->getLogger()->extraDebugging();
|
||||||
if (extraDebugging) {
|
if (extraDebugging) {
|
||||||
qDebug("setupNewVoxelsForDrawing()... _voxelsUpdated=%lu...\n",_voxelsUpdated);
|
qDebug("setupNewVoxelsForDrawing()... _voxelsUpdated=%lu...",_voxelsUpdated);
|
||||||
_viewFrustum->printDebugDetails();
|
_viewFrustum->printDebugDetails();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -801,7 +801,7 @@ void VoxelSystem::cleanupRemovedVoxels() {
|
||||||
// This handles cleanup of voxels that were culled as part of our regular out of view culling operation
|
// This handles cleanup of voxels that were culled as part of our regular out of view culling operation
|
||||||
if (!_removedVoxels.isEmpty()) {
|
if (!_removedVoxels.isEmpty()) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
||||||
qDebug() << "cleanupRemovedVoxels().. _removedVoxels=" << _removedVoxels.count() << "\n";
|
qDebug() << "cleanupRemovedVoxels().. _removedVoxels=" << _removedVoxels.count();
|
||||||
}
|
}
|
||||||
while (!_removedVoxels.isEmpty()) {
|
while (!_removedVoxels.isEmpty()) {
|
||||||
delete _removedVoxels.extract();
|
delete _removedVoxels.extract();
|
||||||
|
@ -815,7 +815,7 @@ void VoxelSystem::cleanupRemovedVoxels() {
|
||||||
if (!_writeRenderFullVBO && (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) {
|
if (!_writeRenderFullVBO && (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
||||||
qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots ["
|
qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots ["
|
||||||
<< _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO \n";
|
<< _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO";
|
||||||
}
|
}
|
||||||
_writeRenderFullVBO = true;
|
_writeRenderFullVBO = true;
|
||||||
}
|
}
|
||||||
|
@ -982,7 +982,7 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo
|
||||||
// possibly shifting down to lower LOD or something. This debug message is to help identify, if/when/how this
|
// possibly shifting down to lower LOD or something. This debug message is to help identify, if/when/how this
|
||||||
// state actually occurs.
|
// state actually occurs.
|
||||||
if (Application::getInstance()->getLogger()->extraDebugging()) {
|
if (Application::getInstance()->getLogger()->extraDebugging()) {
|
||||||
qDebug("OHHHH NOOOOOO!!!! updateNodeInArrays() BAILING (_voxelsInWriteArrays >= _maxVoxels)\n");
|
qDebug("OH NO! updateNodeInArrays() BAILING (_voxelsInWriteArrays >= _maxVoxels)");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1062,7 +1062,7 @@ ProgramObject VoxelSystem::_shadowMapProgram;
|
||||||
|
|
||||||
void VoxelSystem::init() {
|
void VoxelSystem::init() {
|
||||||
if (_initialized) {
|
if (_initialized) {
|
||||||
qDebug("[ERROR] VoxelSystem is already initialized.\n");
|
qDebug("[ERROR] VoxelSystem is already initialized.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1436,7 +1436,7 @@ void VoxelSystem::clearAllNodesBufferIndex() {
|
||||||
_tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation);
|
_tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation);
|
||||||
unlockTree();
|
unlockTree();
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
|
||||||
qDebug("clearing buffer index of %d nodes\n", _nodeCount);
|
qDebug("clearing buffer index of %d nodes", _nodeCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1449,7 +1449,7 @@ bool VoxelSystem::forceRedrawEntireTreeOperation(OctreeElement* element, void* e
|
||||||
void VoxelSystem::forceRedrawEntireTree() {
|
void VoxelSystem::forceRedrawEntireTree() {
|
||||||
_nodeCount = 0;
|
_nodeCount = 0;
|
||||||
_tree->recurseTreeWithOperation(forceRedrawEntireTreeOperation);
|
_tree->recurseTreeWithOperation(forceRedrawEntireTreeOperation);
|
||||||
qDebug("forcing redraw of %d nodes\n", _nodeCount);
|
qDebug("forcing redraw of %d nodes", _nodeCount);
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
@ -1467,7 +1467,7 @@ bool VoxelSystem::randomColorOperation(OctreeElement* element, void* extraData)
|
||||||
void VoxelSystem::randomizeVoxelColors() {
|
void VoxelSystem::randomizeVoxelColors() {
|
||||||
_nodeCount = 0;
|
_nodeCount = 0;
|
||||||
_tree->recurseTreeWithOperation(randomColorOperation);
|
_tree->recurseTreeWithOperation(randomColorOperation);
|
||||||
qDebug("setting randomized true color for %d nodes\n", _nodeCount);
|
qDebug("setting randomized true color for %d nodes", _nodeCount);
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
@ -1483,7 +1483,7 @@ bool VoxelSystem::falseColorizeRandomOperation(OctreeElement* element, void* ext
|
||||||
void VoxelSystem::falseColorizeRandom() {
|
void VoxelSystem::falseColorizeRandom() {
|
||||||
_nodeCount = 0;
|
_nodeCount = 0;
|
||||||
_tree->recurseTreeWithOperation(falseColorizeRandomOperation);
|
_tree->recurseTreeWithOperation(falseColorizeRandomOperation);
|
||||||
qDebug("setting randomized false color for %d nodes\n", _nodeCount);
|
qDebug("setting randomized false color for %d nodes", _nodeCount);
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
@ -1499,7 +1499,7 @@ void VoxelSystem::trueColorize() {
|
||||||
PerformanceWarning warn(true, "trueColorize()",true);
|
PerformanceWarning warn(true, "trueColorize()",true);
|
||||||
_nodeCount = 0;
|
_nodeCount = 0;
|
||||||
_tree->recurseTreeWithOperation(trueColorizeOperation);
|
_tree->recurseTreeWithOperation(trueColorizeOperation);
|
||||||
qDebug("setting true color for %d nodes\n", _nodeCount);
|
qDebug("setting true color for %d nodes", _nodeCount);
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
@ -1521,7 +1521,7 @@ bool VoxelSystem::falseColorizeInViewOperation(OctreeElement* element, void* ext
|
||||||
void VoxelSystem::falseColorizeInView() {
|
void VoxelSystem::falseColorizeInView() {
|
||||||
_nodeCount = 0;
|
_nodeCount = 0;
|
||||||
_tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)_viewFrustum);
|
_tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)_viewFrustum);
|
||||||
qDebug("setting in view false color for %d nodes\n", _nodeCount);
|
qDebug("setting in view false color for %d nodes", _nodeCount);
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
@ -1604,13 +1604,13 @@ void VoxelSystem::falseColorizeBySource() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// create a bunch of colors we'll use during colorization
|
// create a bunch of colors we'll use during colorization
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||||
uint16_t nodeID = VoxelTreeElement::getSourceNodeUUIDKey(node->getUUID());
|
uint16_t nodeID = VoxelTreeElement::getSourceNodeUUIDKey(node->getUUID());
|
||||||
int groupColor = voxelServerCount % NUMBER_OF_COLOR_GROUPS;
|
int groupColor = voxelServerCount % NUMBER_OF_COLOR_GROUPS;
|
||||||
args.colors[nodeID] = groupColors[groupColor];
|
args.colors[nodeID] = groupColors[groupColor];
|
||||||
|
|
||||||
if (groupColors[groupColor].red > 0) {
|
if (groupColors[groupColor].red > 0) {
|
||||||
groupColors[groupColor].red = ((groupColors[groupColor].red - MIN_COLOR)/2) + MIN_COLOR;
|
groupColors[groupColor].red = ((groupColors[groupColor].red - MIN_COLOR)/2) + MIN_COLOR;
|
||||||
}
|
}
|
||||||
|
@ -1620,13 +1620,13 @@ void VoxelSystem::falseColorizeBySource() {
|
||||||
if (groupColors[groupColor].blue > 0) {
|
if (groupColors[groupColor].blue > 0) {
|
||||||
groupColors[groupColor].blue = ((groupColors[groupColor].blue - MIN_COLOR)/2) + MIN_COLOR;
|
groupColors[groupColor].blue = ((groupColors[groupColor].blue - MIN_COLOR)/2) + MIN_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
voxelServerCount++;
|
voxelServerCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_tree->recurseTreeWithOperation(falseColorizeBySourceOperation, &args);
|
_tree->recurseTreeWithOperation(falseColorizeBySourceOperation, &args);
|
||||||
qDebug("setting false color by source for %d nodes\n", _nodeCount);
|
qDebug("setting false color by source for %d nodes", _nodeCount);
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
@ -1679,10 +1679,10 @@ void VoxelSystem::falseColorizeDistanceFromView() {
|
||||||
_maxDistance = 0.0;
|
_maxDistance = 0.0;
|
||||||
_minDistance = FLT_MAX;
|
_minDistance = FLT_MAX;
|
||||||
_tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation, (void*) _viewFrustum);
|
_tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation, (void*) _viewFrustum);
|
||||||
qDebug("determining distance range for %d nodes\n", _nodeCount);
|
qDebug("determining distance range for %d nodes", _nodeCount);
|
||||||
_nodeCount = 0;
|
_nodeCount = 0;
|
||||||
_tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation, (void*) _viewFrustum);
|
_tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation, (void*) _viewFrustum);
|
||||||
qDebug("setting in distance false color for %d nodes\n", _nodeCount);
|
qDebug("setting in distance false color for %d nodes", _nodeCount);
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
@ -1813,7 +1813,7 @@ void VoxelSystem::removeOutOfView() {
|
||||||
}
|
}
|
||||||
bool showRemoveDebugDetails = false;
|
bool showRemoveDebugDetails = false;
|
||||||
if (showRemoveDebugDetails) {
|
if (showRemoveDebugDetails) {
|
||||||
qDebug("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d \n",
|
qDebug("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d",
|
||||||
args.nodesScanned, args.nodesRemoved, args.nodesInside,
|
args.nodesScanned, args.nodesRemoved, args.nodesInside,
|
||||||
args.nodesIntersect, args.nodesOutside, _removedVoxels.count()
|
args.nodesIntersect, args.nodesOutside, _removedVoxels.count()
|
||||||
);
|
);
|
||||||
|
@ -1842,7 +1842,7 @@ void VoxelSystem::showAllLocalVoxels() {
|
||||||
|
|
||||||
bool showRemoveDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showRemoveDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
if (showRemoveDebugDetails) {
|
if (showRemoveDebugDetails) {
|
||||||
qDebug("showAllLocalVoxels() scanned=%ld \n",args.nodesScanned );
|
qDebug("showAllLocalVoxels() scanned=%ld",args.nodesScanned );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1979,15 +1979,15 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) {
|
||||||
|
|
||||||
bool extraDebugDetails = false; // Application::getInstance()->getLogger()->extraDebugging();
|
bool extraDebugDetails = false; // Application::getInstance()->getLogger()->extraDebugging();
|
||||||
if (extraDebugDetails) {
|
if (extraDebugDetails) {
|
||||||
qDebug("hideOutOfView() scanned=%ld removed=%ld show=%ld inside=%ld intersect=%ld outside=%ld\n",
|
qDebug("hideOutOfView() scanned=%ld removed=%ld show=%ld inside=%ld intersect=%ld outside=%ld",
|
||||||
args.nodesScanned, args.nodesRemoved, args.nodesShown, args.nodesInside,
|
args.nodesScanned, args.nodesRemoved, args.nodesShown, args.nodesInside,
|
||||||
args.nodesIntersect, args.nodesOutside
|
args.nodesIntersect, args.nodesOutside
|
||||||
);
|
);
|
||||||
qDebug(" inside/inside=%ld intersect/inside=%ld outside/outside=%ld\n",
|
qDebug("inside/inside=%ld intersect/inside=%ld outside/outside=%ld",
|
||||||
args.nodesInsideInside, args.nodesIntersectInside, args.nodesOutsideOutside
|
args.nodesInsideInside, args.nodesIntersectInside, args.nodesOutsideOutside
|
||||||
);
|
);
|
||||||
|
|
||||||
qDebug() << "args.thisViewFrustum....\n";
|
qDebug() << "args.thisViewFrustum....";
|
||||||
args.thisViewFrustum.printDebugDetails();
|
args.thisViewFrustum.printDebugDetails();
|
||||||
}
|
}
|
||||||
_inhideOutOfView = false;
|
_inhideOutOfView = false;
|
||||||
|
@ -2224,7 +2224,7 @@ bool VoxelSystem::falseColorizeRandomEveryOtherOperation(OctreeElement* element,
|
||||||
void VoxelSystem::falseColorizeRandomEveryOther() {
|
void VoxelSystem::falseColorizeRandomEveryOther() {
|
||||||
falseColorizeRandomEveryOtherArgs args;
|
falseColorizeRandomEveryOtherArgs args;
|
||||||
_tree->recurseTreeWithOperation(falseColorizeRandomEveryOtherOperation,&args);
|
_tree->recurseTreeWithOperation(falseColorizeRandomEveryOtherOperation,&args);
|
||||||
qDebug("randomized false color for every other node: total %ld, colorable %ld, colored %ld\n",
|
qDebug("randomized false color for every other node: total %ld, colorable %ld, colored %ld",
|
||||||
args.totalNodes, args.colorableNodes, args.coloredNodes);
|
args.totalNodes, args.colorableNodes, args.coloredNodes);
|
||||||
_tree->setDirtyBit();
|
_tree->setDirtyBit();
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
|
@ -2294,14 +2294,14 @@ bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, v
|
||||||
|
|
||||||
const bool extraDebugging = false; // enable for extra debugging
|
const bool extraDebugging = false; // enable for extra debugging
|
||||||
if (extraDebugging) {
|
if (extraDebugging) {
|
||||||
qDebug("node In VBO... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s \n",
|
qDebug("node In VBO... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s",
|
||||||
voxel->getCorner().x, voxel->getCorner().y, voxel->getCorner().z, voxel->getScale(),
|
voxel->getCorner().x, voxel->getCorner().y, voxel->getCorner().z, voxel->getScale(),
|
||||||
nodeIndex, debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));
|
nodeIndex, debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args->hasIndexFound[nodeIndex]) {
|
if (args->hasIndexFound[nodeIndex]) {
|
||||||
args->duplicateVBOIndex++;
|
args->duplicateVBOIndex++;
|
||||||
qDebug("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s \n", nodeIndex,
|
qDebug("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s", nodeIndex,
|
||||||
debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));
|
debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));
|
||||||
} else {
|
} else {
|
||||||
args->hasIndexFound[nodeIndex] = true;
|
args->hasIndexFound[nodeIndex] = true;
|
||||||
|
@ -2335,17 +2335,17 @@ void VoxelSystem::collectStatsForTreesAndVBOs() {
|
||||||
collectStatsForTreesAndVBOsArgs args(_maxVoxels);
|
collectStatsForTreesAndVBOsArgs args(_maxVoxels);
|
||||||
args.expectedMax = _voxelsInWriteArrays;
|
args.expectedMax = _voxelsInWriteArrays;
|
||||||
|
|
||||||
qDebug("CALCULATING Local Voxel Tree Statistics >>>>>>>>>>>>\n");
|
qDebug("CALCULATING Local Voxel Tree Statistics >>>>>>>>>>>>");
|
||||||
|
|
||||||
_tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args);
|
_tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args);
|
||||||
|
|
||||||
qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld \n",
|
qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld",
|
||||||
args.totalNodes, args.leafNodes, args.dirtyNodes, args.coloredNodes, args.shouldRenderNodes);
|
args.totalNodes, args.leafNodes, args.dirtyNodes, args.coloredNodes, args.shouldRenderNodes);
|
||||||
|
|
||||||
qDebug(" _voxelsDirty=%s \n _voxelsInWriteArrays=%ld \n minDirty=%ld \n maxDirty=%ld \n", debug::valueOf(_voxelsDirty),
|
qDebug(" _voxelsDirty=%s \n _voxelsInWriteArrays=%ld \n minDirty=%ld \n maxDirty=%ld", debug::valueOf(_voxelsDirty),
|
||||||
_voxelsInWriteArrays, minDirty, maxDirty);
|
_voxelsInWriteArrays, minDirty, maxDirty);
|
||||||
|
|
||||||
qDebug(" inVBO %ld \n nodesInVBOOverExpectedMax %ld \n duplicateVBOIndex %ld \n nodesInVBONotShouldRender %ld \n",
|
qDebug(" inVBO %ld \n nodesInVBOOverExpectedMax %ld \n duplicateVBOIndex %ld \n nodesInVBONotShouldRender %ld",
|
||||||
args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex, args.nodesInVBONotShouldRender);
|
args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex, args.nodesInVBONotShouldRender);
|
||||||
|
|
||||||
glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;
|
glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;
|
||||||
|
@ -2358,13 +2358,13 @@ void VoxelSystem::collectStatsForTreesAndVBOs() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld \n",
|
qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld",
|
||||||
minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays);
|
minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays);
|
||||||
|
|
||||||
qDebug(" _freeIndexes.size()=%ld \n",
|
qDebug(" _freeIndexes.size()=%ld",
|
||||||
_freeIndexes.size());
|
_freeIndexes.size());
|
||||||
|
|
||||||
qDebug("DONE WITH Local Voxel Tree Statistics >>>>>>>>>>>>\n");
|
qDebug("DONE WITH Local Voxel Tree Statistics >>>>>>>>>>>>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2550,7 +2550,7 @@ void VoxelSystem::falseColorizeOccluded() {
|
||||||
|
|
||||||
_tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedOperation, position, (void*)&args);
|
_tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedOperation, position, (void*)&args);
|
||||||
|
|
||||||
qDebug("falseColorizeOccluded()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n",
|
qDebug("falseColorizeOccluded()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld",
|
||||||
position.x, position.y,
|
position.x, position.y,
|
||||||
args.totalVoxels, args.coloredVoxels, args.occludedVoxels,
|
args.totalVoxels, args.coloredVoxels, args.occludedVoxels,
|
||||||
args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped,
|
args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped,
|
||||||
|
@ -2683,9 +2683,9 @@ void VoxelSystem::falseColorizeOccludedV2() {
|
||||||
setupNewVoxelsForDrawing();
|
setupNewVoxelsForDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::nodeAdded(Node* node) {
|
void VoxelSystem::nodeAdded(SharedNodePointer node) {
|
||||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||||
qDebug("VoxelSystem... voxel server %s added...\n", node->getUUID().toString().toLocal8Bit().constData());
|
qDebug("VoxelSystem... voxel server %s added...", node->getUUID().toString().toLocal8Bit().constData());
|
||||||
_voxelServerCount++;
|
_voxelServerCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2704,11 +2704,11 @@ bool VoxelSystem::killSourceVoxelsOperation(OctreeElement* element, void* extraD
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::nodeKilled(Node* node) {
|
void VoxelSystem::nodeKilled(SharedNodePointer node) {
|
||||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||||
_voxelServerCount--;
|
_voxelServerCount--;
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
qDebug("VoxelSystem... voxel server %s removed...\n", nodeUUID.toString().toLocal8Bit().constData());
|
qDebug("VoxelSystem... voxel server %s removed...", nodeUUID.toString().toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2777,7 +2777,7 @@ void VoxelSystem::unlockTree() {
|
||||||
|
|
||||||
|
|
||||||
void VoxelSystem::localVoxelCacheLoaded() {
|
void VoxelSystem::localVoxelCacheLoaded() {
|
||||||
qDebug() << "localVoxelCacheLoaded()\n";
|
qDebug() << "localVoxelCacheLoaded()";
|
||||||
|
|
||||||
// Make sure that the application has properly set up the view frustum for our loaded state
|
// Make sure that the application has properly set up the view frustum for our loaded state
|
||||||
Application::getInstance()->initAvatarAndViewFrustum();
|
Application::getInstance()->initAvatarAndViewFrustum();
|
||||||
|
@ -2790,11 +2790,11 @@ void VoxelSystem::localVoxelCacheLoaded() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::beginLoadingLocalVoxelCache() {
|
void VoxelSystem::beginLoadingLocalVoxelCache() {
|
||||||
qDebug() << "beginLoadingLocalVoxelCache()\n";
|
qDebug() << "beginLoadingLocalVoxelCache()";
|
||||||
_writeRenderFullVBO = true; // this will disable individual node updates
|
_writeRenderFullVBO = true; // this will disable individual node updates
|
||||||
_inhideOutOfView = true; // this will disable hidOutOfView which we want to do until local cache is loaded
|
_inhideOutOfView = true; // this will disable hidOutOfView which we want to do until local cache is loaded
|
||||||
killLocalVoxels();
|
killLocalVoxels();
|
||||||
qDebug() << "DONE beginLoadingLocalVoxelCache()\n";
|
qDebug() << "DONE beginLoadingLocalVoxelCache()";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,7 @@ struct VoxelShaderVBOData
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class VoxelSystem : public NodeData, public OctreeElementDeleteHook, public OctreeElementUpdateHook,
|
class VoxelSystem : public NodeData, public OctreeElementDeleteHook, public OctreeElementUpdateHook {
|
||||||
public NodeListHook {
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
friend class VoxelHideShowThread;
|
friend class VoxelHideShowThread;
|
||||||
|
@ -112,8 +111,6 @@ public:
|
||||||
|
|
||||||
virtual void elementDeleted(OctreeElement* element);
|
virtual void elementDeleted(OctreeElement* element);
|
||||||
virtual void elementUpdated(OctreeElement* element);
|
virtual void elementUpdated(OctreeElement* element);
|
||||||
virtual void nodeAdded(Node* node);
|
|
||||||
virtual void nodeKilled(Node* node);
|
|
||||||
|
|
||||||
bool treeIsBusy() const { return _treeIsBusy; }
|
bool treeIsBusy() const { return _treeIsBusy; }
|
||||||
|
|
||||||
|
@ -124,6 +121,9 @@ signals:
|
||||||
void importProgress(int progress);
|
void importProgress(int progress);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void nodeAdded(SharedNodePointer node);
|
||||||
|
void nodeKilled(SharedNodePointer node);
|
||||||
|
|
||||||
void collectStatsForTreesAndVBOs();
|
void collectStatsForTreesAndVBOs();
|
||||||
|
|
||||||
// Methods that recurse tree
|
// Methods that recurse tree
|
||||||
|
|
29
interface/src/avatar/Avatar.cpp
Executable file → Normal file
29
interface/src/avatar/Avatar.cpp
Executable file → Normal file
|
@ -95,7 +95,6 @@ Avatar::Avatar(Node* owningNode) :
|
||||||
_mouseRayOrigin(0.0f, 0.0f, 0.0f),
|
_mouseRayOrigin(0.0f, 0.0f, 0.0f),
|
||||||
_mouseRayDirection(0.0f, 0.0f, 0.0f),
|
_mouseRayDirection(0.0f, 0.0f, 0.0f),
|
||||||
_isCollisionsOn(true),
|
_isCollisionsOn(true),
|
||||||
_leadingAvatar(NULL),
|
|
||||||
_moving(false),
|
_moving(false),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||||
|
@ -146,27 +145,7 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
|
||||||
return computeRotationFromBodyToWorldUp() * getOrientation();
|
return computeRotationFromBodyToWorldUp() * getOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::follow(Avatar* leadingAvatar) {
|
|
||||||
const float MAX_STRING_LENGTH = 2;
|
|
||||||
|
|
||||||
_leadingAvatar = leadingAvatar;
|
|
||||||
if (_leadingAvatar != NULL) {
|
|
||||||
_leaderUUID = leadingAvatar->getOwningNode()->getUUID();
|
|
||||||
_stringLength = glm::length(_position - _leadingAvatar->getPosition()) / _scale;
|
|
||||||
if (_stringLength > MAX_STRING_LENGTH) {
|
|
||||||
_stringLength = MAX_STRING_LENGTH;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_leaderUUID = QUuid();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
|
|
||||||
if (_leadingAvatar && !_leadingAvatar->getOwningNode()->isAlive()) {
|
|
||||||
follow(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_scale != _targetScale) {
|
if (_scale != _targetScale) {
|
||||||
setScale(_targetScale);
|
setScale(_targetScale);
|
||||||
}
|
}
|
||||||
|
@ -434,27 +413,27 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::goHome() {
|
void Avatar::goHome() {
|
||||||
qDebug("Going Home!\n");
|
qDebug("Going Home!");
|
||||||
setPosition(START_LOCATION);
|
setPosition(START_LOCATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::increaseSize() {
|
void Avatar::increaseSize() {
|
||||||
if ((1.f + SCALING_RATIO) * _targetScale < MAX_AVATAR_SCALE) {
|
if ((1.f + SCALING_RATIO) * _targetScale < MAX_AVATAR_SCALE) {
|
||||||
_targetScale *= (1.f + SCALING_RATIO);
|
_targetScale *= (1.f + SCALING_RATIO);
|
||||||
qDebug("Changed scale to %f\n", _targetScale);
|
qDebug("Changed scale to %f", _targetScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::decreaseSize() {
|
void Avatar::decreaseSize() {
|
||||||
if (MIN_AVATAR_SCALE < (1.f - SCALING_RATIO) * _targetScale) {
|
if (MIN_AVATAR_SCALE < (1.f - SCALING_RATIO) * _targetScale) {
|
||||||
_targetScale *= (1.f - SCALING_RATIO);
|
_targetScale *= (1.f - SCALING_RATIO);
|
||||||
qDebug("Changed scale to %f\n", _targetScale);
|
qDebug("Changed scale to %f", _targetScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::resetSize() {
|
void Avatar::resetSize() {
|
||||||
_targetScale = 1.0f;
|
_targetScale = 1.0f;
|
||||||
qDebug("Reseted scale to %f\n", _targetScale);
|
qDebug("Reseted scale to %f", _targetScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setScale(const float scale) {
|
void Avatar::setScale(const float scale) {
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "Skeleton.h"
|
#include "Skeleton.h"
|
||||||
#include "SkeletonModel.h"
|
#include "SkeletonModel.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "devices/SerialInterface.h"
|
|
||||||
#include "devices/Transmitter.h"
|
#include "devices/Transmitter.h"
|
||||||
|
|
||||||
static const float SCALING_RATIO = .05f;
|
static const float SCALING_RATIO = .05f;
|
||||||
|
@ -135,7 +134,6 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void simulate(float deltaTime, Transmitter* transmitter);
|
void simulate(float deltaTime, Transmitter* transmitter);
|
||||||
void follow(Avatar* leadingAvatar);
|
|
||||||
void render(bool forceRenderHead);
|
void render(bool forceRenderHead);
|
||||||
|
|
||||||
//setters
|
//setters
|
||||||
|
@ -217,7 +215,6 @@ protected:
|
||||||
glm::vec3 _mouseRayOrigin;
|
glm::vec3 _mouseRayOrigin;
|
||||||
glm::vec3 _mouseRayDirection;
|
glm::vec3 _mouseRayDirection;
|
||||||
bool _isCollisionsOn;
|
bool _isCollisionsOn;
|
||||||
Avatar* _leadingAvatar;
|
|
||||||
float _stringLength;
|
float _stringLength;
|
||||||
|
|
||||||
bool _moving; ///< set when position is changing
|
bool _moving; ///< set when position is changing
|
||||||
|
|
|
@ -60,7 +60,7 @@ bool FaceModel::render(float alpha) {
|
||||||
void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
||||||
// get the rotation axes in joint space and use them to adjust the rotation
|
// get the rotation axes in joint space and use them to adjust the rotation
|
||||||
glm::mat3 axes = glm::mat3_cast(_rotation);
|
glm::mat3 axes = glm::mat3_cast(_rotation);
|
||||||
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform *
|
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
|
||||||
joint.preTransform * glm::mat4_cast(joint.preRotation)));
|
joint.preTransform * glm::mat4_cast(joint.preRotation)));
|
||||||
state.rotation = glm::angleAxis(-_owningHead->getRoll(), glm::normalize(inverse * axes[2])) *
|
state.rotation = glm::angleAxis(-_owningHead->getRoll(), glm::normalize(inverse * axes[2])) *
|
||||||
glm::angleAxis(_owningHead->getYaw(), glm::normalize(inverse * axes[1])) *
|
glm::angleAxis(_owningHead->getYaw(), glm::normalize(inverse * axes[1])) *
|
||||||
|
|
|
@ -368,8 +368,7 @@ void Hand::updateCollisions() {
|
||||||
glm::vec3 totalPenetration;
|
glm::vec3 totalPenetration;
|
||||||
|
|
||||||
// check other avatars
|
// check other avatars
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||||
Avatar* otherAvatar = (Avatar*)node->getLinkedData();
|
Avatar* otherAvatar = (Avatar*)node->getLinkedData();
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
|
||||||
|
@ -388,21 +387,21 @@ void Hand::updateCollisions() {
|
||||||
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
|
||||||
palm.setIsCollidingWithPalm(true);
|
palm.setIsCollidingWithPalm(true);
|
||||||
if (!wasColliding) {
|
if (!wasColliding) {
|
||||||
const float PALM_COLLIDE_VOLUME = 1.f;
|
const float PALM_COLLIDE_VOLUME = 1.f;
|
||||||
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
const float PALM_COLLIDE_FREQUENCY = 1000.f;
|
||||||
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
|
||||||
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
|
||||||
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
|
||||||
PALM_COLLIDE_FREQUENCY,
|
PALM_COLLIDE_FREQUENCY,
|
||||||
PALM_COLLIDE_DURATION_MAX,
|
PALM_COLLIDE_DURATION_MAX,
|
||||||
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
PALM_COLLIDE_DECAY_PER_SAMPLE);
|
||||||
// If the other person's palm is in motion, move mine downward to show I was hit
|
// If the other person's palm is in motion, move mine downward to show I was hit
|
||||||
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
|
||||||
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
|
||||||
// add slapback here
|
// add slapback here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "BuckyBalls.h"
|
#include "BuckyBalls.h"
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "devices/SerialInterface.h"
|
|
||||||
#include "VoxelSystem.h"
|
#include "VoxelSystem.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
#include "VideoFace.h"
|
#include "VideoFace.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "devices/SerialInterface.h"
|
|
||||||
#include "renderer/TextureCache.h"
|
#include "renderer/TextureCache.h"
|
||||||
|
|
||||||
enum eyeContactTargets {
|
enum eyeContactTargets {
|
||||||
|
|
|
@ -87,15 +87,6 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
_elapsedTimeMoving += deltaTime;
|
_elapsedTimeMoving += deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_leadingAvatar && !_leadingAvatar->getOwningNode()->isAlive()) {
|
|
||||||
follow(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ajust, scale, position and lookAt position when following an other avatar
|
|
||||||
if (_leadingAvatar && _targetScale != _leadingAvatar->getScale()) {
|
|
||||||
_targetScale = _leadingAvatar->getScale();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_scale != _targetScale) {
|
if (_scale != _targetScale) {
|
||||||
float scale = (1.f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale;
|
float scale = (1.f - SMOOTHING_RATIO) * _scale + SMOOTHING_RATIO * _targetScale;
|
||||||
setScale(scale);
|
setScale(scale);
|
||||||
|
@ -299,7 +290,6 @@ const float MAX_PITCH = 90.0f;
|
||||||
// Update avatar head rotation with sensor data
|
// Update avatar head rotation with sensor data
|
||||||
void MyAvatar::updateFromGyrosAndOrWebcam(bool turnWithHead) {
|
void MyAvatar::updateFromGyrosAndOrWebcam(bool turnWithHead) {
|
||||||
Faceshift* faceshift = Application::getInstance()->getFaceshift();
|
Faceshift* faceshift = Application::getInstance()->getFaceshift();
|
||||||
SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor();
|
|
||||||
Webcam* webcam = Application::getInstance()->getWebcam();
|
Webcam* webcam = Application::getInstance()->getWebcam();
|
||||||
glm::vec3 estimatedPosition, estimatedRotation;
|
glm::vec3 estimatedPosition, estimatedRotation;
|
||||||
|
|
||||||
|
@ -320,16 +310,11 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool turnWithHead) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (gyros->isActive()) {
|
|
||||||
estimatedRotation = gyros->getEstimatedRotation();
|
|
||||||
|
|
||||||
} else if (webcam->isActive()) {
|
} else if (webcam->isActive()) {
|
||||||
estimatedRotation = webcam->getEstimatedRotation();
|
estimatedRotation = webcam->getEstimatedRotation();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!_leadingAvatar) {
|
_head.setPitch(_head.getMousePitch());
|
||||||
_head.setPitch(_head.getMousePitch());
|
|
||||||
}
|
|
||||||
_head.getVideoFace().clearFrame();
|
_head.getVideoFace().clearFrame();
|
||||||
|
|
||||||
// restore rotation, lean to neutral positions
|
// restore rotation, lean to neutral positions
|
||||||
|
@ -634,47 +619,6 @@ void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
|
||||||
_shouldJump = false;
|
_shouldJump = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add thrusts from leading avatar
|
|
||||||
const float FOLLOWING_RATE = 0.02f;
|
|
||||||
const float MIN_YAW = 5.0f;
|
|
||||||
const float MIN_PITCH = 1.0f;
|
|
||||||
const float PITCH_RATE = 0.1f;
|
|
||||||
const float MIN_YAW_BEFORE_PITCH = 30.0f;
|
|
||||||
|
|
||||||
if (_leadingAvatar != NULL) {
|
|
||||||
glm::vec3 toTarget = _leadingAvatar->getPosition() - _position;
|
|
||||||
|
|
||||||
if (glm::length(_position - _leadingAvatar->getPosition()) > _scale * _stringLength) {
|
|
||||||
_position += toTarget * FOLLOWING_RATE;
|
|
||||||
} else {
|
|
||||||
toTarget = _leadingAvatar->getHead().getLookAtPosition() - _head.getPosition();
|
|
||||||
}
|
|
||||||
toTarget = glm::vec3(glm::dot(right, toTarget),
|
|
||||||
glm::dot(up , toTarget),
|
|
||||||
glm::dot(front, toTarget));
|
|
||||||
|
|
||||||
float yawAngle = angleBetween(-IDENTITY_FRONT, glm::vec3(toTarget.x, 0.f, toTarget.z));
|
|
||||||
if (glm::abs(yawAngle) > MIN_YAW){
|
|
||||||
if (IDENTITY_RIGHT.x * toTarget.x + IDENTITY_RIGHT.y * toTarget.y + IDENTITY_RIGHT.z * toTarget.z > 0) {
|
|
||||||
_bodyYawDelta -= yawAngle;
|
|
||||||
} else {
|
|
||||||
_bodyYawDelta += yawAngle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float pitchAngle = glm::abs(90.0f - angleBetween(IDENTITY_UP, toTarget));
|
|
||||||
if (glm::abs(pitchAngle) > MIN_PITCH && yawAngle < MIN_YAW_BEFORE_PITCH){
|
|
||||||
if (IDENTITY_UP.x * toTarget.x + IDENTITY_UP.y * toTarget.y + IDENTITY_UP.z * toTarget.z > 0) {
|
|
||||||
_head.setMousePitch(_head.getMousePitch() + PITCH_RATE * pitchAngle);
|
|
||||||
} else {
|
|
||||||
_head.setMousePitch(_head.getMousePitch() - PITCH_RATE * pitchAngle);
|
|
||||||
}
|
|
||||||
_head.setPitch(_head.getMousePitch());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Add thrusts from Transmitter
|
// Add thrusts from Transmitter
|
||||||
if (transmitter) {
|
if (transmitter) {
|
||||||
transmitter->checkForLostTransmitter();
|
transmitter->checkForLostTransmitter();
|
||||||
|
@ -873,15 +817,7 @@ void MyAvatar::updateAvatarCollisions(float deltaTime) {
|
||||||
// Reset detector for nearest avatar
|
// Reset detector for nearest avatar
|
||||||
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
// loop through all the other avatars for potential interactions...
|
// loop through all the other avatars for potential interactions
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
|
||||||
//Avatar *otherAvatar = (Avatar *)node->getLinkedData();
|
|
||||||
//
|
|
||||||
// Placeholder: Add code here when we want to add Avatar<->Avatar collision stuff
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SortedAvatar {
|
class SortedAvatar {
|
||||||
|
@ -902,10 +838,10 @@ void MyAvatar::updateChatCircle(float deltaTime) {
|
||||||
|
|
||||||
// find all circle-enabled members and sort by distance
|
// find all circle-enabled members and sort by distance
|
||||||
QVector<SortedAvatar> sortedAvatars;
|
QVector<SortedAvatar> sortedAvatars;
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||||
SortedAvatar sortedAvatar;
|
SortedAvatar sortedAvatar;
|
||||||
sortedAvatar.avatar = (Avatar*)node->getLinkedData();
|
sortedAvatar.avatar = (Avatar*)node->getLinkedData();
|
||||||
if (!sortedAvatar.avatar->isChatCirclingEnabled()) {
|
if (!sortedAvatar.avatar->isChatCirclingEnabled()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -914,6 +850,7 @@ void MyAvatar::updateChatCircle(float deltaTime) {
|
||||||
sortedAvatars.append(sortedAvatar);
|
sortedAvatars.append(sortedAvatar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qSort(sortedAvatars.begin(), sortedAvatars.end());
|
qSort(sortedAvatars.begin(), sortedAvatars.end());
|
||||||
|
|
||||||
// compute the accumulated centers
|
// compute the accumulated centers
|
||||||
|
|
|
@ -51,7 +51,6 @@ public:
|
||||||
float getAbsoluteHeadYaw() const;
|
float getAbsoluteHeadYaw() const;
|
||||||
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
|
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
|
||||||
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
|
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
|
||||||
Avatar* getLeadingAvatar() const { return _leadingAvatar; }
|
|
||||||
glm::vec3 getGravity() const { return _gravity; }
|
glm::vec3 getGravity() const { return _gravity; }
|
||||||
glm::vec3 getUprightHeadPosition() const;
|
glm::vec3 getUprightHeadPosition() const;
|
||||||
glm::vec3 getEyeLevelPosition() const;
|
glm::vec3 getEyeLevelPosition() const;
|
||||||
|
|
|
@ -154,7 +154,6 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector<int>& fingerJoin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
setJointPosition(jointIndex, palm.getPosition());
|
|
||||||
float sign = (jointIndex == geometry.rightHandJointIndex) ? 1.0f : -1.0f;
|
float sign = (jointIndex == geometry.rightHandJointIndex) ? 1.0f : -1.0f;
|
||||||
glm::quat palmRotation;
|
glm::quat palmRotation;
|
||||||
getJointRotation(jointIndex, palmRotation, true);
|
getJointRotation(jointIndex, palmRotation, true);
|
||||||
|
@ -186,6 +185,7 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector<int>& fingerJoin
|
||||||
|
|
||||||
// no point in continuing if there are no fingers
|
// no point in continuing if there are no fingers
|
||||||
if (palm.getNumFingers() == 0 || fingerJointIndices.isEmpty()) {
|
if (palm.getNumFingers() == 0 || fingerJointIndices.isEmpty()) {
|
||||||
|
stretchArm(jointIndex, palm.getPosition());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +203,8 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector<int>& fingerJoin
|
||||||
|
|
||||||
setJointRotation(fingerJointIndex, rotationBetween(palmRotation * jointVector, fingerVector) * palmRotation, true);
|
setJointRotation(fingerJointIndex, rotationBetween(palmRotation * jointVector, fingerVector) * palmRotation, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stretchArm(jointIndex, palm.getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonModel::updateJointState(int index) {
|
void SkeletonModel::updateJointState(int index) {
|
||||||
|
@ -219,9 +221,47 @@ void SkeletonModel::updateJointState(int index) {
|
||||||
void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
||||||
// get the rotation axes in joint space and use them to adjust the rotation
|
// get the rotation axes in joint space and use them to adjust the rotation
|
||||||
glm::mat3 axes = glm::mat3_cast(_rotation);
|
glm::mat3 axes = glm::mat3_cast(_rotation);
|
||||||
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform *
|
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
|
||||||
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)));
|
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)));
|
||||||
state.rotation = glm::angleAxis(-_owningAvatar->getHead().getLeanSideways(), glm::normalize(inverse * axes[2])) *
|
state.rotation = glm::angleAxis(-_owningAvatar->getHead().getLeanSideways(), glm::normalize(inverse * axes[2])) *
|
||||||
glm::angleAxis(-_owningAvatar->getHead().getLeanForward(), glm::normalize(inverse * axes[0])) * joint.rotation;
|
glm::angleAxis(-_owningAvatar->getHead().getLeanForward(), glm::normalize(inverse * axes[0])) * joint.rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonModel::stretchArm(int jointIndex, const glm::vec3& position) {
|
||||||
|
// find out where the hand is pointing
|
||||||
|
glm::quat handRotation;
|
||||||
|
getJointRotation(jointIndex, handRotation, true);
|
||||||
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
|
glm::vec3 forwardVector(jointIndex == geometry.rightHandJointIndex ? -1.0f : 1.0f, 0.0f, 0.0f);
|
||||||
|
glm::vec3 handVector = handRotation * forwardVector;
|
||||||
|
|
||||||
|
// align elbow with hand
|
||||||
|
const FBXJoint& joint = geometry.joints.at(jointIndex);
|
||||||
|
if (joint.parentIndex == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glm::quat elbowRotation;
|
||||||
|
getJointRotation(joint.parentIndex, elbowRotation, true);
|
||||||
|
applyRotationDelta(joint.parentIndex, rotationBetween(elbowRotation * forwardVector, handVector), false);
|
||||||
|
|
||||||
|
// set position according to normal length
|
||||||
|
float scale = extractUniformScale(_scale);
|
||||||
|
glm::vec3 handPosition = position - _translation;
|
||||||
|
glm::vec3 elbowPosition = handPosition - handVector * joint.distanceToParent * scale;
|
||||||
|
|
||||||
|
// set shoulder orientation to point to elbow
|
||||||
|
const FBXJoint& parentJoint = geometry.joints.at(joint.parentIndex);
|
||||||
|
if (parentJoint.parentIndex == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glm::quat shoulderRotation;
|
||||||
|
getJointRotation(parentJoint.parentIndex, shoulderRotation, true);
|
||||||
|
applyRotationDelta(parentJoint.parentIndex, rotationBetween(shoulderRotation * forwardVector,
|
||||||
|
elbowPosition - extractTranslation(_jointStates.at(parentJoint.parentIndex).transform)), false);
|
||||||
|
|
||||||
|
// update the shoulder state
|
||||||
|
updateJointState(parentJoint.parentIndex);
|
||||||
|
|
||||||
|
// adjust the elbow's local translation
|
||||||
|
setJointTranslation(joint.parentIndex, elbowPosition);
|
||||||
|
}
|
||||||
|
|
|
@ -40,6 +40,10 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/// Using the current position and rotation of the identified (hand) joint, computes a
|
||||||
|
/// reasonable stretched configuration for the connected arm.
|
||||||
|
void stretchArm(int jointIndex, const glm::vec3& position);
|
||||||
|
|
||||||
Avatar* _owningAvatar;
|
Avatar* _owningAvatar;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ void Faceshift::setTCPEnabled(bool enabled) {
|
||||||
void Faceshift::connectSocket() {
|
void Faceshift::connectSocket() {
|
||||||
if (_tcpEnabled) {
|
if (_tcpEnabled) {
|
||||||
if (!_tcpRetryCount) {
|
if (!_tcpRetryCount) {
|
||||||
qDebug("Faceshift: Connecting...\n");
|
qDebug("Faceshift: Connecting...");
|
||||||
}
|
}
|
||||||
|
|
||||||
_tcpSocket.connectToHost("localhost", FACESHIFT_PORT);
|
_tcpSocket.connectToHost("localhost", FACESHIFT_PORT);
|
||||||
|
@ -125,7 +125,7 @@ void Faceshift::connectSocket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Faceshift::noteConnected() {
|
void Faceshift::noteConnected() {
|
||||||
qDebug("Faceshift: Connected.\n");
|
qDebug("Faceshift: Connected.");
|
||||||
|
|
||||||
// request the list of blendshape names
|
// request the list of blendshape names
|
||||||
string message;
|
string message;
|
||||||
|
@ -136,7 +136,7 @@ void Faceshift::noteConnected() {
|
||||||
void Faceshift::noteError(QAbstractSocket::SocketError error) {
|
void Faceshift::noteError(QAbstractSocket::SocketError error) {
|
||||||
if (!_tcpRetryCount) {
|
if (!_tcpRetryCount) {
|
||||||
// Only spam log with fail to connect the first time, so that we can keep waiting for server
|
// Only spam log with fail to connect the first time, so that we can keep waiting for server
|
||||||
qDebug() << "Faceshift: " << _tcpSocket.errorString() << "\n";
|
qDebug() << "Faceshift: " << _tcpSocket.errorString();
|
||||||
}
|
}
|
||||||
// retry connection after a 2 second delay
|
// retry connection after a 2 second delay
|
||||||
if (_tcpEnabled) {
|
if (_tcpEnabled) {
|
||||||
|
|
|
@ -1,422 +0,0 @@
|
||||||
//
|
|
||||||
// SerialInterface.cpp
|
|
||||||
// 2012 by Philip Rosedale for High Fidelity Inc.
|
|
||||||
//
|
|
||||||
// Read interface data from the gyros/accelerometer Invensense board using the SerialUSB
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <regex.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <string>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include <glm/gtx/vector_angle.hpp>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <inv_tty.h>
|
|
||||||
#include <inv_mpu.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <SharedUtil.h>
|
|
||||||
|
|
||||||
#include "Application.h"
|
|
||||||
#include "SerialInterface.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "Webcam.h"
|
|
||||||
|
|
||||||
const short NO_READ_MAXIMUM_MSECS = 3000;
|
|
||||||
const int GRAVITY_SAMPLES = 60; // Use the first few samples to baseline values
|
|
||||||
const int NORTH_SAMPLES = 30;
|
|
||||||
const int ACCELERATION_SENSOR_FUSION_SAMPLES = 20;
|
|
||||||
const int COMPASS_SENSOR_FUSION_SAMPLES = 100;
|
|
||||||
const int LONG_TERM_RATE_SAMPLES = 1000;
|
|
||||||
|
|
||||||
const bool USING_INVENSENSE_MPU9150 = 1;
|
|
||||||
|
|
||||||
SerialInterface::SerialInterface() :
|
|
||||||
_active(false),
|
|
||||||
_gravity(0, 0, 0),
|
|
||||||
_averageRotationRates(0, 0, 0),
|
|
||||||
_averageAcceleration(0, 0, 0),
|
|
||||||
_estimatedRotation(0, 0, 0),
|
|
||||||
_estimatedPosition(0, 0, 0),
|
|
||||||
_estimatedVelocity(0, 0, 0),
|
|
||||||
_lastAcceleration(0, 0, 0),
|
|
||||||
_lastRotationRates(0, 0, 0),
|
|
||||||
_compassMinima(-211, -132, -186),
|
|
||||||
_compassMaxima(89, 95, 98),
|
|
||||||
_angularVelocityToLinearAccel(0.003f, -0.001f, -0.006f,
|
|
||||||
-0.005f, -0.001f, -0.006f,
|
|
||||||
0.010f, 0.004f, 0.007f),
|
|
||||||
_angularAccelToLinearAccel(0.0f, 0.0f, 0.002f,
|
|
||||||
0.0f, 0.0f, 0.001f,
|
|
||||||
-0.002f, -0.002f, 0.0f)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerialInterface::pair() {
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
// look for a matching gyro setup
|
|
||||||
DIR *devDir;
|
|
||||||
struct dirent *entry;
|
|
||||||
int matchStatus;
|
|
||||||
regex_t regex;
|
|
||||||
|
|
||||||
// for now this only works on OS X, where the usb serial shows up as /dev/tty.usb*,
|
|
||||||
// and (possibly just Ubuntu) Linux, where it shows up as /dev/ttyACM*
|
|
||||||
if((devDir = opendir("/dev"))) {
|
|
||||||
while((entry = readdir(devDir))) {
|
|
||||||
#ifdef __APPLE__
|
|
||||||
regcomp(®ex, "tty\\.usb", REG_EXTENDED|REG_NOSUB);
|
|
||||||
#else
|
|
||||||
regcomp(®ex, "ttyACM", REG_EXTENDED|REG_NOSUB);
|
|
||||||
#endif
|
|
||||||
matchStatus = regexec(®ex, entry->d_name, (size_t) 0, NULL, 0);
|
|
||||||
if (matchStatus == 0) {
|
|
||||||
char *serialPortname = new char[100];
|
|
||||||
sprintf(serialPortname, "/dev/%s", entry->d_name);
|
|
||||||
|
|
||||||
initializePort(serialPortname);
|
|
||||||
|
|
||||||
delete [] serialPortname;
|
|
||||||
}
|
|
||||||
regfree(®ex);
|
|
||||||
}
|
|
||||||
closedir(devDir);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to the serial port
|
|
||||||
void SerialInterface::initializePort(char* portname) {
|
|
||||||
#ifndef _WIN32
|
|
||||||
_serialDescriptor = open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
|
|
||||||
|
|
||||||
qDebug("Opening SerialUSB %s: ", portname);
|
|
||||||
|
|
||||||
if (_serialDescriptor == -1) {
|
|
||||||
qDebug("Failed.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct termios options;
|
|
||||||
tcgetattr(_serialDescriptor, &options);
|
|
||||||
|
|
||||||
options.c_cflag |= (CLOCAL | CREAD | CS8);
|
|
||||||
options.c_cflag &= ~PARENB;
|
|
||||||
options.c_cflag &= ~CSTOPB;
|
|
||||||
options.c_cflag &= ~CSIZE;
|
|
||||||
tcsetattr(_serialDescriptor, TCSANOW, &options);
|
|
||||||
|
|
||||||
cfsetispeed(&options,B115200);
|
|
||||||
cfsetospeed(&options,B115200);
|
|
||||||
|
|
||||||
if (USING_INVENSENSE_MPU9150) {
|
|
||||||
// block on invensense reads until there is data to read
|
|
||||||
int currentFlags = fcntl(_serialDescriptor, F_GETFL);
|
|
||||||
fcntl(_serialDescriptor, F_SETFL, currentFlags & ~O_NONBLOCK);
|
|
||||||
|
|
||||||
// make sure there's nothing queued up to be read
|
|
||||||
tcflush(_serialDescriptor, TCIOFLUSH);
|
|
||||||
|
|
||||||
// this disables streaming so there's no garbage data on reads
|
|
||||||
if (write(_serialDescriptor, "SD\n", 3) != 3) {
|
|
||||||
qDebug("Failed.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
char result[4];
|
|
||||||
if (read(_serialDescriptor, result, 4) != 4) {
|
|
||||||
qDebug("Failed.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tty_set_file_descriptor(_serialDescriptor);
|
|
||||||
mpu_init(0);
|
|
||||||
mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL | INV_XYZ_COMPASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug("Connected.\n");
|
|
||||||
resetSerial();
|
|
||||||
|
|
||||||
_active = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the serial interface channel values onscreen as vertical lines
|
|
||||||
void SerialInterface::renderLevels(int width, int height) {
|
|
||||||
char val[40];
|
|
||||||
if (USING_INVENSENSE_MPU9150) {
|
|
||||||
// For invensense gyros, render as horizontal bars
|
|
||||||
const int LEVEL_CORNER_X = 10;
|
|
||||||
const int LEVEL_CORNER_Y = 200;
|
|
||||||
|
|
||||||
// Draw the numeric degree/sec values from the gyros
|
|
||||||
sprintf(val, "Yaw %4.1f", _estimatedRotation.y);
|
|
||||||
drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y, 0.10, 0, 1.0, 1, val, 0, 1, 0);
|
|
||||||
sprintf(val, "Pitch %4.1f", _estimatedRotation.x);
|
|
||||||
drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 15, 0.10, 0, 1.0, 1, val, 0, 1, 0);
|
|
||||||
sprintf(val, "Roll %4.1f", _estimatedRotation.z);
|
|
||||||
drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 30, 0.10, 0, 1.0, 1, val, 0, 1, 0);
|
|
||||||
sprintf(val, "X %4.3f", _lastAcceleration.x - _gravity.x);
|
|
||||||
drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 45, 0.10, 0, 1.0, 1, val, 0, 1, 0);
|
|
||||||
sprintf(val, "Y %4.3f", _lastAcceleration.y - _gravity.y);
|
|
||||||
drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 60, 0.10, 0, 1.0, 1, val, 0, 1, 0);
|
|
||||||
sprintf(val, "Z %4.3f", _lastAcceleration.z - _gravity.z);
|
|
||||||
drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 75, 0.10, 0, 1.0, 1, val, 0, 1, 0);
|
|
||||||
|
|
||||||
// Draw the levels as horizontal lines
|
|
||||||
const int LEVEL_CENTER = 150;
|
|
||||||
const float ACCEL_VIEW_SCALING = 10.f;
|
|
||||||
const float POSITION_SCALING = 400.f;
|
|
||||||
|
|
||||||
glLineWidth(2.0);
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
// Rotation rates
|
|
||||||
glColor4f(1, 1, 1, 1);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y - 3);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastYawRate(), LEVEL_CORNER_Y - 3);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 12);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastPitchRate(), LEVEL_CORNER_Y + 12);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 27);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + getLastRollRate(), LEVEL_CORNER_Y + 27);
|
|
||||||
// Estimated Rotation
|
|
||||||
glColor4f(0, 1, 1, 1);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y - 1);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.y, LEVEL_CORNER_Y - 1);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 14);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.x, LEVEL_CORNER_Y + 14);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 29);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _estimatedRotation.z, LEVEL_CORNER_Y + 29);
|
|
||||||
|
|
||||||
// Acceleration rates
|
|
||||||
glColor4f(1, 1, 1, 1);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 42);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_estimatedAcceleration.x * ACCEL_VIEW_SCALING), LEVEL_CORNER_Y + 42);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 57);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_estimatedAcceleration.y * ACCEL_VIEW_SCALING), LEVEL_CORNER_Y + 57);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 72);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_estimatedAcceleration.z * ACCEL_VIEW_SCALING), LEVEL_CORNER_Y + 72);
|
|
||||||
|
|
||||||
// Estimated Position
|
|
||||||
glColor4f(0, 1, 1, 1);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 44);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_estimatedPosition.x * POSITION_SCALING), LEVEL_CORNER_Y + 44);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 59);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_estimatedPosition.y * POSITION_SCALING), LEVEL_CORNER_Y + 59);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 74);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_estimatedPosition.z * POSITION_SCALING), LEVEL_CORNER_Y + 74);
|
|
||||||
|
|
||||||
|
|
||||||
glEnd();
|
|
||||||
// Draw green vertical centerline
|
|
||||||
glColor4f(0, 1, 0, 0.5);
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y - 6);
|
|
||||||
glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 30);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerialInterface::readData(float deltaTime) {
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
int initialSamples = totalSamples;
|
|
||||||
|
|
||||||
if (USING_INVENSENSE_MPU9150) {
|
|
||||||
|
|
||||||
// ask the invensense for raw gyro data
|
|
||||||
short accelData[3];
|
|
||||||
if (mpu_get_accel_reg(accelData, 0)) {
|
|
||||||
close(_serialDescriptor);
|
|
||||||
qDebug("Disconnected SerialUSB.\n");
|
|
||||||
_active = false;
|
|
||||||
return; // disconnected
|
|
||||||
}
|
|
||||||
|
|
||||||
const float LSB_TO_METERS_PER_SECOND2 = 1.f / 16384.f * GRAVITY_EARTH;
|
|
||||||
// From MPU-9150 register map, with setting on
|
|
||||||
// highest resolution = +/- 2G
|
|
||||||
|
|
||||||
_lastAcceleration = glm::vec3(-accelData[2], -accelData[1], -accelData[0]) * LSB_TO_METERS_PER_SECOND2;
|
|
||||||
|
|
||||||
short gyroData[3];
|
|
||||||
mpu_get_gyro_reg(gyroData, 0);
|
|
||||||
|
|
||||||
// Convert the integer rates to floats
|
|
||||||
const float LSB_TO_DEGREES_PER_SECOND = 1.f / 16.4f; // From MPU-9150 register map, 2000 deg/sec.
|
|
||||||
glm::vec3 rotationRates;
|
|
||||||
rotationRates[0] = ((float) -gyroData[2]) * LSB_TO_DEGREES_PER_SECOND;
|
|
||||||
rotationRates[1] = ((float) -gyroData[1]) * LSB_TO_DEGREES_PER_SECOND;
|
|
||||||
rotationRates[2] = ((float) -gyroData[0]) * LSB_TO_DEGREES_PER_SECOND;
|
|
||||||
|
|
||||||
short compassData[3];
|
|
||||||
mpu_get_compass_reg(compassData, 0);
|
|
||||||
|
|
||||||
// Convert integer values to floats, update extents
|
|
||||||
_lastCompass = glm::vec3(compassData[2], -compassData[0], -compassData[1]);
|
|
||||||
|
|
||||||
// update and subtract the long term average
|
|
||||||
_averageRotationRates = (1.f - 1.f/(float)LONG_TERM_RATE_SAMPLES) * _averageRotationRates +
|
|
||||||
1.f/(float)LONG_TERM_RATE_SAMPLES * rotationRates;
|
|
||||||
rotationRates -= _averageRotationRates;
|
|
||||||
|
|
||||||
// compute the angular acceleration
|
|
||||||
glm::vec3 angularAcceleration = (deltaTime < EPSILON) ? glm::vec3() : (rotationRates - _lastRotationRates) / deltaTime;
|
|
||||||
_lastRotationRates = rotationRates;
|
|
||||||
|
|
||||||
// Update raw rotation estimates
|
|
||||||
glm::quat estimatedRotation = glm::quat(glm::radians(_estimatedRotation)) *
|
|
||||||
glm::quat(glm::radians(deltaTime * _lastRotationRates));
|
|
||||||
|
|
||||||
// Update acceleration estimate: first, subtract gravity as rotated into current frame
|
|
||||||
_estimatedAcceleration = (totalSamples < GRAVITY_SAMPLES) ? glm::vec3() :
|
|
||||||
_lastAcceleration - glm::inverse(estimatedRotation) * _gravity;
|
|
||||||
|
|
||||||
// update and subtract the long term average
|
|
||||||
_averageAcceleration = (1.f - 1.f/(float)LONG_TERM_RATE_SAMPLES) * _averageAcceleration +
|
|
||||||
1.f/(float)LONG_TERM_RATE_SAMPLES * _estimatedAcceleration;
|
|
||||||
_estimatedAcceleration -= _averageAcceleration;
|
|
||||||
|
|
||||||
// Consider updating our angular velocity/acceleration to linear acceleration mapping
|
|
||||||
if (glm::length(_estimatedAcceleration) > EPSILON &&
|
|
||||||
(glm::length(_lastRotationRates) > EPSILON || glm::length(angularAcceleration) > EPSILON)) {
|
|
||||||
// compute predicted linear acceleration, find error between actual and predicted
|
|
||||||
glm::vec3 predictedAcceleration = _angularVelocityToLinearAccel * _lastRotationRates +
|
|
||||||
_angularAccelToLinearAccel * angularAcceleration;
|
|
||||||
glm::vec3 error = _estimatedAcceleration - predictedAcceleration;
|
|
||||||
|
|
||||||
// the "error" is actually what we want: the linear acceleration minus rotational influences
|
|
||||||
_estimatedAcceleration = error;
|
|
||||||
|
|
||||||
// adjust according to error in each dimension, in proportion to input magnitudes
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (fabsf(error[i]) < EPSILON) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const float LEARNING_RATE = 0.001f;
|
|
||||||
float rateSum = fabsf(_lastRotationRates.x) + fabsf(_lastRotationRates.y) + fabsf(_lastRotationRates.z);
|
|
||||||
if (rateSum > EPSILON) {
|
|
||||||
for (int j = 0; j < 3; j++) {
|
|
||||||
float proportion = LEARNING_RATE * fabsf(_lastRotationRates[j]) / rateSum;
|
|
||||||
if (proportion > EPSILON) {
|
|
||||||
_angularVelocityToLinearAccel[j][i] += error[i] * proportion / _lastRotationRates[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float accelSum = fabsf(angularAcceleration.x) + fabsf(angularAcceleration.y) + fabsf(angularAcceleration.z);
|
|
||||||
if (accelSum > EPSILON) {
|
|
||||||
for (int j = 0; j < 3; j++) {
|
|
||||||
float proportion = LEARNING_RATE * fabsf(angularAcceleration[j]) / accelSum;
|
|
||||||
if (proportion > EPSILON) {
|
|
||||||
_angularAccelToLinearAccel[j][i] += error[i] * proportion / angularAcceleration[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rotate estimated acceleration into global rotation frame
|
|
||||||
_estimatedAcceleration = estimatedRotation * _estimatedAcceleration;
|
|
||||||
|
|
||||||
// Update estimated position and velocity
|
|
||||||
float const DECAY_VELOCITY = 0.975f;
|
|
||||||
float const DECAY_POSITION = 0.975f;
|
|
||||||
_estimatedVelocity += deltaTime * _estimatedAcceleration;
|
|
||||||
_estimatedPosition += deltaTime * _estimatedVelocity;
|
|
||||||
_estimatedVelocity *= DECAY_VELOCITY;
|
|
||||||
|
|
||||||
// Attempt to fuse gyro position with webcam position
|
|
||||||
Webcam* webcam = Application::getInstance()->getWebcam();
|
|
||||||
if (webcam->isActive()) {
|
|
||||||
const float WEBCAM_POSITION_FUSION = 0.5f;
|
|
||||||
_estimatedPosition = glm::mix(_estimatedPosition, webcam->getEstimatedPosition(), WEBCAM_POSITION_FUSION);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_estimatedPosition *= DECAY_POSITION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accumulate a set of initial baseline readings for setting gravity
|
|
||||||
if (totalSamples == 0) {
|
|
||||||
_gravity = _lastAcceleration;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (totalSamples < GRAVITY_SAMPLES) {
|
|
||||||
_gravity = glm::mix(_gravity, _lastAcceleration, 1.0f / GRAVITY_SAMPLES);
|
|
||||||
|
|
||||||
// North samples start later, because the initial compass readings are screwy
|
|
||||||
int northSample = totalSamples - (GRAVITY_SAMPLES - NORTH_SAMPLES);
|
|
||||||
if (northSample == 0) {
|
|
||||||
_north = _lastCompass;
|
|
||||||
|
|
||||||
} else if (northSample > 0) {
|
|
||||||
_north = glm::mix(_north, _lastCompass, 1.0f / NORTH_SAMPLES);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Use gravity reading to do sensor fusion on the pitch and roll estimation
|
|
||||||
estimatedRotation = safeMix(estimatedRotation,
|
|
||||||
rotationBetween(estimatedRotation * _lastAcceleration, _gravity) * estimatedRotation,
|
|
||||||
1.0f / ACCELERATION_SENSOR_FUSION_SAMPLES);
|
|
||||||
|
|
||||||
// Update the compass extents
|
|
||||||
_compassMinima = glm::min(_compassMinima, _lastCompass);
|
|
||||||
_compassMaxima = glm::max(_compassMaxima, _lastCompass);
|
|
||||||
|
|
||||||
// Same deal with the compass heading
|
|
||||||
estimatedRotation = safeMix(estimatedRotation,
|
|
||||||
rotationBetween(estimatedRotation * recenterCompass(_lastCompass),
|
|
||||||
recenterCompass(_north)) * estimatedRotation,
|
|
||||||
1.0f / COMPASS_SENSOR_FUSION_SAMPLES);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_estimatedRotation = safeEulerAngles(estimatedRotation);
|
|
||||||
|
|
||||||
totalSamples++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (initialSamples == totalSamples) {
|
|
||||||
timeval now;
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
|
|
||||||
if (diffclock(&lastGoodRead, &now) > NO_READ_MAXIMUM_MSECS) {
|
|
||||||
qDebug("No data - Shutting down SerialInterface.\n");
|
|
||||||
resetSerial();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
gettimeofday(&lastGoodRead, NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerialInterface::resetAverages() {
|
|
||||||
totalSamples = 0;
|
|
||||||
_gravity = glm::vec3(0, 0, 0);
|
|
||||||
_averageRotationRates = glm::vec3(0, 0, 0);
|
|
||||||
_averageAcceleration = glm::vec3(0, 0, 0);
|
|
||||||
_lastRotationRates = glm::vec3(0, 0, 0);
|
|
||||||
_estimatedRotation = glm::vec3(0, 0, 0);
|
|
||||||
_estimatedPosition = glm::vec3(0, 0, 0);
|
|
||||||
_estimatedVelocity = glm::vec3(0, 0, 0);
|
|
||||||
_estimatedAcceleration = glm::vec3(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerialInterface::resetSerial() {
|
|
||||||
#ifndef _WIN32
|
|
||||||
resetAverages();
|
|
||||||
_active = false;
|
|
||||||
gettimeofday(&lastGoodRead, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 SerialInterface::recenterCompass(const glm::vec3& compass) {
|
|
||||||
// compensate for "hard iron" distortion by subtracting the midpoint on each axis; see
|
|
||||||
// http://www.sensorsmag.com/sensors/motion-velocity-displacement/compensating-tilt-hard-iron-and-soft-iron-effects-6475
|
|
||||||
return (compass - (_compassMinima + _compassMaxima) * 0.5f) / (_compassMaxima - _compassMinima);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
//
|
|
||||||
// SerialInterface.h
|
|
||||||
// hifi
|
|
||||||
//
|
|
||||||
// Created by Stephen Birarda on 2/15/13.
|
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __interface__SerialInterface__
|
|
||||||
#define __interface__SerialInterface__
|
|
||||||
|
|
||||||
// These includes are for serial port reading/writing
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
#include "InterfaceConfig.h"
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
extern const bool USING_INVENSENSE_MPU9150;
|
|
||||||
|
|
||||||
class SerialInterface {
|
|
||||||
public:
|
|
||||||
SerialInterface();
|
|
||||||
|
|
||||||
void pair();
|
|
||||||
void readData(float deltaTime);
|
|
||||||
const float getLastPitchRate() const { return _lastRotationRates[0]; }
|
|
||||||
const float getLastYawRate() const { return _lastRotationRates[1]; }
|
|
||||||
const float getLastRollRate() const { return _lastRotationRates[2]; }
|
|
||||||
const glm::vec3& getLastRotationRates() const { return _lastRotationRates; };
|
|
||||||
const glm::vec3& getEstimatedRotation() const { return _estimatedRotation; };
|
|
||||||
const glm::vec3& getEstimatedPosition() const { return _estimatedPosition; };
|
|
||||||
const glm::vec3& getEstimatedVelocity() const { return _estimatedVelocity; };
|
|
||||||
const glm::vec3& getEstimatedAcceleration() const { return _estimatedAcceleration; };
|
|
||||||
const glm::vec3& getLastAcceleration() const { return _lastAcceleration; };
|
|
||||||
const glm::vec3& getGravity() const { return _gravity; };
|
|
||||||
|
|
||||||
void renderLevels(int width, int height);
|
|
||||||
void resetAverages();
|
|
||||||
bool isActive() const { return _active; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initializePort(char* portname);
|
|
||||||
void resetSerial();
|
|
||||||
|
|
||||||
glm::vec3 recenterCompass(const glm::vec3& compass);
|
|
||||||
|
|
||||||
bool _active;
|
|
||||||
int _serialDescriptor;
|
|
||||||
int totalSamples;
|
|
||||||
timeval lastGoodRead;
|
|
||||||
glm::vec3 _gravity;
|
|
||||||
glm::vec3 _north;
|
|
||||||
glm::vec3 _averageRotationRates;
|
|
||||||
glm::vec3 _averageAcceleration;
|
|
||||||
glm::vec3 _estimatedRotation;
|
|
||||||
glm::vec3 _estimatedPosition;
|
|
||||||
glm::vec3 _estimatedVelocity;
|
|
||||||
glm::vec3 _estimatedAcceleration;
|
|
||||||
glm::vec3 _lastAcceleration;
|
|
||||||
glm::vec3 _lastRotationRates;
|
|
||||||
glm::vec3 _lastCompass;
|
|
||||||
glm::vec3 _compassMinima;
|
|
||||||
glm::vec3 _compassMaxima;
|
|
||||||
|
|
||||||
glm::mat3 _angularVelocityToLinearAccel;
|
|
||||||
glm::mat3 _angularAccelToLinearAccel;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -30,10 +30,10 @@ SixenseManager::~SixenseManager() {
|
||||||
void SixenseManager::setFilter(bool filter) {
|
void SixenseManager::setFilter(bool filter) {
|
||||||
#ifdef HAVE_SIXENSE
|
#ifdef HAVE_SIXENSE
|
||||||
if (filter) {
|
if (filter) {
|
||||||
qDebug("Sixense Filter ON\n");
|
qDebug("Sixense Filter ON");
|
||||||
sixenseSetFilterEnabled(1);
|
sixenseSetFilterEnabled(1);
|
||||||
} else {
|
} else {
|
||||||
qDebug("Sixense Filter OFF\n");
|
qDebug("Sixense Filter OFF");
|
||||||
sixenseSetFilterEnabled(0);
|
sixenseSetFilterEnabled(0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,7 +44,7 @@ void Transmitter::checkForLostTransmitter() {
|
||||||
int msecsSinceLast = diffclock(_lastReceivedPacket, &now);
|
int msecsSinceLast = diffclock(_lastReceivedPacket, &now);
|
||||||
if (msecsSinceLast > TIME_TO_ASSUME_LOST_MSECS) {
|
if (msecsSinceLast > TIME_TO_ASSUME_LOST_MSECS) {
|
||||||
resetLevels();
|
resetLevels();
|
||||||
qDebug("Transmitter signal lost.\n");
|
qDebug("Transmitter signal lost.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,12 +99,12 @@ void Transmitter::processIncomingData(unsigned char* packetData, int numBytes) {
|
||||||
_estimatedRotation.y *= (1.f - DECAY_RATE * DELTA_TIME);
|
_estimatedRotation.y *= (1.f - DECAY_RATE * DELTA_TIME);
|
||||||
|
|
||||||
if (!_isConnected) {
|
if (!_isConnected) {
|
||||||
qDebug("Transmitter Connected.\n");
|
qDebug("Transmitter Connected.");
|
||||||
_isConnected = true;
|
_isConnected = true;
|
||||||
_estimatedRotation *= 0.0;
|
_estimatedRotation *= 0.0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug("Transmitter packet read error, %d bytes.\n", numBytes);
|
qDebug("Transmitter packet read error, %d bytes.", numBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -473,26 +473,26 @@ static glm::quat xnToGLM(const XnMatrix3X3& matrix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XN_CALLBACK_TYPE newUser(UserGenerator& generator, XnUserID id, void* cookie) {
|
static void XN_CALLBACK_TYPE newUser(UserGenerator& generator, XnUserID id, void* cookie) {
|
||||||
qDebug("Found user %d.\n", id);
|
qDebug("Found user %d.", id);
|
||||||
generator.GetSkeletonCap().RequestCalibration(id, false);
|
generator.GetSkeletonCap().RequestCalibration(id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XN_CALLBACK_TYPE lostUser(UserGenerator& generator, XnUserID id, void* cookie) {
|
static void XN_CALLBACK_TYPE lostUser(UserGenerator& generator, XnUserID id, void* cookie) {
|
||||||
qDebug("Lost user %d.\n", id);
|
qDebug("Lost user %d.", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XN_CALLBACK_TYPE calibrationStarted(SkeletonCapability& capability, XnUserID id, void* cookie) {
|
static void XN_CALLBACK_TYPE calibrationStarted(SkeletonCapability& capability, XnUserID id, void* cookie) {
|
||||||
qDebug("Calibration started for user %d.\n", id);
|
qDebug("Calibration started for user %d.", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XN_CALLBACK_TYPE calibrationCompleted(SkeletonCapability& capability,
|
static void XN_CALLBACK_TYPE calibrationCompleted(SkeletonCapability& capability,
|
||||||
XnUserID id, XnCalibrationStatus status, void* cookie) {
|
XnUserID id, XnCalibrationStatus status, void* cookie) {
|
||||||
if (status == XN_CALIBRATION_STATUS_OK) {
|
if (status == XN_CALIBRATION_STATUS_OK) {
|
||||||
qDebug("Calibration completed for user %d.\n", id);
|
qDebug("Calibration completed for user %d.", id);
|
||||||
capability.StartTracking(id);
|
capability.StartTracking(id);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
qDebug("Calibration failed to user %d.\n", id);
|
qDebug("Calibration failed to user %d.", id);
|
||||||
capability.RequestCalibration(id, true);
|
capability.RequestCalibration(id, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,7 +604,7 @@ void FrameGrabber::grabFrame() {
|
||||||
// make sure it's in the format we expect
|
// make sure it's in the format we expect
|
||||||
if (image->nChannels != 3 || image->depth != IPL_DEPTH_8U || image->dataOrder != IPL_DATA_ORDER_PIXEL ||
|
if (image->nChannels != 3 || image->depth != IPL_DEPTH_8U || image->dataOrder != IPL_DATA_ORDER_PIXEL ||
|
||||||
image->origin != 0) {
|
image->origin != 0) {
|
||||||
qDebug("Invalid webcam image format.\n");
|
qDebug("Invalid webcam image format.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
color = image;
|
color = image;
|
||||||
|
@ -938,7 +938,7 @@ bool FrameGrabber::init() {
|
||||||
// load our face cascade
|
// load our face cascade
|
||||||
switchToResourcesParentIfRequired();
|
switchToResourcesParentIfRequired();
|
||||||
if (_faceCascade.empty() && !_faceCascade.load("resources/haarcascades/haarcascade_frontalface_alt.xml")) {
|
if (_faceCascade.empty() && !_faceCascade.load("resources/haarcascades/haarcascade_frontalface_alt.xml")) {
|
||||||
qDebug("Failed to load Haar cascade for face tracking.\n");
|
qDebug("Failed to load Haar cascade for face tracking.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -971,7 +971,7 @@ bool FrameGrabber::init() {
|
||||||
|
|
||||||
// next, an ordinary webcam
|
// next, an ordinary webcam
|
||||||
if ((_capture = cvCaptureFromCAM(-1)) == 0) {
|
if ((_capture = cvCaptureFromCAM(-1)) == 0) {
|
||||||
qDebug("Failed to open webcam.\n");
|
qDebug("Failed to open webcam.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const int IDEAL_FRAME_WIDTH = 320;
|
const int IDEAL_FRAME_WIDTH = 320;
|
||||||
|
|
|
@ -33,16 +33,16 @@ int main(int argc, const char * argv[]) {
|
||||||
if (clockSkewOption) {
|
if (clockSkewOption) {
|
||||||
int clockSkew = atoi(clockSkewOption);
|
int clockSkew = atoi(clockSkewOption);
|
||||||
usecTimestampNowForceClockSkew(clockSkew);
|
usecTimestampNowForceClockSkew(clockSkew);
|
||||||
qDebug("clockSkewOption=%s clockSkew=%d\n", clockSkewOption, clockSkew);
|
qDebug("clockSkewOption=%s clockSkew=%d", clockSkewOption, clockSkew);
|
||||||
}
|
}
|
||||||
|
|
||||||
int exitCode;
|
int exitCode;
|
||||||
{
|
{
|
||||||
Application app(argc, const_cast<char**>(argv), startup_time);
|
Application app(argc, const_cast<char**>(argv), startup_time);
|
||||||
|
|
||||||
qDebug( "Created QT Application.\n" );
|
qDebug( "Created QT Application.");
|
||||||
exitCode = app.exec();
|
exitCode = app.exec();
|
||||||
}
|
}
|
||||||
qDebug("Normal exit.\n");
|
qDebug("Normal exit.");
|
||||||
return exitCode;
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -484,6 +484,7 @@ public:
|
||||||
|
|
||||||
int parentIndex;
|
int parentIndex;
|
||||||
|
|
||||||
|
glm::vec3 translation;
|
||||||
glm::mat4 preTransform;
|
glm::mat4 preTransform;
|
||||||
glm::quat preRotation;
|
glm::quat preRotation;
|
||||||
glm::quat rotation;
|
glm::quat rotation;
|
||||||
|
@ -499,8 +500,8 @@ glm::mat4 getGlobalTransform(const QMultiHash<QString, QString>& parentMap,
|
||||||
glm::mat4 globalTransform;
|
glm::mat4 globalTransform;
|
||||||
while (!nodeID.isNull()) {
|
while (!nodeID.isNull()) {
|
||||||
const FBXModel& model = models.value(nodeID);
|
const FBXModel& model = models.value(nodeID);
|
||||||
globalTransform = model.preTransform * glm::mat4_cast(model.preRotation * model.rotation * model.postRotation) *
|
globalTransform = glm::translate(model.translation) * model.preTransform * glm::mat4_cast(model.preRotation *
|
||||||
model.postTransform * globalTransform;
|
model.rotation * model.postRotation) * model.postTransform * globalTransform;
|
||||||
|
|
||||||
QList<QString> parentIDs = parentMap.values(nodeID);
|
QList<QString> parentIDs = parentMap.values(nodeID);
|
||||||
nodeID = QString();
|
nodeID = QString();
|
||||||
|
@ -523,11 +524,13 @@ public:
|
||||||
|
|
||||||
void printNode(const FBXNode& node, int indent) {
|
void printNode(const FBXNode& node, int indent) {
|
||||||
QByteArray spaces(indent, ' ');
|
QByteArray spaces(indent, ' ');
|
||||||
qDebug("%s%s: ", spaces.data(), node.name.data());
|
QDebug nodeDebug = qDebug();
|
||||||
|
|
||||||
|
nodeDebug.nospace() << spaces.data() << node.name.data() << ": ";
|
||||||
foreach (const QVariant& property, node.properties) {
|
foreach (const QVariant& property, node.properties) {
|
||||||
qDebug() << property;
|
nodeDebug << property;
|
||||||
}
|
}
|
||||||
qDebug() << "\n";
|
|
||||||
foreach (const FBXNode& child, node.children) {
|
foreach (const FBXNode& child, node.children) {
|
||||||
printNode(child, indent + 1);
|
printNode(child, indent + 1);
|
||||||
}
|
}
|
||||||
|
@ -956,8 +959,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html
|
// see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html
|
||||||
model.preTransform = glm::translate(translation) * glm::translate(rotationOffset) *
|
model.translation = translation;
|
||||||
glm::translate(rotationPivot);
|
model.preTransform = glm::translate(rotationOffset) * glm::translate(rotationPivot);
|
||||||
model.preRotation = glm::quat(glm::radians(preRotation));
|
model.preRotation = glm::quat(glm::radians(preRotation));
|
||||||
model.rotation = glm::quat(glm::radians(rotation));
|
model.rotation = glm::quat(glm::radians(rotation));
|
||||||
model.postRotation = glm::quat(glm::radians(postRotation));
|
model.postRotation = glm::quat(glm::radians(postRotation));
|
||||||
|
@ -1142,6 +1145,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
}
|
}
|
||||||
joint.freeLineage.remove(lastFreeIndex + 1, joint.freeLineage.size() - lastFreeIndex - 1);
|
joint.freeLineage.remove(lastFreeIndex + 1, joint.freeLineage.size() - lastFreeIndex - 1);
|
||||||
|
|
||||||
|
joint.translation = model.translation;
|
||||||
joint.preTransform = model.preTransform;
|
joint.preTransform = model.preTransform;
|
||||||
joint.preRotation = model.preRotation;
|
joint.preRotation = model.preRotation;
|
||||||
joint.rotation = model.rotation;
|
joint.rotation = model.rotation;
|
||||||
|
@ -1151,13 +1155,14 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
joint.rotationMax = model.rotationMax;
|
joint.rotationMax = model.rotationMax;
|
||||||
glm::quat combinedRotation = model.preRotation * model.rotation * model.postRotation;
|
glm::quat combinedRotation = model.preRotation * model.rotation * model.postRotation;
|
||||||
if (joint.parentIndex == -1) {
|
if (joint.parentIndex == -1) {
|
||||||
joint.transform = geometry.offset * model.preTransform * glm::mat4_cast(combinedRotation) * model.postTransform;
|
joint.transform = geometry.offset * glm::translate(model.translation) * model.preTransform *
|
||||||
|
glm::mat4_cast(combinedRotation) * model.postTransform;
|
||||||
joint.inverseDefaultRotation = glm::inverse(combinedRotation);
|
joint.inverseDefaultRotation = glm::inverse(combinedRotation);
|
||||||
joint.distanceToParent = 0.0f;
|
joint.distanceToParent = 0.0f;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const FBXJoint& parentJoint = geometry.joints.at(joint.parentIndex);
|
const FBXJoint& parentJoint = geometry.joints.at(joint.parentIndex);
|
||||||
joint.transform = parentJoint.transform *
|
joint.transform = parentJoint.transform * glm::translate(model.translation) *
|
||||||
model.preTransform * glm::mat4_cast(combinedRotation) * model.postTransform;
|
model.preTransform * glm::mat4_cast(combinedRotation) * model.postTransform;
|
||||||
joint.inverseDefaultRotation = glm::inverse(combinedRotation) * parentJoint.inverseDefaultRotation;
|
joint.inverseDefaultRotation = glm::inverse(combinedRotation) * parentJoint.inverseDefaultRotation;
|
||||||
joint.distanceToParent = glm::distance(extractTranslation(parentJoint.transform),
|
joint.distanceToParent = glm::distance(extractTranslation(parentJoint.transform),
|
||||||
|
@ -1271,7 +1276,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
QString jointID = childMap.value(clusterID);
|
QString jointID = childMap.value(clusterID);
|
||||||
fbxCluster.jointIndex = modelIDs.indexOf(jointID);
|
fbxCluster.jointIndex = modelIDs.indexOf(jointID);
|
||||||
if (fbxCluster.jointIndex == -1) {
|
if (fbxCluster.jointIndex == -1) {
|
||||||
qDebug() << "Joint not in model list: " << jointID << "\n";
|
qDebug() << "Joint not in model list: " << jointID;
|
||||||
fbxCluster.jointIndex = 0;
|
fbxCluster.jointIndex = 0;
|
||||||
}
|
}
|
||||||
fbxCluster.inverseBindMatrix = glm::inverse(cluster.transformLink) * modelTransform;
|
fbxCluster.inverseBindMatrix = glm::inverse(cluster.transformLink) * modelTransform;
|
||||||
|
@ -1289,7 +1294,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
FBXCluster cluster;
|
FBXCluster cluster;
|
||||||
cluster.jointIndex = modelIDs.indexOf(modelID);
|
cluster.jointIndex = modelIDs.indexOf(modelID);
|
||||||
if (cluster.jointIndex == -1) {
|
if (cluster.jointIndex == -1) {
|
||||||
qDebug() << "Model not in model list: " << modelID << "\n";
|
qDebug() << "Model not in model list: " << modelID;
|
||||||
cluster.jointIndex = 0;
|
cluster.jointIndex = 0;
|
||||||
}
|
}
|
||||||
extracted.mesh.clusters.append(cluster);
|
extracted.mesh.clusters.append(cluster);
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
int parentIndex;
|
int parentIndex;
|
||||||
float distanceToParent;
|
float distanceToParent;
|
||||||
float boneRadius;
|
float boneRadius;
|
||||||
|
glm::vec3 translation;
|
||||||
glm::mat4 preTransform;
|
glm::mat4 preTransform;
|
||||||
glm::quat preRotation;
|
glm::quat preRotation;
|
||||||
glm::quat rotation;
|
glm::quat rotation;
|
||||||
|
|
|
@ -251,18 +251,16 @@ QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkGeometry::NetworkGeometry(const QUrl& url) :
|
NetworkGeometry::NetworkGeometry(const QUrl& url) :
|
||||||
|
_modelRequest(url),
|
||||||
_modelReply(NULL),
|
_modelReply(NULL),
|
||||||
_mappingReply(NULL)
|
_mappingReply(NULL),
|
||||||
|
_attempts(0)
|
||||||
{
|
{
|
||||||
if (!url.isValid()) {
|
if (!url.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QNetworkRequest modelRequest(url);
|
_modelRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
|
||||||
modelRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
|
makeModelRequest();
|
||||||
_modelReply = Application::getInstance()->getNetworkAccessManager()->get(modelRequest);
|
|
||||||
|
|
||||||
connect(_modelReply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(maybeReadModelWithMapping()));
|
|
||||||
connect(_modelReply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleModelReplyError()));
|
|
||||||
|
|
||||||
QUrl mappingURL = url;
|
QUrl mappingURL = url;
|
||||||
QString path = url.path();
|
QString path = url.path();
|
||||||
|
@ -312,12 +310,28 @@ glm::vec4 NetworkGeometry::computeAverageColor() const {
|
||||||
return (totalTriangles == 0) ? glm::vec4(1.0f, 1.0f, 1.0f, 1.0f) : totalColor / totalTriangles;
|
return (totalTriangles == 0) ? glm::vec4(1.0f, 1.0f, 1.0f, 1.0f) : totalColor / totalTriangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkGeometry::makeModelRequest() {
|
||||||
|
_modelReply = Application::getInstance()->getNetworkAccessManager()->get(_modelRequest);
|
||||||
|
|
||||||
|
connect(_modelReply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(maybeReadModelWithMapping()));
|
||||||
|
connect(_modelReply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleModelReplyError()));
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkGeometry::handleModelReplyError() {
|
void NetworkGeometry::handleModelReplyError() {
|
||||||
qDebug() << _modelReply->errorString() << "\n";
|
QDebug debug = qDebug() << _modelReply->errorString();
|
||||||
|
|
||||||
_modelReply->disconnect(this);
|
_modelReply->disconnect(this);
|
||||||
_modelReply->deleteLater();
|
_modelReply->deleteLater();
|
||||||
_modelReply = NULL;
|
_modelReply = NULL;
|
||||||
|
|
||||||
|
// retry with increasing delays
|
||||||
|
const int MAX_ATTEMPTS = 8;
|
||||||
|
const int BASE_DELAY_MS = 1000;
|
||||||
|
if (++_attempts < MAX_ATTEMPTS) {
|
||||||
|
QTimer::singleShot(BASE_DELAY_MS * (int)pow(2.0, _attempts), this, SLOT(makeModelRequest()));
|
||||||
|
debug << " -- retrying...";
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkGeometry::handleMappingReplyError() {
|
void NetworkGeometry::handleMappingReplyError() {
|
||||||
|
@ -351,7 +365,7 @@ void NetworkGeometry::maybeReadModelWithMapping() {
|
||||||
_geometry = url.path().toLower().endsWith(".svo") ? readSVO(model) : readFBX(model, mapping);
|
_geometry = url.path().toLower().endsWith(".svo") ? readSVO(model) : readFBX(model, mapping);
|
||||||
|
|
||||||
} catch (const QString& error) {
|
} catch (const QString& error) {
|
||||||
qDebug() << "Error reading " << url << ": " << error << "\n";
|
qDebug() << "Error reading " << url << ": " << error;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define __interface__GeometryCache__
|
#define __interface__GeometryCache__
|
||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QNetworkRequest>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QWeakPointer>
|
#include <QWeakPointer>
|
||||||
|
@ -67,15 +68,18 @@ public:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
void makeModelRequest();
|
||||||
void handleModelReplyError();
|
void handleModelReplyError();
|
||||||
void handleMappingReplyError();
|
void handleMappingReplyError();
|
||||||
void maybeReadModelWithMapping();
|
void maybeReadModelWithMapping();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
QNetworkRequest _modelRequest;
|
||||||
QNetworkReply* _modelReply;
|
QNetworkReply* _modelReply;
|
||||||
QNetworkReply* _mappingReply;
|
QNetworkReply* _mappingReply;
|
||||||
|
|
||||||
|
int _attempts;
|
||||||
FBXGeometry _geometry;
|
FBXGeometry _geometry;
|
||||||
QVector<NetworkMesh> _meshes;
|
QVector<NetworkMesh> _meshes;
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,7 +54,7 @@ static ProgramObject* createProgram(const QString& name) {
|
||||||
|
|
||||||
void GlowEffect::init() {
|
void GlowEffect::init() {
|
||||||
if (_initialized) {
|
if (_initialized) {
|
||||||
qDebug("[ERROR] GlowEffeect is already initialized.\n");
|
qDebug("[ERROR] GlowEffeect is already initialized.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,20 +284,20 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) {
|
||||||
void GlowEffect::cycleRenderMode() {
|
void GlowEffect::cycleRenderMode() {
|
||||||
switch(_renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT)) {
|
switch(_renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT)) {
|
||||||
case ADD_MODE:
|
case ADD_MODE:
|
||||||
qDebug() << "Glow mode: Add\n";
|
qDebug() << "Glow mode: Add";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLUR_ADD_MODE:
|
case BLUR_ADD_MODE:
|
||||||
qDebug() << "Glow mode: Blur/add\n";
|
qDebug() << "Glow mode: Blur/add";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLUR_PERSIST_ADD_MODE:
|
case BLUR_PERSIST_ADD_MODE:
|
||||||
qDebug() << "Glow mode: Blur/persist/add\n";
|
qDebug() << "Glow mode: Blur/persist/add";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case DIFFUSE_ADD_MODE:
|
case DIFFUSE_ADD_MODE:
|
||||||
qDebug() << "Glow mode: Diffuse/add\n";
|
qDebug() << "Glow mode: Diffuse/add";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_isFirstFrame = true;
|
_isFirstFrame = true;
|
||||||
|
|
|
@ -99,6 +99,7 @@ void Model::simulate(float deltaTime) {
|
||||||
if (_jointStates.isEmpty()) {
|
if (_jointStates.isEmpty()) {
|
||||||
foreach (const FBXJoint& joint, geometry.joints) {
|
foreach (const FBXJoint& joint, geometry.joints) {
|
||||||
JointState state;
|
JointState state;
|
||||||
|
state.translation = joint.translation;
|
||||||
state.rotation = joint.rotation;
|
state.rotation = joint.rotation;
|
||||||
_jointStates.append(state);
|
_jointStates.append(state);
|
||||||
}
|
}
|
||||||
|
@ -626,7 +627,7 @@ void Model::updateJointState(int index) {
|
||||||
glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset);
|
glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset);
|
||||||
|
|
||||||
glm::quat combinedRotation = joint.preRotation * state.rotation * joint.postRotation;
|
glm::quat combinedRotation = joint.preRotation * state.rotation * joint.postRotation;
|
||||||
state.transform = baseTransform * geometry.offset * joint.preTransform *
|
state.transform = baseTransform * geometry.offset * glm::translate(state.translation) * joint.preTransform *
|
||||||
glm::mat4_cast(combinedRotation) * joint.postTransform;
|
glm::mat4_cast(combinedRotation) * joint.postTransform;
|
||||||
state.combinedRotation = _rotation * combinedRotation;
|
state.combinedRotation = _rotation * combinedRotation;
|
||||||
|
|
||||||
|
@ -642,7 +643,7 @@ void Model::updateJointState(int index) {
|
||||||
maybeUpdateEyeRotation(parentState, joint, state);
|
maybeUpdateEyeRotation(parentState, joint, state);
|
||||||
}
|
}
|
||||||
glm::quat combinedRotation = joint.preRotation * state.rotation * joint.postRotation;
|
glm::quat combinedRotation = joint.preRotation * state.rotation * joint.postRotation;
|
||||||
state.transform = parentState.transform * joint.preTransform *
|
state.transform = parentState.transform * glm::translate(state.translation) * joint.preTransform *
|
||||||
glm::mat4_cast(combinedRotation) * joint.postTransform;
|
glm::mat4_cast(combinedRotation) * joint.postTransform;
|
||||||
state.combinedRotation = parentState.combinedRotation * combinedRotation;
|
state.combinedRotation = parentState.combinedRotation * combinedRotation;
|
||||||
}
|
}
|
||||||
|
@ -747,6 +748,23 @@ bool Model::setJointRotation(int jointIndex, const glm::quat& rotation, bool fro
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::setJointTranslation(int jointIndex, const glm::vec3& translation) {
|
||||||
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
|
const FBXJoint& joint = geometry.joints.at(jointIndex);
|
||||||
|
|
||||||
|
glm::mat4 parentTransform;
|
||||||
|
if (joint.parentIndex == -1) {
|
||||||
|
parentTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
parentTransform = _jointStates.at(joint.parentIndex).transform;
|
||||||
|
}
|
||||||
|
JointState& state = _jointStates[jointIndex];
|
||||||
|
glm::vec3 preTranslation = extractTranslation(joint.preTransform * glm::mat4_cast(joint.preRotation *
|
||||||
|
state.rotation * joint.postRotation) * joint.postTransform);
|
||||||
|
state.translation = glm::vec3(glm::inverse(parentTransform) * glm::vec4(translation, 1.0f)) - preTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
bool Model::restoreJointPosition(int jointIndex, float percent) {
|
bool Model::restoreJointPosition(int jointIndex, float percent) {
|
||||||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -824,25 +842,6 @@ void Model::renderCollisionProxies(float alpha) {
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setJointTranslation(int jointIndex, int parentIndex, int childIndex, const glm::vec3& translation) {
|
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
|
||||||
JointState& state = _jointStates[jointIndex];
|
|
||||||
if (childIndex != -1 && geometry.joints.at(jointIndex).isFree) {
|
|
||||||
// if there's a child, then I must adjust *my* rotation
|
|
||||||
glm::vec3 childTranslation = extractTranslation(_jointStates.at(childIndex).transform);
|
|
||||||
applyRotationDelta(jointIndex, rotationBetween(childTranslation - extractTranslation(state.transform),
|
|
||||||
childTranslation - translation));
|
|
||||||
}
|
|
||||||
if (parentIndex != -1 && geometry.joints.at(parentIndex).isFree) {
|
|
||||||
// if there's a parent, then I must adjust *its* rotation
|
|
||||||
JointState& parent = _jointStates[parentIndex];
|
|
||||||
glm::vec3 parentTranslation = extractTranslation(parent.transform);
|
|
||||||
applyRotationDelta(parentIndex, rotationBetween(extractTranslation(state.transform) - parentTranslation,
|
|
||||||
translation - parentTranslation));
|
|
||||||
}
|
|
||||||
::setTranslation(state.transform, translation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Model::deleteGeometry() {
|
void Model::deleteGeometry() {
|
||||||
foreach (Model* attachment, _attachments) {
|
foreach (Model* attachment, _attachments) {
|
||||||
delete attachment;
|
delete attachment;
|
||||||
|
|
|
@ -141,6 +141,7 @@ protected:
|
||||||
|
|
||||||
class JointState {
|
class JointState {
|
||||||
public:
|
public:
|
||||||
|
glm::vec3 translation;
|
||||||
glm::quat rotation;
|
glm::quat rotation;
|
||||||
glm::mat4 transform;
|
glm::mat4 transform;
|
||||||
glm::quat combinedRotation;
|
glm::quat combinedRotation;
|
||||||
|
@ -172,6 +173,8 @@ protected:
|
||||||
bool allIntermediatesFree = false, const glm::vec3& alignment = glm::vec3(0.0f, -1.0f, 0.0f));
|
bool allIntermediatesFree = false, const glm::vec3& alignment = glm::vec3(0.0f, -1.0f, 0.0f));
|
||||||
bool setJointRotation(int jointIndex, const glm::quat& rotation, bool fromBind = false);
|
bool setJointRotation(int jointIndex, const glm::quat& rotation, bool fromBind = false);
|
||||||
|
|
||||||
|
void setJointTranslation(int jointIndex, const glm::vec3& translation);
|
||||||
|
|
||||||
/// Restores the indexed joint to its default position.
|
/// Restores the indexed joint to its default position.
|
||||||
/// \param percent the percentage of the default position to apply (i.e., 0.25f to slerp one fourth of the way to
|
/// \param percent the percentage of the default position to apply (i.e., 0.25f to slerp one fourth of the way to
|
||||||
/// the original position
|
/// the original position
|
||||||
|
@ -188,8 +191,6 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void setJointTranslation(int jointIndex, int parentIndex, int childIndex, const glm::vec3& translation);
|
|
||||||
|
|
||||||
void deleteGeometry();
|
void deleteGeometry();
|
||||||
|
|
||||||
float _pupilDilation;
|
float _pupilDilation;
|
||||||
|
|
|
@ -36,7 +36,7 @@ ProgramObject* PointShader::createPointShaderProgram(const QString& name) {
|
||||||
|
|
||||||
void PointShader::init() {
|
void PointShader::init() {
|
||||||
if (_initialized) {
|
if (_initialized) {
|
||||||
qDebug("[ERROR] PointShader is already initialized.\n");
|
qDebug("[ERROR] PointShader is already initialized.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switchToResourcesParentIfRequired();
|
switchToResourcesParentIfRequired();
|
||||||
|
|
|
@ -252,16 +252,17 @@ Texture::~Texture() {
|
||||||
glDeleteTextures(1, &_id);
|
glDeleteTextures(1, &_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) : _reply(NULL), _averageColor(1.0f, 1.0f, 1.0f, 1.0f) {
|
NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) :
|
||||||
|
_request(url),
|
||||||
|
_reply(NULL),
|
||||||
|
_attempts(0),
|
||||||
|
_averageColor(1.0f, 1.0f, 1.0f, 1.0f) {
|
||||||
|
|
||||||
if (!url.isValid()) {
|
if (!url.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QNetworkRequest request(url);
|
_request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
|
||||||
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
|
makeRequest();
|
||||||
_reply = Application::getInstance()->getNetworkAccessManager()->get(request);
|
|
||||||
|
|
||||||
connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64)));
|
|
||||||
connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError()));
|
|
||||||
|
|
||||||
// default to white/blue
|
// default to white/blue
|
||||||
glBindTexture(GL_TEXTURE_2D, getID());
|
glBindTexture(GL_TEXTURE_2D, getID());
|
||||||
|
@ -279,6 +280,13 @@ void NetworkTexture::imageLoaded(const QImage& image) {
|
||||||
// nothing by default
|
// nothing by default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkTexture::makeRequest() {
|
||||||
|
_reply = Application::getInstance()->getNetworkAccessManager()->get(_request);
|
||||||
|
|
||||||
|
connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64)));
|
||||||
|
connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError()));
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkTexture::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
|
void NetworkTexture::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
|
||||||
if (bytesReceived < bytesTotal && !_reply->isFinished()) {
|
if (bytesReceived < bytesTotal && !_reply->isFinished()) {
|
||||||
return;
|
return;
|
||||||
|
@ -314,11 +322,20 @@ void NetworkTexture::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTo
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkTexture::handleReplyError() {
|
void NetworkTexture::handleReplyError() {
|
||||||
qDebug() << _reply->errorString() << "\n";
|
QDebug debug = qDebug() << _reply->errorString();
|
||||||
|
|
||||||
_reply->disconnect(this);
|
_reply->disconnect(this);
|
||||||
_reply->deleteLater();
|
_reply->deleteLater();
|
||||||
_reply = NULL;
|
_reply = NULL;
|
||||||
|
|
||||||
|
// retry with increasing delays
|
||||||
|
const int MAX_ATTEMPTS = 8;
|
||||||
|
const int BASE_DELAY_MS = 1000;
|
||||||
|
if (++_attempts < MAX_ATTEMPTS) {
|
||||||
|
QTimer::singleShot(BASE_DELAY_MS * (int)pow(2.0, _attempts), this, SLOT(makeRequest()));
|
||||||
|
debug << " -- retrying...";
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url, bool normalMap) :
|
DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url, bool normalMap) :
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QNetworkRequest>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QWeakPointer>
|
#include <QWeakPointer>
|
||||||
|
@ -126,12 +127,15 @@ protected:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
void makeRequest();
|
||||||
void handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
void handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
||||||
void handleReplyError();
|
void handleReplyError();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
QNetworkRequest _request;
|
||||||
QNetworkReply* _reply;
|
QNetworkReply* _reply;
|
||||||
|
int _attempts;
|
||||||
glm::vec4 _averageColor;
|
glm::vec4 _averageColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ ProgramObject* VoxelShader::createGeometryShaderProgram(const QString& name) {
|
||||||
|
|
||||||
void VoxelShader::init() {
|
void VoxelShader::init() {
|
||||||
if (_initialized) {
|
if (_initialized) {
|
||||||
qDebug("[ERROR] TestProgram is already initialized.\n");
|
qDebug("[ERROR] TestProgram is already initialized.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switchToResourcesParentIfRequired();
|
switchToResourcesParentIfRequired();
|
||||||
|
|
|
@ -19,7 +19,7 @@ bool Controller::computeStars(unsigned numStars, unsigned seed) {
|
||||||
|
|
||||||
this->retile(numStars, _tileResolution);
|
this->retile(numStars, _tileResolution);
|
||||||
|
|
||||||
qDebug() << "Total time to generate stars: " << ((usecTimestampNow() - usecTimestamp(&startTime)) / 1000) << " msec\n";
|
qDebug() << "Total time to generate stars: " << ((usecTimestampNow() - usecTimestamp(&startTime)) / 1000) << "msec";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ void Generator::computeStarPositions(InputVertices& destination, unsigned limit,
|
||||||
vertices->push_back(InputVertex(azimuth, altitude, computeStarColor(STAR_COLORIZATION)));
|
vertices->push_back(InputVertex(azimuth, altitude, computeStarColor(STAR_COLORIZATION)));
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Total time to generate stars: " << ((usecTimestampNow() - usecTimestamp(&startTime)) / 1000) << " msec\n";
|
qDebug() << "Total time to generate stars: " << ((usecTimestampNow() - usecTimestamp(&startTime)) / 1000) << " msec";
|
||||||
}
|
}
|
||||||
|
|
||||||
// computeStarColor
|
// computeStarColor
|
||||||
|
|
|
@ -241,9 +241,10 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
||||||
NodeToJurisdictionMap& serverJurisdictions) {
|
NodeToJurisdictionMap& serverJurisdictions) {
|
||||||
|
|
||||||
QLocale locale(QLocale::English);
|
QLocale locale(QLocale::English);
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
// only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
|
// only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
|
||||||
if (node->getType() == serverType) {
|
if (node->getType() == serverType) {
|
||||||
serverCount++;
|
serverCount++;
|
||||||
|
@ -261,8 +262,8 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
||||||
std::stringstream serverDetails("");
|
std::stringstream serverDetails("");
|
||||||
std::stringstream extraDetails("");
|
std::stringstream extraDetails("");
|
||||||
std::stringstream linkDetails("");
|
std::stringstream linkDetails("");
|
||||||
|
|
||||||
if (nodeList->getNodeActiveSocketOrPing(&(*node))) {
|
if (nodeList->getNodeActiveSocketOrPing(node.data())) {
|
||||||
serverDetails << "active ";
|
serverDetails << "active ";
|
||||||
} else {
|
} else {
|
||||||
serverDetails << "inactive ";
|
serverDetails << "inactive ";
|
||||||
|
@ -270,29 +271,29 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
||||||
|
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
|
||||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||||
// missing at least one jurisdiction
|
// missing at least one jurisdiction
|
||||||
if (serverJurisdictions.find(nodeUUID) == serverJurisdictions.end()) {
|
if (serverJurisdictions.find(nodeUUID) == serverJurisdictions.end()) {
|
||||||
serverDetails << " unknown jurisdiction ";
|
serverDetails << " unknown jurisdiction ";
|
||||||
} else {
|
} else {
|
||||||
const JurisdictionMap& map = serverJurisdictions[nodeUUID];
|
const JurisdictionMap& map = serverJurisdictions[nodeUUID];
|
||||||
|
|
||||||
unsigned char* rootCode = map.getRootOctalCode();
|
unsigned char* rootCode = map.getRootOctalCode();
|
||||||
|
|
||||||
if (rootCode) {
|
if (rootCode) {
|
||||||
QString rootCodeHex = octalCodeToHexString(rootCode);
|
QString rootCodeHex = octalCodeToHexString(rootCode);
|
||||||
|
|
||||||
VoxelPositionSize rootDetails;
|
VoxelPositionSize rootDetails;
|
||||||
voxelDetailsForCode(rootCode, rootDetails);
|
voxelDetailsForCode(rootCode, rootDetails);
|
||||||
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||||
serverBounds.scale(TREE_SCALE);
|
serverBounds.scale(TREE_SCALE);
|
||||||
serverDetails << " jurisdiction: "
|
serverDetails << " jurisdiction: "
|
||||||
<< rootCodeHex.toLocal8Bit().constData()
|
<< rootCodeHex.toLocal8Bit().constData()
|
||||||
<< " ["
|
<< " ["
|
||||||
<< rootDetails.x << ", "
|
<< rootDetails.x << ", "
|
||||||
<< rootDetails.y << ", "
|
<< rootDetails.y << ", "
|
||||||
<< rootDetails.z << ": "
|
<< rootDetails.z << ": "
|
||||||
<< rootDetails.s << "] ";
|
<< rootDetails.s << "] ";
|
||||||
} else {
|
} else {
|
||||||
serverDetails << " jurisdiction has no rootCode";
|
serverDetails << " jurisdiction has no rootCode";
|
||||||
} // root code
|
} // root code
|
||||||
|
@ -304,7 +305,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
||||||
NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats();
|
NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats();
|
||||||
if (sceneStats->find(nodeUUID) != sceneStats->end()) {
|
if (sceneStats->find(nodeUUID) != sceneStats->end()) {
|
||||||
VoxelSceneStats& stats = sceneStats->at(nodeUUID);
|
VoxelSceneStats& stats = sceneStats->at(nodeUUID);
|
||||||
|
|
||||||
switch (_extraServerDetails[serverCount-1]) {
|
switch (_extraServerDetails[serverCount-1]) {
|
||||||
case MOST: {
|
case MOST: {
|
||||||
extraDetails << "<br/>" ;
|
extraDetails << "<br/>" ;
|
||||||
|
@ -312,14 +313,14 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
||||||
const unsigned long USECS_PER_MSEC = 1000;
|
const unsigned long USECS_PER_MSEC = 1000;
|
||||||
float lastFullEncode = stats.getLastFullTotalEncodeTime() / USECS_PER_MSEC;
|
float lastFullEncode = stats.getLastFullTotalEncodeTime() / USECS_PER_MSEC;
|
||||||
float lastFullSend = stats.getLastFullElapsedTime() / USECS_PER_MSEC;
|
float lastFullSend = stats.getLastFullElapsedTime() / USECS_PER_MSEC;
|
||||||
|
|
||||||
QString lastFullEncodeString = locale.toString(lastFullEncode);
|
QString lastFullEncodeString = locale.toString(lastFullEncode);
|
||||||
QString lastFullSendString = locale.toString(lastFullSend);
|
QString lastFullSendString = locale.toString(lastFullSend);
|
||||||
|
|
||||||
extraDetails << "<br/>" << "Last Full Scene... " <<
|
extraDetails << "<br/>" << "Last Full Scene... " <<
|
||||||
"Encode Time: " << lastFullEncodeString.toLocal8Bit().constData() << " ms " <<
|
"Encode Time: " << lastFullEncodeString.toLocal8Bit().constData() << " ms " <<
|
||||||
"Send Time: " << lastFullSendString.toLocal8Bit().constData() << " ms ";
|
"Send Time: " << lastFullSendString.toLocal8Bit().constData() << " ms ";
|
||||||
|
|
||||||
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
|
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
|
||||||
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
|
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
|
||||||
VoxelSceneStats::ItemInfo& itemInfo = stats.getItemInfo(item);
|
VoxelSceneStats::ItemInfo& itemInfo = stats.getItemInfo(item);
|
||||||
|
@ -330,44 +331,44 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
||||||
QString totalString = locale.toString((uint)stats.getTotalElements());
|
QString totalString = locale.toString((uint)stats.getTotalElements());
|
||||||
QString internalString = locale.toString((uint)stats.getTotalInternal());
|
QString internalString = locale.toString((uint)stats.getTotalInternal());
|
||||||
QString leavesString = locale.toString((uint)stats.getTotalLeaves());
|
QString leavesString = locale.toString((uint)stats.getTotalLeaves());
|
||||||
|
|
||||||
serverDetails << "<br/>" << "Node UUID: " <<
|
serverDetails << "<br/>" << "Node UUID: " <<
|
||||||
nodeUUID.toString().toLocal8Bit().constData() << " ";
|
nodeUUID.toString().toLocal8Bit().constData() << " ";
|
||||||
|
|
||||||
serverDetails << "<br/>" << "Voxels: " <<
|
serverDetails << "<br/>" << "Voxels: " <<
|
||||||
totalString.toLocal8Bit().constData() << " total " <<
|
totalString.toLocal8Bit().constData() << " total " <<
|
||||||
internalString.toLocal8Bit().constData() << " internal " <<
|
internalString.toLocal8Bit().constData() << " internal " <<
|
||||||
leavesString.toLocal8Bit().constData() << " leaves ";
|
leavesString.toLocal8Bit().constData() << " leaves ";
|
||||||
|
|
||||||
QString incomingPacketsString = locale.toString((uint)stats.getIncomingPackets());
|
QString incomingPacketsString = locale.toString((uint)stats.getIncomingPackets());
|
||||||
QString incomingBytesString = locale.toString((uint)stats.getIncomingBytes());
|
QString incomingBytesString = locale.toString((uint)stats.getIncomingBytes());
|
||||||
QString incomingWastedBytesString = locale.toString((uint)stats.getIncomingWastedBytes());
|
QString incomingWastedBytesString = locale.toString((uint)stats.getIncomingWastedBytes());
|
||||||
QString incomingOutOfOrderString = locale.toString((uint)stats.getIncomingOutOfOrder());
|
QString incomingOutOfOrderString = locale.toString((uint)stats.getIncomingOutOfOrder());
|
||||||
QString incomingLikelyLostString = locale.toString((uint)stats.getIncomingLikelyLost());
|
QString incomingLikelyLostString = locale.toString((uint)stats.getIncomingLikelyLost());
|
||||||
|
|
||||||
int clockSkewInMS = node->getClockSkewUsec() / (int)USECS_PER_MSEC;
|
int clockSkewInMS = node->getClockSkewUsec() / (int)USECS_PER_MSEC;
|
||||||
QString incomingFlightTimeString = locale.toString((int)stats.getIncomingFlightTimeAverage());
|
QString incomingFlightTimeString = locale.toString((int)stats.getIncomingFlightTimeAverage());
|
||||||
QString incomingPingTimeString = locale.toString(node->getPingMs());
|
QString incomingPingTimeString = locale.toString(node->getPingMs());
|
||||||
QString incomingClockSkewString = locale.toString(clockSkewInMS);
|
QString incomingClockSkewString = locale.toString(clockSkewInMS);
|
||||||
|
|
||||||
serverDetails << "<br/>" << "Incoming Packets: " <<
|
serverDetails << "<br/>" << "Incoming Packets: " <<
|
||||||
incomingPacketsString.toLocal8Bit().constData() <<
|
incomingPacketsString.toLocal8Bit().constData() <<
|
||||||
" Out of Order: " << incomingOutOfOrderString.toLocal8Bit().constData() <<
|
" Out of Order: " << incomingOutOfOrderString.toLocal8Bit().constData() <<
|
||||||
" Likely Lost: " << incomingLikelyLostString.toLocal8Bit().constData();
|
" Likely Lost: " << incomingLikelyLostString.toLocal8Bit().constData();
|
||||||
|
|
||||||
serverDetails << "<br/>" <<
|
serverDetails << "<br/>" <<
|
||||||
" Average Flight Time: " << incomingFlightTimeString.toLocal8Bit().constData() << " msecs";
|
" Average Flight Time: " << incomingFlightTimeString.toLocal8Bit().constData() << " msecs";
|
||||||
|
|
||||||
serverDetails << "<br/>" <<
|
serverDetails << "<br/>" <<
|
||||||
" Average Ping Time: " << incomingPingTimeString.toLocal8Bit().constData() << " msecs";
|
" Average Ping Time: " << incomingPingTimeString.toLocal8Bit().constData() << " msecs";
|
||||||
|
|
||||||
serverDetails << "<br/>" <<
|
serverDetails << "<br/>" <<
|
||||||
" Average Clock Skew: " << incomingClockSkewString.toLocal8Bit().constData() << " msecs";
|
" Average Clock Skew: " << incomingClockSkewString.toLocal8Bit().constData() << " msecs";
|
||||||
|
|
||||||
serverDetails << "<br/>" << "Incoming" <<
|
serverDetails << "<br/>" << "Incoming" <<
|
||||||
" Bytes: " << incomingBytesString.toLocal8Bit().constData() <<
|
" Bytes: " << incomingBytesString.toLocal8Bit().constData() <<
|
||||||
" Wasted Bytes: " << incomingWastedBytesString.toLocal8Bit().constData();
|
" Wasted Bytes: " << incomingWastedBytesString.toLocal8Bit().constData();
|
||||||
|
|
||||||
serverDetails << extraDetails.str();
|
serverDetails << extraDetails.str();
|
||||||
if (_extraServerDetails[serverCount-1] == MORE) {
|
if (_extraServerDetails[serverCount-1] == MORE) {
|
||||||
linkDetails << " " << " [<a href='most-" << serverCount << "'>most...</a>]";
|
linkDetails << " " << " [<a href='most-" << serverCount << "'>most...</a>]";
|
||||||
|
@ -376,7 +377,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
||||||
linkDetails << " " << " [<a href='more-" << serverCount << "'>less...</a>]";
|
linkDetails << " " << " [<a href='more-" << serverCount << "'>less...</a>]";
|
||||||
linkDetails << " " << " [<a href='less-" << serverCount << "'>least...</a>]";
|
linkDetails << " " << " [<a href='less-" << serverCount << "'>least...</a>]";
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case LESS: {
|
case LESS: {
|
||||||
// nothing
|
// nothing
|
||||||
|
@ -391,7 +392,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
||||||
serverDetails << linkDetails.str();
|
serverDetails << linkDetails.str();
|
||||||
_labels[_voxelServerLables[serverCount - 1]]->setText(serverDetails.str().c_str());
|
_labels[_voxelServerLables[serverCount - 1]]->setText(serverDetails.str().c_str());
|
||||||
} // is VOXEL_SERVER
|
} // is VOXEL_SERVER
|
||||||
} // Node Loop
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelStatsDialog::reject() {
|
void VoxelStatsDialog::reject() {
|
||||||
|
|
|
@ -103,9 +103,9 @@ void AudioInjector::injectAudio() {
|
||||||
|
|
||||||
|
|
||||||
// grab our audio mixer from the NodeList, if it exists
|
// grab our audio mixer from the NodeList, if it exists
|
||||||
Node* audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||||
|
|
||||||
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer)) {
|
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer.data())) {
|
||||||
// send off this audio packet
|
// send off this audio packet
|
||||||
nodeList->getNodeSocket().writeDatagram((char*) injectedAudioPacket,
|
nodeList->getNodeSocket().writeDatagram((char*) injectedAudioPacket,
|
||||||
(currentPacketPosition - injectedAudioPacket) + bytesToCopy,
|
(currentPacketPosition - injectedAudioPacket) + bytesToCopy,
|
||||||
|
|
|
@ -101,7 +101,7 @@ qint64 AudioRingBuffer::writeData(const char* data, qint64 maxSize) {
|
||||||
&& (less(_endOfLastWrite, _nextOutput)
|
&& (less(_endOfLastWrite, _nextOutput)
|
||||||
&& lessEqual(_nextOutput, shiftedPositionAccomodatingWrap(_endOfLastWrite, samplesToCopy)))) {
|
&& lessEqual(_nextOutput, shiftedPositionAccomodatingWrap(_endOfLastWrite, samplesToCopy)))) {
|
||||||
// this read will cross the next output, so call us starved and reset the buffer
|
// this read will cross the next output, so call us starved and reset the buffer
|
||||||
qDebug() << "Filled the ring buffer. Resetting.\n";
|
qDebug() << "Filled the ring buffer. Resetting.";
|
||||||
_endOfLastWrite = _buffer;
|
_endOfLastWrite = _buffer;
|
||||||
_nextOutput = _buffer;
|
_nextOutput = _buffer;
|
||||||
_isStarved = true;
|
_isStarved = true;
|
||||||
|
|
|
@ -20,7 +20,8 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::
|
||||||
_position(0.0f, 0.0f, 0.0f),
|
_position(0.0f, 0.0f, 0.0f),
|
||||||
_orientation(0.0f, 0.0f, 0.0f, 0.0f),
|
_orientation(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
_willBeAddedToMix(false),
|
_willBeAddedToMix(false),
|
||||||
_shouldLoopbackForNode(false)
|
_shouldLoopbackForNode(false),
|
||||||
|
_shouldOutputStarveDebug(true)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,11 +58,19 @@ int PositionalAudioRingBuffer::parsePositionalData(unsigned char* sourceBuffer,
|
||||||
|
|
||||||
bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) {
|
bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) {
|
||||||
if (!isNotStarvedOrHasMinimumSamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL + numJitterBufferSamples)) {
|
if (!isNotStarvedOrHasMinimumSamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL + numJitterBufferSamples)) {
|
||||||
qDebug() << "Starved and do not have minimum samples to start. Buffer held back.\n";
|
if (_shouldOutputStarveDebug) {
|
||||||
|
qDebug() << "Starved and do not have minimum samples to start. Buffer held back.";
|
||||||
|
_shouldOutputStarveDebug = false;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (samplesAvailable() < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
} else if (samplesAvailable() < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
||||||
qDebug() << "Do not have number of samples needed for interval. Buffer starved.\n";
|
qDebug() << "Do not have number of samples needed for interval. Buffer starved.";
|
||||||
_isStarved = true;
|
_isStarved = true;
|
||||||
|
|
||||||
|
// reset our _shouldOutputStarveDebug to true so the next is printed
|
||||||
|
_shouldOutputStarveDebug = true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// good buffer, add this to the mix
|
// good buffer, add this to the mix
|
||||||
|
|
|
@ -49,6 +49,7 @@ protected:
|
||||||
glm::quat _orientation;
|
glm::quat _orientation;
|
||||||
bool _willBeAddedToMix;
|
bool _willBeAddedToMix;
|
||||||
bool _shouldLoopbackForNode;
|
bool _shouldLoopbackForNode;
|
||||||
|
bool _shouldOutputStarveDebug;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__PositionalAudioRingBuffer__) */
|
#endif /* defined(__hifi__PositionalAudioRingBuffer__) */
|
||||||
|
|
|
@ -30,7 +30,6 @@ AvatarData::AvatarData(Node* owningNode) :
|
||||||
_bodyPitch(0.0),
|
_bodyPitch(0.0),
|
||||||
_bodyRoll(0.0),
|
_bodyRoll(0.0),
|
||||||
_targetScale(1.0f),
|
_targetScale(1.0f),
|
||||||
_leaderUUID(),
|
|
||||||
_handState(0),
|
_handState(0),
|
||||||
_keyState(NO_KEY_DOWN),
|
_keyState(NO_KEY_DOWN),
|
||||||
_isChatCirclingEnabled(false),
|
_isChatCirclingEnabled(false),
|
||||||
|
@ -77,10 +76,6 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
|
|
||||||
// Body scale
|
// Body scale
|
||||||
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale);
|
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale);
|
||||||
|
|
||||||
// Follow mode info
|
|
||||||
memcpy(destinationBuffer, _leaderUUID.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
|
|
||||||
destinationBuffer += NUM_BYTES_RFC4122_UUID;
|
|
||||||
|
|
||||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw);
|
||||||
|
@ -200,10 +195,6 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
// Body scale
|
// Body scale
|
||||||
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _targetScale);
|
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _targetScale);
|
||||||
|
|
||||||
// Follow mode info
|
|
||||||
_leaderUUID = QUuid::fromRfc4122(QByteArray((char*) sourceBuffer, NUM_BYTES_RFC4122_UUID));
|
|
||||||
sourceBuffer += NUM_BYTES_RFC4122_UUID;
|
|
||||||
|
|
||||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||||
float headYaw, headPitch, headRoll;
|
float headYaw, headPitch, headRoll;
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw);
|
||||||
|
@ -301,5 +292,5 @@ void AvatarData::setClampedTargetScale(float targetScale) {
|
||||||
targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
|
targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
|
||||||
|
|
||||||
_targetScale = targetScale;
|
_targetScale = targetScale;
|
||||||
qDebug() << "Changed scale to " << _targetScale << "\n";
|
qDebug() << "Changed scale to " << _targetScale;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,8 +101,6 @@ public:
|
||||||
QString getQStringChatMessage() { return QString(_chatMessage.data()); }
|
QString getQStringChatMessage() { return QString(_chatMessage.data()); }
|
||||||
|
|
||||||
bool isChatCirclingEnabled() const { return _isChatCirclingEnabled; }
|
bool isChatCirclingEnabled() const { return _isChatCirclingEnabled; }
|
||||||
|
|
||||||
const QUuid& getLeaderUUID() const { return _leaderUUID; }
|
|
||||||
|
|
||||||
const HeadData* getHeadData() const { return _headData; }
|
const HeadData* getHeadData() const { return _headData; }
|
||||||
const HandData* getHandData() const { return _handData; }
|
const HandData* getHandData() const { return _handData; }
|
||||||
|
@ -135,9 +133,6 @@ protected:
|
||||||
// Body scale
|
// Body scale
|
||||||
float _targetScale;
|
float _targetScale;
|
||||||
|
|
||||||
// Following mode infos
|
|
||||||
QUuid _leaderUUID;
|
|
||||||
|
|
||||||
// Hand state (are we grabbing something or not)
|
// Hand state (are we grabbing something or not)
|
||||||
char _handState;
|
char _handState;
|
||||||
|
|
||||||
|
|
|
@ -301,8 +301,8 @@ void MetavoxelNode::clearChildren(const AttributePointer& attribute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetavoxelPath::operator[](int index) const {
|
int MetavoxelPath::operator[](int index) const {
|
||||||
return _array.at(index * BITS_PER_ELEMENT) | (_array.at(index * BITS_PER_ELEMENT + 1) << 1) |
|
return (int)_array.at(index * BITS_PER_ELEMENT) | ((int)_array.at(index * BITS_PER_ELEMENT + 1) << 1) |
|
||||||
(_array.at(index * BITS_PER_ELEMENT + 2) << 2);
|
((int)_array.at(index * BITS_PER_ELEMENT + 2) << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelPath& MetavoxelPath::operator+=(int element) {
|
MetavoxelPath& MetavoxelPath::operator+=(int element) {
|
||||||
|
@ -429,7 +429,7 @@ void ScriptedMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
_visitation = &visitation;
|
_visitation = &visitation;
|
||||||
_guideFunction.call(QScriptValue(), _arguments);
|
_guideFunction.call(QScriptValue(), _arguments);
|
||||||
if (_guideFunction.engine()->hasUncaughtException()) {
|
if (_guideFunction.engine()->hasUncaughtException()) {
|
||||||
qDebug() << "Script error: " << _guideFunction.engine()->uncaughtException().toString() << "\n";
|
qDebug() << "Script error: " << _guideFunction.engine()->uncaughtException().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
|
||||||
PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket);
|
PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket);
|
||||||
_receivedPacketCount++;
|
_receivedPacketCount++;
|
||||||
|
|
||||||
Node* senderNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
SharedNodePointer senderNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||||
|
|
||||||
unsigned short int sequence = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
|
unsigned short int sequence = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
|
||||||
uint64_t sentAt = (*((uint64_t*)(packetData + numBytesPacketHeader + sizeof(sequence))));
|
uint64_t sentAt = (*((uint64_t*)(packetData + numBytesPacketHeader + sizeof(sequence))));
|
||||||
|
@ -70,7 +70,7 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
|
||||||
if (_myServer->wantsDebugReceiving()) {
|
if (_myServer->wantsDebugReceiving()) {
|
||||||
qDebug() << "PROCESSING THREAD: got '" << packetType << "' packet - " << _receivedPacketCount
|
qDebug() << "PROCESSING THREAD: got '" << packetType << "' packet - " << _receivedPacketCount
|
||||||
<< " command from client receivedBytes=" << packetLength
|
<< " command from client receivedBytes=" << packetLength
|
||||||
<< " sequence=" << sequence << " transitTime=" << transitTime << " usecs\n";
|
<< " sequence=" << sequence << " transitTime=" << transitTime << " usecs";
|
||||||
}
|
}
|
||||||
int atByte = numBytesPacketHeader + sizeof(sequence) + sizeof(sentAt);
|
int atByte = numBytesPacketHeader + sizeof(sequence) + sizeof(sentAt);
|
||||||
unsigned char* editData = (unsigned char*)&packetData[atByte];
|
unsigned char* editData = (unsigned char*)&packetData[atByte];
|
||||||
|
@ -87,7 +87,9 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
|
||||||
_myServer->getOctree()->lockForWrite();
|
_myServer->getOctree()->lockForWrite();
|
||||||
uint64_t startProcess = usecTimestampNow();
|
uint64_t startProcess = usecTimestampNow();
|
||||||
int editDataBytesRead = _myServer->getOctree()->processEditPacketData(packetType,
|
int editDataBytesRead = _myServer->getOctree()->processEditPacketData(packetType,
|
||||||
packetData, packetLength, editData, maxSize, senderNode);
|
packetData,
|
||||||
|
packetLength,
|
||||||
|
editData, maxSize, senderNode.data());
|
||||||
_myServer->getOctree()->unlock();
|
_myServer->getOctree()->unlock();
|
||||||
uint64_t endProcess = usecTimestampNow();
|
uint64_t endProcess = usecTimestampNow();
|
||||||
|
|
||||||
|
@ -114,16 +116,16 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
|
||||||
senderNode->setLastHeardMicrostamp(usecTimestampNow());
|
senderNode->setLastHeardMicrostamp(usecTimestampNow());
|
||||||
nodeUUID = senderNode->getUUID();
|
nodeUUID = senderNode->getUUID();
|
||||||
if (debugProcessPacket) {
|
if (debugProcessPacket) {
|
||||||
qDebug() << "sender has uuid=" << nodeUUID << "\n";
|
qDebug() << "sender has uuid=" << nodeUUID;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (debugProcessPacket) {
|
if (debugProcessPacket) {
|
||||||
qDebug() << "sender has no known nodeUUID.\n";
|
qDebug() << "sender has no known nodeUUID.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trackInboundPackets(nodeUUID, sequence, transitTime, editsInPacket, processTime, lockWaitTime);
|
trackInboundPackets(nodeUUID, sequence, transitTime, editsInPacket, processTime, lockWaitTime);
|
||||||
} else {
|
} else {
|
||||||
printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
|
qDebug("unknown packet ignored... packetData[0]=%c", packetData[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,11 @@ bool OctreeSendThread::process() {
|
||||||
|
|
||||||
// don't do any send processing until the initial load of the octree is complete...
|
// don't do any send processing until the initial load of the octree is complete...
|
||||||
if (_myServer->isInitialLoadComplete()) {
|
if (_myServer->isInitialLoadComplete()) {
|
||||||
Node* node = NodeList::getInstance()->nodeWithUUID(_nodeUUID);
|
SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(_nodeUUID);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
// make sure the node list doesn't kill our node while we're using it
|
// make sure the node list doesn't kill our node while we're using it
|
||||||
if (node->trylock()) {
|
if (node->getMutex().tryLock()) {
|
||||||
gotLock = true;
|
gotLock = true;
|
||||||
OctreeQueryNode* nodeData = NULL;
|
OctreeQueryNode* nodeData = NULL;
|
||||||
|
|
||||||
|
@ -48,15 +48,15 @@ bool OctreeSendThread::process() {
|
||||||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged));
|
printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged));
|
||||||
}
|
}
|
||||||
packetsSent = packetDistributor(node, nodeData, viewFrustumChanged);
|
packetsSent = packetDistributor(node.data(), nodeData, viewFrustumChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
node->unlock(); // we're done with this node for now.
|
node->getMutex().unlock(); // we're done with this node for now.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
qDebug("OctreeSendThread::process() waiting for isInitialLoadComplete()\n");
|
qDebug("OctreeSendThread::process() waiting for isInitialLoadComplete()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ int OctreeSendThread::handlePacketSend(Node* node, OctreeQueryNode* nodeData, in
|
||||||
qDebug() << "Adding stats to packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
|
qDebug() << "Adding stats to packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
|
||||||
" statsMessageLength: " << statsMessageLength <<
|
" statsMessageLength: " << statsMessageLength <<
|
||||||
" original size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
|
" original size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
|
||||||
"] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]\n";
|
"] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually send it
|
// actually send it
|
||||||
|
@ -154,7 +154,7 @@ int OctreeSendThread::handlePacketSend(Node* node, OctreeQueryNode* nodeData, in
|
||||||
if (debug) {
|
if (debug) {
|
||||||
qDebug() << "Sending separate stats packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
|
qDebug() << "Sending separate stats packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
|
||||||
" size: " << statsMessageLength << " [" << _totalBytes <<
|
" size: " << statsMessageLength << " [" << _totalBytes <<
|
||||||
"] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]\n";
|
"] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
trueBytesSent += statsMessageLength;
|
trueBytesSent += statsMessageLength;
|
||||||
|
@ -174,7 +174,7 @@ int OctreeSendThread::handlePacketSend(Node* node, OctreeQueryNode* nodeData, in
|
||||||
if (debug) {
|
if (debug) {
|
||||||
qDebug() << "Sending packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
|
qDebug() << "Sending packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
|
||||||
" size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
|
" size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
|
||||||
"] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]\n";
|
"] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nodeData->stats.markAsSent();
|
nodeData->stats.markAsSent();
|
||||||
|
@ -194,7 +194,7 @@ int OctreeSendThread::handlePacketSend(Node* node, OctreeQueryNode* nodeData, in
|
||||||
if (debug) {
|
if (debug) {
|
||||||
qDebug() << "Sending packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
|
qDebug() << "Sending packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence <<
|
||||||
" size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
|
" size: " << nodeData->getPacketLength() << " [" << _totalBytes <<
|
||||||
"] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]\n";
|
"] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
||||||
qDebug("about to call handlePacketSend() .... line: %d -- format change "
|
qDebug("about to call handlePacketSend() .... line: %d -- format change "
|
||||||
"wantColor=%s wantCompression=%s SENDING PARTIAL PACKET! currentPacketIsColor=%s "
|
"wantColor=%s wantCompression=%s SENDING PARTIAL PACKET! currentPacketIsColor=%s "
|
||||||
"currentPacketIsCompressed=%s\n",
|
"currentPacketIsCompressed=%s",
|
||||||
__LINE__,
|
__LINE__,
|
||||||
debug::valueOf(wantColor), debug::valueOf(wantCompression),
|
debug::valueOf(wantColor), debug::valueOf(wantCompression),
|
||||||
debug::valueOf(nodeData->getCurrentPacketIsColor()),
|
debug::valueOf(nodeData->getCurrentPacketIsColor()),
|
||||||
|
@ -245,7 +245,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||||
} else {
|
} else {
|
||||||
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
||||||
qDebug("wantColor=%s wantCompression=%s FIXING HEADER! currentPacketIsColor=%s currentPacketIsCompressed=%s\n",
|
qDebug("wantColor=%s wantCompression=%s FIXING HEADER! currentPacketIsColor=%s currentPacketIsCompressed=%s",
|
||||||
debug::valueOf(wantColor), debug::valueOf(wantCompression),
|
debug::valueOf(wantColor), debug::valueOf(wantCompression),
|
||||||
debug::valueOf(nodeData->getCurrentPacketIsColor()),
|
debug::valueOf(nodeData->getCurrentPacketIsColor()),
|
||||||
debug::valueOf(nodeData->getCurrentPacketIsCompressed()) );
|
debug::valueOf(nodeData->getCurrentPacketIsCompressed()) );
|
||||||
|
@ -257,7 +257,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
|
targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
|
||||||
}
|
}
|
||||||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
qDebug("line:%d _packetData.changeSettings() wantCompression=%s targetSize=%d\n", __LINE__,
|
qDebug("line:%d _packetData.changeSettings() wantCompression=%s targetSize=%d", __LINE__,
|
||||||
debug::valueOf(wantCompression), targetSize);
|
debug::valueOf(wantCompression), targetSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
qDebug("wantColor/isColor=%s/%s wantCompression/isCompressed=%s/%s viewFrustumChanged=%s, getWantLowResMoving()=%s\n",
|
qDebug("wantColor/isColor=%s/%s wantCompression/isCompressed=%s/%s viewFrustumChanged=%s, getWantLowResMoving()=%s",
|
||||||
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()),
|
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()),
|
||||||
debug::valueOf(wantCompression), debug::valueOf(nodeData->getCurrentPacketIsCompressed()),
|
debug::valueOf(wantCompression), debug::valueOf(nodeData->getCurrentPacketIsCompressed()),
|
||||||
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->getWantLowResMoving()));
|
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->getWantLowResMoving()));
|
||||||
|
@ -274,7 +274,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
const ViewFrustum* lastViewFrustum = wantDelta ? &nodeData->getLastKnownViewFrustum() : NULL;
|
const ViewFrustum* lastViewFrustum = wantDelta ? &nodeData->getLastKnownViewFrustum() : NULL;
|
||||||
|
|
||||||
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
||||||
qDebug("packetDistributor() viewFrustumChanged=%s, nodeBag.isEmpty=%s, viewSent=%s\n",
|
qDebug("packetDistributor() viewFrustumChanged=%s, nodeBag.isEmpty=%s, viewSent=%s",
|
||||||
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()),
|
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()),
|
||||||
debug::valueOf(nodeData->getViewSent())
|
debug::valueOf(nodeData->getViewSent())
|
||||||
);
|
);
|
||||||
|
@ -285,7 +285,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
if (viewFrustumChanged || nodeData->nodeBag.isEmpty()) {
|
if (viewFrustumChanged || nodeData->nodeBag.isEmpty()) {
|
||||||
uint64_t now = usecTimestampNow();
|
uint64_t now = usecTimestampNow();
|
||||||
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
||||||
qDebug("(viewFrustumChanged=%s || nodeData->nodeBag.isEmpty() =%s)...\n",
|
qDebug("(viewFrustumChanged=%s || nodeData->nodeBag.isEmpty() =%s)...",
|
||||||
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()));
|
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()));
|
||||||
if (nodeData->getLastTimeBagEmpty() > 0) {
|
if (nodeData->getLastTimeBagEmpty() > 0) {
|
||||||
float elapsedSceneSend = (now - nodeData->getLastTimeBagEmpty()) / 1000000.0f;
|
float elapsedSceneSend = (now - nodeData->getLastTimeBagEmpty()) / 1000000.0f;
|
||||||
|
@ -294,7 +294,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
} else {
|
} else {
|
||||||
qDebug("elapsed time to send scene = %f seconds", elapsedSceneSend);
|
qDebug("elapsed time to send scene = %f seconds", elapsedSceneSend);
|
||||||
}
|
}
|
||||||
qDebug(" [occlusionCulling:%s, wantDelta:%s, wantColor:%s ]\n",
|
qDebug("[ occlusionCulling:%s, wantDelta:%s, wantColor:%s ]",
|
||||||
debug::valueOf(nodeData->getWantOcclusionCulling()), debug::valueOf(wantDelta),
|
debug::valueOf(nodeData->getWantOcclusionCulling()), debug::valueOf(wantDelta),
|
||||||
debug::valueOf(wantColor));
|
debug::valueOf(wantColor));
|
||||||
}
|
}
|
||||||
|
@ -323,12 +323,12 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
unsigned long elapsedTime = nodeData->stats.getElapsedTime();
|
unsigned long elapsedTime = nodeData->stats.getElapsedTime();
|
||||||
|
|
||||||
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
||||||
qDebug("about to call handlePacketSend() .... line: %d -- completed scene \n", __LINE__ );
|
qDebug("about to call handlePacketSend() .... line: %d -- completed scene", __LINE__ );
|
||||||
}
|
}
|
||||||
int packetsJustSent = handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
int packetsJustSent = handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||||
packetsSentThisInterval += packetsJustSent;
|
packetsSentThisInterval += packetsJustSent;
|
||||||
if (forceDebugging) {
|
if (forceDebugging) {
|
||||||
qDebug("packetsJustSent=%d packetsSentThisInterval=%d\n", packetsJustSent, packetsSentThisInterval);
|
qDebug("packetsJustSent=%d packetsSentThisInterval=%d", packetsJustSent, packetsSentThisInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forceDebugging || _myServer->wantsDebugSending()) {
|
if (forceDebugging || _myServer->wantsDebugSending()) {
|
||||||
|
@ -338,7 +338,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
<< " elapsed:" << elapsedTime
|
<< " elapsed:" << elapsedTime
|
||||||
<< " Packets:" << _totalPackets
|
<< " Packets:" << _totalPackets
|
||||||
<< " Bytes:" << _totalBytes
|
<< " Bytes:" << _totalBytes
|
||||||
<< " Wasted:" << _totalWastedBytes << "\n";
|
<< " Wasted:" << _totalWastedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start tracking our stats
|
// start tracking our stats
|
||||||
|
@ -354,7 +354,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
qDebug() << "Scene started at " << usecTimestampNow()
|
qDebug() << "Scene started at " << usecTimestampNow()
|
||||||
<< " Packets:" << _totalPackets
|
<< " Packets:" << _totalPackets
|
||||||
<< " Bytes:" << _totalBytes
|
<< " Bytes:" << _totalBytes
|
||||||
<< " Wasted:" << _totalWastedBytes << "\n";
|
<< " Wasted:" << _totalWastedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
::startSceneSleepTime = _usleepTime;
|
::startSceneSleepTime = _usleepTime;
|
||||||
|
@ -382,7 +382,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
int maxPacketsPerInterval = std::min(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval());
|
int maxPacketsPerInterval = std::min(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval());
|
||||||
|
|
||||||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
qDebug("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d\n",
|
qDebug("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d",
|
||||||
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
||||||
nodeData->getMaxOctreePacketsPerSecond(), clientMaxPacketsPerInterval);
|
nodeData->getMaxOctreePacketsPerSecond(), clientMaxPacketsPerInterval);
|
||||||
}
|
}
|
||||||
|
@ -391,7 +391,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
bool completedScene = false;
|
bool completedScene = false;
|
||||||
while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval) {
|
while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval) {
|
||||||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
qDebug("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d\n",
|
qDebug("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d server PPI=%d nodePPS=%d nodePPI=%d",
|
||||||
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval(),
|
||||||
nodeData->getMaxOctreePacketsPerSecond(), clientMaxPacketsPerInterval);
|
nodeData->getMaxOctreePacketsPerSecond(), clientMaxPacketsPerInterval);
|
||||||
}
|
}
|
||||||
|
@ -471,14 +471,14 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
if (writtenSize > nodeData->getAvailable()) {
|
if (writtenSize > nodeData->getAvailable()) {
|
||||||
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
||||||
qDebug("about to call handlePacketSend() .... line: %d -- "
|
qDebug("about to call handlePacketSend() .... line: %d -- "
|
||||||
"writtenSize[%d] > available[%d] too big, sending packet as is.\n",
|
"writtenSize[%d] > available[%d] too big, sending packet as is.",
|
||||||
__LINE__, writtenSize, nodeData->getAvailable());
|
__LINE__, writtenSize, nodeData->getAvailable());
|
||||||
}
|
}
|
||||||
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
||||||
qDebug(">>>>>> calling writeToPacket() available=%d compressedSize=%d uncompressedSize=%d target=%d\n",
|
qDebug(">>>>>> calling writeToPacket() available=%d compressedSize=%d uncompressedSize=%d target=%d",
|
||||||
nodeData->getAvailable(), _packetData.getFinalizedSize(),
|
nodeData->getAvailable(), _packetData.getFinalizedSize(),
|
||||||
_packetData.getUncompressedSize(), _packetData.getTargetSize());
|
_packetData.getUncompressedSize(), _packetData.getTargetSize());
|
||||||
}
|
}
|
||||||
|
@ -499,7 +499,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
int targetSize = MAX_OCTREE_PACKET_DATA_SIZE;
|
int targetSize = MAX_OCTREE_PACKET_DATA_SIZE;
|
||||||
if (sendNow) {
|
if (sendNow) {
|
||||||
if (forceDebugging) {
|
if (forceDebugging) {
|
||||||
qDebug("about to call handlePacketSend() .... line: %d -- sendNow = TRUE\n", __LINE__);
|
qDebug("about to call handlePacketSend() .... line: %d -- sendNow = TRUE", __LINE__);
|
||||||
}
|
}
|
||||||
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
|
||||||
if (wantCompression) {
|
if (wantCompression) {
|
||||||
|
@ -515,7 +515,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) - COMPRESS_PADDING;
|
targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) - COMPRESS_PADDING;
|
||||||
}
|
}
|
||||||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
qDebug("line:%d _packetData.changeSettings() wantCompression=%s targetSize=%d\n",__LINE__,
|
qDebug("line:%d _packetData.changeSettings() wantCompression=%s targetSize=%d",__LINE__,
|
||||||
debug::valueOf(nodeData->getWantCompression()), targetSize);
|
debug::valueOf(nodeData->getWantCompression()), targetSize);
|
||||||
}
|
}
|
||||||
_packetData.changeSettings(nodeData->getWantCompression(), targetSize); // will do reset
|
_packetData.changeSettings(nodeData->getWantCompression(), targetSize); // will do reset
|
||||||
|
@ -546,18 +546,18 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
if (elapsedmsec > 1000) {
|
if (elapsedmsec > 1000) {
|
||||||
int elapsedsec = (end - start)/1000000;
|
int elapsedsec = (end - start)/1000000;
|
||||||
qDebug("WARNING! packetLoop() took %d seconds [%d milliseconds %d calls in compress] "
|
qDebug("WARNING! packetLoop() took %d seconds [%d milliseconds %d calls in compress] "
|
||||||
"to generate %d bytes in %d packets %d nodes still to send\n",
|
"to generate %d bytes in %d packets %d nodes still to send",
|
||||||
elapsedsec, elapsedCompressTimeMsecs, elapsedCompressCalls,
|
elapsedsec, elapsedCompressTimeMsecs, elapsedCompressCalls,
|
||||||
trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
||||||
} else {
|
} else {
|
||||||
qDebug("WARNING! packetLoop() took %d milliseconds [%d milliseconds %d calls in compress] "
|
qDebug("WARNING! packetLoop() took %d milliseconds [%d milliseconds %d calls in compress] "
|
||||||
"to generate %d bytes in %d packets, %d nodes still to send\n",
|
"to generate %d bytes in %d packets, %d nodes still to send",
|
||||||
elapsedmsec, elapsedCompressTimeMsecs, elapsedCompressCalls,
|
elapsedmsec, elapsedCompressTimeMsecs, elapsedCompressCalls,
|
||||||
trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
||||||
}
|
}
|
||||||
} else if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
} else if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
qDebug("packetLoop() took %d milliseconds [%d milliseconds %d calls in compress] "
|
qDebug("packetLoop() took %d milliseconds [%d milliseconds %d calls in compress] "
|
||||||
"to generate %d bytes in %d packets, %d nodes still to send\n",
|
"to generate %d bytes in %d packets, %d nodes still to send",
|
||||||
elapsedmsec, elapsedCompressTimeMsecs, elapsedCompressCalls,
|
elapsedmsec, elapsedCompressTimeMsecs, elapsedCompressCalls,
|
||||||
trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
trueBytesSent, truePacketsSent, nodeData->nodeBag.count());
|
||||||
}
|
}
|
||||||
|
@ -575,7 +575,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
||||||
|
|
||||||
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) {
|
||||||
qDebug("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d "
|
qDebug("truePacketsSent=%d packetsSentThisInterval=%d maxPacketsPerInterval=%d "
|
||||||
"server PPI=%d nodePPS=%d nodePPI=%d\n",
|
"server PPI=%d nodePPS=%d nodePPI=%d",
|
||||||
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval,
|
truePacketsSent, packetsSentThisInterval, maxPacketsPerInterval,
|
||||||
_myServer->getPacketsPerClientPerInterval(), nodeData->getMaxOctreePacketsPerSecond(),
|
_myServer->getPacketsPerClientPerInterval(), nodeData->getMaxOctreePacketsPerSecond(),
|
||||||
clientMaxPacketsPerInterval);
|
clientMaxPacketsPerInterval);
|
||||||
|
|
|
@ -27,11 +27,7 @@ void OctreeServer::attachQueryNodeToNode(Node* newNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::nodeAdded(Node* node) {
|
void OctreeServer::nodeKilled(SharedNodePointer node) {
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
void OctreeServer::nodeKilled(Node* node) {
|
|
||||||
// Use this to cleanup our node
|
// Use this to cleanup our node
|
||||||
if (node->getType() == NODE_TYPE_AGENT) {
|
if (node->getType() == NODE_TYPE_AGENT) {
|
||||||
OctreeQueryNode* nodeData = (OctreeQueryNode*)node->getLinkedData();
|
OctreeQueryNode* nodeData = (OctreeQueryNode*)node->getLinkedData();
|
||||||
|
@ -90,14 +86,11 @@ OctreeServer::~OctreeServer() {
|
||||||
_persistThread->terminate();
|
_persistThread->terminate();
|
||||||
delete _persistThread;
|
delete _persistThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tell our NodeList we're done with notifications
|
|
||||||
NodeList::getInstance()->removeHook(this);
|
|
||||||
|
|
||||||
delete _jurisdiction;
|
delete _jurisdiction;
|
||||||
_jurisdiction = NULL;
|
_jurisdiction = NULL;
|
||||||
|
|
||||||
qDebug() << "OctreeServer::run()... DONE\n";
|
qDebug() << "OctreeServer::run()... DONE";
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::initMongoose(int port) {
|
void OctreeServer::initMongoose(int port) {
|
||||||
|
@ -127,7 +120,7 @@ int OctreeServer::civetwebRequestHandler(struct mg_connection* connection) {
|
||||||
|
|
||||||
#ifdef FORCE_CRASH
|
#ifdef FORCE_CRASH
|
||||||
if (strcmp(ri->uri, "/force_crash") == 0 && strcmp(ri->request_method, "GET") == 0) {
|
if (strcmp(ri->uri, "/force_crash") == 0 && strcmp(ri->request_method, "GET") == 0) {
|
||||||
qDebug() << "About to force a crash!\n";
|
qDebug() << "About to force a crash!";
|
||||||
int foo;
|
int foo;
|
||||||
int* forceCrash = &foo;
|
int* forceCrash = &foo;
|
||||||
mg_printf(connection, "%s", "HTTP/1.0 200 OK\r\n\r\n");
|
mg_printf(connection, "%s", "HTTP/1.0 200 OK\r\n\r\n");
|
||||||
|
@ -471,9 +464,9 @@ void OctreeServer::setArguments(int argc, char** argv) {
|
||||||
_argc = argc;
|
_argc = argc;
|
||||||
_argv = const_cast<const char**>(argv);
|
_argv = const_cast<const char**>(argv);
|
||||||
|
|
||||||
qDebug("OctreeServer::setArguments()\n");
|
qDebug("OctreeServer::setArguments()");
|
||||||
for (int i = 0; i < _argc; i++) {
|
for (int i = 0; i < _argc; i++) {
|
||||||
qDebug("_argv[%d]=%s\n", i, _argv[i]);
|
qDebug("_argv[%d]=%s", i, _argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -488,7 +481,7 @@ void OctreeServer::parsePayload() {
|
||||||
|
|
||||||
int argCount = configList.size() + 1;
|
int argCount = configList.size() + 1;
|
||||||
|
|
||||||
qDebug("OctreeServer::parsePayload()... argCount=%d\n",argCount);
|
qDebug("OctreeServer::parsePayload()... argCount=%d",argCount);
|
||||||
|
|
||||||
_parsedArgV = new char*[argCount];
|
_parsedArgV = new char*[argCount];
|
||||||
const char* dummy = "config-from-payload";
|
const char* dummy = "config-from-payload";
|
||||||
|
@ -499,7 +492,7 @@ void OctreeServer::parsePayload() {
|
||||||
QString configItem = configList.at(i-1);
|
QString configItem = configList.at(i-1);
|
||||||
_parsedArgV[i] = new char[configItem.length() + sizeof(char)];
|
_parsedArgV[i] = new char[configItem.length() + sizeof(char)];
|
||||||
strcpy(_parsedArgV[i], configItem.toLocal8Bit().constData());
|
strcpy(_parsedArgV[i], configItem.toLocal8Bit().constData());
|
||||||
qDebug("OctreeServer::parsePayload()... _parsedArgV[%d]=%s\n", i, _parsedArgV[i]);
|
qDebug("OctreeServer::parsePayload()... _parsedArgV[%d]=%s", i, _parsedArgV[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setArguments(argCount, _parsedArgV);
|
setArguments(argCount, _parsedArgV);
|
||||||
|
@ -514,7 +507,7 @@ void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSo
|
||||||
if (packetType == getMyQueryMessageType()) {
|
if (packetType == getMyQueryMessageType()) {
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
qDebug() << "Got PACKET_TYPE_VOXEL_QUERY at" << usecTimestampNow() << "\n";
|
qDebug() << "Got PACKET_TYPE_VOXEL_QUERY at" << usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
int numBytesPacketHeader = numBytesForPacketHeader((unsigned char*) dataByteArray.data());
|
int numBytesPacketHeader = numBytesForPacketHeader((unsigned char*) dataByteArray.data());
|
||||||
|
@ -524,10 +517,10 @@ void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSo
|
||||||
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesPacketHeader,
|
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesPacketHeader,
|
||||||
NUM_BYTES_RFC4122_UUID));
|
NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
Node* node = nodeList->nodeWithUUID(nodeUUID);
|
SharedNodePointer node = nodeList->nodeWithUUID(nodeUUID);
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
nodeList->updateNodeWithData(node, senderSockAddr, (unsigned char *) dataByteArray.data(),
|
nodeList->updateNodeWithData(node.data(), senderSockAddr, (unsigned char *) dataByteArray.data(),
|
||||||
dataByteArray.size());
|
dataByteArray.size());
|
||||||
if (!node->getActiveSocket()) {
|
if (!node->getActiveSocket()) {
|
||||||
// we don't have an active socket for this node, but they're talking to us
|
// we don't have an active socket for this node, but they're talking to us
|
||||||
|
@ -579,22 +572,22 @@ void OctreeServer::run() {
|
||||||
const char* JURISDICTION_FILE = "--jurisdictionFile";
|
const char* JURISDICTION_FILE = "--jurisdictionFile";
|
||||||
const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE);
|
const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE);
|
||||||
if (jurisdictionFile) {
|
if (jurisdictionFile) {
|
||||||
qDebug("jurisdictionFile=%s\n", jurisdictionFile);
|
qDebug("jurisdictionFile=%s", jurisdictionFile);
|
||||||
|
|
||||||
qDebug("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
qDebug("about to readFromFile().... jurisdictionFile=%s", jurisdictionFile);
|
||||||
_jurisdiction = new JurisdictionMap(jurisdictionFile);
|
_jurisdiction = new JurisdictionMap(jurisdictionFile);
|
||||||
qDebug("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
|
qDebug("after readFromFile().... jurisdictionFile=%s", jurisdictionFile);
|
||||||
} else {
|
} else {
|
||||||
const char* JURISDICTION_ROOT = "--jurisdictionRoot";
|
const char* JURISDICTION_ROOT = "--jurisdictionRoot";
|
||||||
const char* jurisdictionRoot = getCmdOption(_argc, _argv, JURISDICTION_ROOT);
|
const char* jurisdictionRoot = getCmdOption(_argc, _argv, JURISDICTION_ROOT);
|
||||||
if (jurisdictionRoot) {
|
if (jurisdictionRoot) {
|
||||||
qDebug("jurisdictionRoot=%s\n", jurisdictionRoot);
|
qDebug("jurisdictionRoot=%s", jurisdictionRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
|
const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
|
||||||
const char* jurisdictionEndNodes = getCmdOption(_argc, _argv, JURISDICTION_ENDNODES);
|
const char* jurisdictionEndNodes = getCmdOption(_argc, _argv, JURISDICTION_ENDNODES);
|
||||||
if (jurisdictionEndNodes) {
|
if (jurisdictionEndNodes) {
|
||||||
qDebug("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
|
qDebug("jurisdictionEndNodes=%s", jurisdictionEndNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jurisdictionRoot || jurisdictionEndNodes) {
|
if (jurisdictionRoot || jurisdictionEndNodes) {
|
||||||
|
@ -612,29 +605,29 @@ void OctreeServer::run() {
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
// tell our NodeList about our desire to get notifications
|
// tell our NodeList about our desire to get notifications
|
||||||
nodeList->addHook(this);
|
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||||
nodeList->linkedDataCreateCallback = &OctreeServer::attachQueryNodeToNode;
|
nodeList->linkedDataCreateCallback = &OctreeServer::attachQueryNodeToNode;
|
||||||
|
|
||||||
srand((unsigned)time(0));
|
srand((unsigned)time(0));
|
||||||
|
|
||||||
const char* VERBOSE_DEBUG = "--verboseDebug";
|
const char* VERBOSE_DEBUG = "--verboseDebug";
|
||||||
_verboseDebug = cmdOptionExists(_argc, _argv, VERBOSE_DEBUG);
|
_verboseDebug = cmdOptionExists(_argc, _argv, VERBOSE_DEBUG);
|
||||||
qDebug("verboseDebug=%s\n", debug::valueOf(_verboseDebug));
|
qDebug("verboseDebug=%s", debug::valueOf(_verboseDebug));
|
||||||
|
|
||||||
const char* DEBUG_SENDING = "--debugSending";
|
const char* DEBUG_SENDING = "--debugSending";
|
||||||
_debugSending = cmdOptionExists(_argc, _argv, DEBUG_SENDING);
|
_debugSending = cmdOptionExists(_argc, _argv, DEBUG_SENDING);
|
||||||
qDebug("debugSending=%s\n", debug::valueOf(_debugSending));
|
qDebug("debugSending=%s", debug::valueOf(_debugSending));
|
||||||
|
|
||||||
const char* DEBUG_RECEIVING = "--debugReceiving";
|
const char* DEBUG_RECEIVING = "--debugReceiving";
|
||||||
_debugReceiving = cmdOptionExists(_argc, _argv, DEBUG_RECEIVING);
|
_debugReceiving = cmdOptionExists(_argc, _argv, DEBUG_RECEIVING);
|
||||||
qDebug("debugReceiving=%s\n", debug::valueOf(_debugReceiving));
|
qDebug("debugReceiving=%s", debug::valueOf(_debugReceiving));
|
||||||
|
|
||||||
// By default we will persist, if you want to disable this, then pass in this parameter
|
// By default we will persist, if you want to disable this, then pass in this parameter
|
||||||
const char* NO_PERSIST = "--NoPersist";
|
const char* NO_PERSIST = "--NoPersist";
|
||||||
if (cmdOptionExists(_argc, _argv, NO_PERSIST)) {
|
if (cmdOptionExists(_argc, _argv, NO_PERSIST)) {
|
||||||
_wantPersist = false;
|
_wantPersist = false;
|
||||||
}
|
}
|
||||||
qDebug("wantPersist=%s\n", debug::valueOf(_wantPersist));
|
qDebug("wantPersist=%s", debug::valueOf(_wantPersist));
|
||||||
|
|
||||||
// if we want Persistence, set up the local file and persist thread
|
// if we want Persistence, set up the local file and persist thread
|
||||||
if (_wantPersist) {
|
if (_wantPersist) {
|
||||||
|
@ -648,7 +641,7 @@ void OctreeServer::run() {
|
||||||
strcpy(_persistFilename, getMyDefaultPersistFilename());
|
strcpy(_persistFilename, getMyDefaultPersistFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("persistFilename=%s\n", _persistFilename);
|
qDebug("persistFilename=%s", _persistFilename);
|
||||||
|
|
||||||
// now set up PersistThread
|
// now set up PersistThread
|
||||||
_persistThread = new OctreePersistThread(_tree, _persistFilename);
|
_persistThread = new OctreePersistThread(_tree, _persistFilename);
|
||||||
|
@ -665,7 +658,7 @@ void OctreeServer::run() {
|
||||||
if (clockSkewOption) {
|
if (clockSkewOption) {
|
||||||
int clockSkew = atoi(clockSkewOption);
|
int clockSkew = atoi(clockSkewOption);
|
||||||
usecTimestampNowForceClockSkew(clockSkew);
|
usecTimestampNowForceClockSkew(clockSkew);
|
||||||
qDebug("clockSkewOption=%s clockSkew=%d\n", clockSkewOption, clockSkew);
|
qDebug("clockSkewOption=%s clockSkew=%d", clockSkewOption, clockSkew);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if the user passed in a command line option for setting packet send rate
|
// Check to see if the user passed in a command line option for setting packet send rate
|
||||||
|
@ -676,7 +669,7 @@ void OctreeServer::run() {
|
||||||
if (_packetsPerClientPerInterval < 1) {
|
if (_packetsPerClientPerInterval < 1) {
|
||||||
_packetsPerClientPerInterval = 1;
|
_packetsPerClientPerInterval = 1;
|
||||||
}
|
}
|
||||||
qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, _packetsPerClientPerInterval);
|
qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d", packetsPerSecond, _packetsPerClientPerInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiSockAddr senderSockAddr;
|
HifiSockAddr senderSockAddr;
|
||||||
|
@ -703,7 +696,7 @@ void OctreeServer::run() {
|
||||||
if (gmtm != NULL) {
|
if (gmtm != NULL) {
|
||||||
strftime(utcBuffer, MAX_TIME_LENGTH, " [%m/%d/%Y %X UTC]", gmtm);
|
strftime(utcBuffer, MAX_TIME_LENGTH, " [%m/%d/%Y %X UTC]", gmtm);
|
||||||
}
|
}
|
||||||
qDebug() << "Now running... started at: " << localBuffer << utcBuffer << "\n";
|
qDebug() << "Now running... started at: " << localBuffer << utcBuffer;
|
||||||
|
|
||||||
QTimer* domainServerTimer = new QTimer(this);
|
QTimer* domainServerTimer = new QTimer(this);
|
||||||
connect(domainServerTimer, SIGNAL(timeout()), this, SLOT(checkInWithDomainServerOrExit()));
|
connect(domainServerTimer, SIGNAL(timeout()), this, SLOT(checkInWithDomainServerOrExit()));
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
#include "OctreeInboundPacketProcessor.h"
|
#include "OctreeInboundPacketProcessor.h"
|
||||||
|
|
||||||
/// Handles assignments of type OctreeServer - sending octrees to various clients.
|
/// Handles assignments of type OctreeServer - sending octrees to various clients.
|
||||||
class OctreeServer : public ThreadedAssignment, public NodeListHook {
|
class OctreeServer : public ThreadedAssignment {
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
OctreeServer(const unsigned char* dataBuffer, int numBytes);
|
OctreeServer(const unsigned char* dataBuffer, int numBytes);
|
||||||
~OctreeServer();
|
~OctreeServer();
|
||||||
|
@ -60,15 +61,13 @@ public:
|
||||||
virtual int sendSpecialPacket(Node* node) { return 0; }
|
virtual int sendSpecialPacket(Node* node) { return 0; }
|
||||||
|
|
||||||
static void attachQueryNodeToNode(Node* newNode);
|
static void attachQueryNodeToNode(Node* newNode);
|
||||||
|
|
||||||
// NodeListHook
|
|
||||||
virtual void nodeAdded(Node* node);
|
|
||||||
virtual void nodeKilled(Node* node);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/// runs the voxel server assignment
|
/// runs the voxel server assignment
|
||||||
void run();
|
void run();
|
||||||
void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr);
|
void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr);
|
||||||
|
|
||||||
|
void nodeKilled(SharedNodePointer node);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int _argc;
|
int _argc;
|
||||||
|
|
|
@ -71,19 +71,19 @@ CoverageMap::~CoverageMap() {
|
||||||
};
|
};
|
||||||
|
|
||||||
void CoverageMap::printStats() {
|
void CoverageMap::printStats() {
|
||||||
qDebug("CoverageMap::printStats()...\n");
|
qDebug("CoverageMap::printStats()...");
|
||||||
qDebug("MINIMUM_POLYGON_AREA_TO_STORE=%f\n",MINIMUM_POLYGON_AREA_TO_STORE);
|
qDebug("MINIMUM_POLYGON_AREA_TO_STORE=%f",MINIMUM_POLYGON_AREA_TO_STORE);
|
||||||
qDebug("_mapCount=%d\n",_mapCount);
|
qDebug("_mapCount=%d",_mapCount);
|
||||||
qDebug("_checkMapRootCalls=%d\n",_checkMapRootCalls);
|
qDebug("_checkMapRootCalls=%d",_checkMapRootCalls);
|
||||||
qDebug("_notAllInView=%d\n",_notAllInView);
|
qDebug("_notAllInView=%d",_notAllInView);
|
||||||
qDebug("_maxPolygonsUsed=%d\n",CoverageRegion::_maxPolygonsUsed);
|
qDebug("_maxPolygonsUsed=%d",CoverageRegion::_maxPolygonsUsed);
|
||||||
qDebug("_totalPolygons=%d\n",CoverageRegion::_totalPolygons);
|
qDebug("_totalPolygons=%d",CoverageRegion::_totalPolygons);
|
||||||
qDebug("_occlusionTests=%d\n",CoverageRegion::_occlusionTests);
|
qDebug("_occlusionTests=%d",CoverageRegion::_occlusionTests);
|
||||||
qDebug("_regionSkips=%d\n",CoverageRegion::_regionSkips);
|
qDebug("_regionSkips=%d",CoverageRegion::_regionSkips);
|
||||||
qDebug("_tooSmallSkips=%d\n",CoverageRegion::_tooSmallSkips);
|
qDebug("_tooSmallSkips=%d",CoverageRegion::_tooSmallSkips);
|
||||||
qDebug("_regionFullSkips=%d\n",CoverageRegion::_regionFullSkips);
|
qDebug("_regionFullSkips=%d",CoverageRegion::_regionFullSkips);
|
||||||
qDebug("_outOfOrderPolygon=%d\n",CoverageRegion::_outOfOrderPolygon);
|
qDebug("_outOfOrderPolygon=%d",CoverageRegion::_outOfOrderPolygon);
|
||||||
qDebug("_clippedPolygons=%d\n",CoverageRegion::_clippedPolygons);
|
qDebug("_clippedPolygons=%d",CoverageRegion::_clippedPolygons);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoverageMap::erase() {
|
void CoverageMap::erase() {
|
||||||
|
@ -102,7 +102,7 @@ void CoverageMap::erase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isRoot && wantDebugging) {
|
if (_isRoot && wantDebugging) {
|
||||||
qDebug("CoverageMap last to be deleted...\n");
|
qDebug("CoverageMap last to be deleted...");
|
||||||
printStats();
|
printStats();
|
||||||
|
|
||||||
CoverageRegion::_maxPolygonsUsed = 0;
|
CoverageRegion::_maxPolygonsUsed = 0;
|
||||||
|
|
|
@ -78,11 +78,11 @@ void CoverageMapV2::erase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isRoot && wantDebugging) {
|
if (_isRoot && wantDebugging) {
|
||||||
qDebug("CoverageMapV2 last to be deleted...\n");
|
qDebug("CoverageMapV2 last to be deleted...");
|
||||||
qDebug("MINIMUM_POLYGON_AREA_TO_STORE=%f\n",MINIMUM_POLYGON_AREA_TO_STORE);
|
qDebug("MINIMUM_POLYGON_AREA_TO_STORE=%f",MINIMUM_POLYGON_AREA_TO_STORE);
|
||||||
qDebug("_mapCount=%d\n",_mapCount);
|
qDebug("_mapCount=%d",_mapCount);
|
||||||
qDebug("_checkMapRootCalls=%d\n",_checkMapRootCalls);
|
qDebug("_checkMapRootCalls=%d",_checkMapRootCalls);
|
||||||
qDebug("_notAllInView=%d\n",_notAllInView);
|
qDebug("_notAllInView=%d",_notAllInView);
|
||||||
_mapCount = 0;
|
_mapCount = 0;
|
||||||
_checkMapRootCalls = 0;
|
_checkMapRootCalls = 0;
|
||||||
_notAllInView = 0;
|
_notAllInView = 0;
|
||||||
|
|
|
@ -15,29 +15,20 @@
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include "JurisdictionListener.h"
|
#include "JurisdictionListener.h"
|
||||||
|
|
||||||
|
|
||||||
JurisdictionListener::JurisdictionListener(NODE_TYPE type, PacketSenderNotify* notify) :
|
JurisdictionListener::JurisdictionListener(NODE_TYPE type, PacketSenderNotify* notify) :
|
||||||
PacketSender(notify, JurisdictionListener::DEFAULT_PACKETS_PER_SECOND)
|
PacketSender(notify, JurisdictionListener::DEFAULT_PACKETS_PER_SECOND)
|
||||||
{
|
{
|
||||||
_nodeType = type;
|
_nodeType = type;
|
||||||
ReceivedPacketProcessor::_dontSleep = true; // we handle sleeping so this class doesn't need to
|
ReceivedPacketProcessor::_dontSleep = true; // we handle sleeping so this class doesn't need to
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
nodeList->addHook(this);
|
|
||||||
|
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
||||||
|
|
||||||
//qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)\n", type);
|
//qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)\n", type);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JurisdictionListener::~JurisdictionListener() {
|
void JurisdictionListener::nodeKilled(SharedNodePointer node) {
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
nodeList->removeHook(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JurisdictionListener::nodeAdded(Node* node) {
|
|
||||||
// nothing to do. But need to implement it.
|
|
||||||
}
|
|
||||||
|
|
||||||
void JurisdictionListener::nodeKilled(Node* node) {
|
|
||||||
if (_jurisdictions.find(node->getUUID()) != _jurisdictions.end()) {
|
if (_jurisdictions.find(node->getUUID()) != _jurisdictions.end()) {
|
||||||
_jurisdictions.erase(_jurisdictions.find(node->getUUID()));
|
_jurisdictions.erase(_jurisdictions.find(node->getUUID()));
|
||||||
}
|
}
|
||||||
|
@ -52,8 +43,9 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
||||||
int nodeCount = 0;
|
int nodeCount = 0;
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
if (nodeList->getNodeActiveSocketOrPing(&(*node)) &&
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
|
if (nodeList->getNodeActiveSocketOrPing(node.data()) &&
|
||||||
node->getType() == getNodeType()) {
|
node->getType() == getNodeType()) {
|
||||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||||
PacketSender::queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
|
PacketSender::queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
|
||||||
|
@ -73,7 +65,7 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
||||||
|
|
||||||
void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||||
if (packetData[0] == PACKET_TYPE_JURISDICTION) {
|
if (packetData[0] == PACKET_TYPE_JURISDICTION) {
|
||||||
Node* node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||||
if (node) {
|
if (node) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
JurisdictionMap map;
|
JurisdictionMap map;
|
||||||
|
|
|
@ -15,32 +15,32 @@
|
||||||
#include <PacketSender.h>
|
#include <PacketSender.h>
|
||||||
#include <ReceivedPacketProcessor.h>
|
#include <ReceivedPacketProcessor.h>
|
||||||
|
|
||||||
|
|
||||||
#include "JurisdictionMap.h"
|
#include "JurisdictionMap.h"
|
||||||
|
|
||||||
/// Sends out PACKET_TYPE_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes
|
/// Sends out PACKET_TYPE_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes
|
||||||
/// the PACKET_TYPE_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions
|
/// the PACKET_TYPE_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions
|
||||||
/// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
/// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
||||||
/// and adding them to the processing queue by calling queueReceivedPacket()
|
/// and adding them to the processing queue by calling queueReceivedPacket()
|
||||||
class JurisdictionListener : public NodeListHook, public PacketSender, public ReceivedPacketProcessor {
|
class JurisdictionListener : public PacketSender, public ReceivedPacketProcessor {
|
||||||
public:
|
public:
|
||||||
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
||||||
static const int NO_SERVER_CHECK_RATE = 60; // if no servers yet detected, keep checking at 60fps
|
static const int NO_SERVER_CHECK_RATE = 60; // if no servers yet detected, keep checking at 60fps
|
||||||
|
|
||||||
JurisdictionListener(NODE_TYPE type = NODE_TYPE_VOXEL_SERVER, PacketSenderNotify* notify = NULL);
|
JurisdictionListener(NODE_TYPE type = NODE_TYPE_VOXEL_SERVER, PacketSenderNotify* notify = NULL);
|
||||||
~JurisdictionListener();
|
|
||||||
|
|
||||||
virtual bool process();
|
virtual bool process();
|
||||||
|
|
||||||
NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; };
|
NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; };
|
||||||
|
|
||||||
/// Called by NodeList to inform us that a node has been added.
|
|
||||||
void nodeAdded(Node* node);
|
|
||||||
/// Called by NodeList to inform us that a node has been killed.
|
|
||||||
void nodeKilled(Node* node);
|
|
||||||
|
|
||||||
NODE_TYPE getNodeType() const { return _nodeType; }
|
NODE_TYPE getNodeType() const { return _nodeType; }
|
||||||
void setNodeType(NODE_TYPE type) { _nodeType = type; }
|
void setNodeType(NODE_TYPE type) { _nodeType = type; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/// Called by NodeList to inform us that a node has been killed.
|
||||||
|
void nodeKilled(SharedNodePointer node);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Callback for processing of received packets. Will process any queued PACKET_TYPE_JURISDICTION and update the
|
/// Callback for processing of received packets. Will process any queued PACKET_TYPE_JURISDICTION and update the
|
||||||
/// jurisdiction map member variable
|
/// jurisdiction map member variable
|
||||||
|
|
|
@ -145,7 +145,7 @@ void myDebugPrintOctalCode(const unsigned char* octalCode, bool withNewLine) {
|
||||||
|
|
||||||
JurisdictionMap::JurisdictionMap(const char* rootHexCode, const char* endNodesHexCodes) {
|
JurisdictionMap::JurisdictionMap(const char* rootHexCode, const char* endNodesHexCodes) {
|
||||||
|
|
||||||
qDebug("JurisdictionMap::JurisdictionMap(const char* rootHexCode=[%p] %s, const char* endNodesHexCodes=[%p] %s)\n",
|
qDebug("JurisdictionMap::JurisdictionMap(const char* rootHexCode=[%p] %s, const char* endNodesHexCodes=[%p] %s)",
|
||||||
rootHexCode, rootHexCode, endNodesHexCodes, endNodesHexCodes);
|
rootHexCode, rootHexCode, endNodesHexCodes, endNodesHexCodes);
|
||||||
|
|
||||||
_rootOctalCode = hexStringToOctalCode(QString(rootHexCode));
|
_rootOctalCode = hexStringToOctalCode(QString(rootHexCode));
|
||||||
|
@ -162,7 +162,7 @@ JurisdictionMap::JurisdictionMap(const char* rootHexCode, const char* endNodesHe
|
||||||
|
|
||||||
unsigned char* endNodeOctcode = hexStringToOctalCode(endNodeHexString);
|
unsigned char* endNodeOctcode = hexStringToOctalCode(endNodeHexString);
|
||||||
|
|
||||||
qDebug("JurisdictionMap::JurisdictionMap() endNodeList(%d)=%s\n",
|
qDebug("JurisdictionMap::JurisdictionMap() endNodeList(%d)=%s",
|
||||||
i, endNodeHexString.toLocal8Bit().constData());
|
i, endNodeHexString.toLocal8Bit().constData());
|
||||||
|
|
||||||
//printOctalCode(endNodeOctcode);
|
//printOctalCode(endNodeOctcode);
|
||||||
|
@ -209,7 +209,7 @@ bool JurisdictionMap::readFromFile(const char* filename) {
|
||||||
QString settingsFile(filename);
|
QString settingsFile(filename);
|
||||||
QSettings settings(settingsFile, QSettings::IniFormat);
|
QSettings settings(settingsFile, QSettings::IniFormat);
|
||||||
QString rootCode = settings.value("root","00").toString();
|
QString rootCode = settings.value("root","00").toString();
|
||||||
qDebug() << "rootCode=" << rootCode << "\n";
|
qDebug() << "rootCode=" << rootCode;
|
||||||
|
|
||||||
_rootOctalCode = hexStringToOctalCode(rootCode);
|
_rootOctalCode = hexStringToOctalCode(rootCode);
|
||||||
printOctalCode(_rootOctalCode);
|
printOctalCode(_rootOctalCode);
|
||||||
|
@ -220,7 +220,7 @@ bool JurisdictionMap::readFromFile(const char* filename) {
|
||||||
foreach (const QString &childKey, childKeys) {
|
foreach (const QString &childKey, childKeys) {
|
||||||
QString childValue = settings.value(childKey).toString();
|
QString childValue = settings.value(childKey).toString();
|
||||||
values.insert(childKey, childValue);
|
values.insert(childKey, childValue);
|
||||||
qDebug() << childKey << "=" << childValue << "\n";
|
qDebug() << childKey << "=" << childValue;
|
||||||
|
|
||||||
unsigned char* octcode = hexStringToOctalCode(childValue);
|
unsigned char* octcode = hexStringToOctalCode(childValue);
|
||||||
printOctalCode(octcode);
|
printOctalCode(octcode);
|
||||||
|
@ -234,11 +234,11 @@ bool JurisdictionMap::readFromFile(const char* filename) {
|
||||||
void JurisdictionMap::displayDebugDetails() const {
|
void JurisdictionMap::displayDebugDetails() const {
|
||||||
QString rootNodeValue = octalCodeToHexString(_rootOctalCode);
|
QString rootNodeValue = octalCodeToHexString(_rootOctalCode);
|
||||||
|
|
||||||
qDebug() << "root:" << rootNodeValue << "\n";
|
qDebug() << "root:" << rootNodeValue;
|
||||||
|
|
||||||
for (int i = 0; i < _endNodes.size(); i++) {
|
for (int i = 0; i < _endNodes.size(); i++) {
|
||||||
QString value = octalCodeToHexString(_endNodes[i]);
|
QString value = octalCodeToHexString(_endNodes[i]);
|
||||||
qDebug() << "End node[" << i << "]: " << rootNodeValue << "\n";
|
qDebug() << "End node[" << i << "]: " << rootNodeValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ JurisdictionSender::~JurisdictionSender() {
|
||||||
|
|
||||||
void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||||
if (packetData[0] == PACKET_TYPE_JURISDICTION_REQUEST) {
|
if (packetData[0] == PACKET_TYPE_JURISDICTION_REQUEST) {
|
||||||
Node* node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||||
if (node) {
|
if (node) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
lockRequestingNodes();
|
lockRequestingNodes();
|
||||||
|
@ -64,7 +64,7 @@ bool JurisdictionSender::process() {
|
||||||
|
|
||||||
QUuid nodeUUID = _nodesRequestingJurisdictions.front();
|
QUuid nodeUUID = _nodesRequestingJurisdictions.front();
|
||||||
_nodesRequestingJurisdictions.pop();
|
_nodesRequestingJurisdictions.pop();
|
||||||
Node* node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
SharedNodePointer node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
||||||
|
|
||||||
if (node->getActiveSocket() != NULL) {
|
if (node->getActiveSocket() != NULL) {
|
||||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
/// to requesting parties. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
/// to requesting parties. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
||||||
/// and adding them to the processing queue by calling queueReceivedPacket()
|
/// and adding them to the processing queue by calling queueReceivedPacket()
|
||||||
class JurisdictionSender : public PacketSender, public ReceivedPacketProcessor {
|
class JurisdictionSender : public PacketSender, public ReceivedPacketProcessor {
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ void Octree::recurseTreeWithOperation(RecurseOctreeOperation operation, void* ex
|
||||||
void Octree::recurseNodeWithOperation(OctreeElement* node, RecurseOctreeOperation operation, void* extraData,
|
void Octree::recurseNodeWithOperation(OctreeElement* node, RecurseOctreeOperation operation, void* extraData,
|
||||||
int recursionCount) {
|
int recursionCount) {
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
qDebug() << "Octree::recurseNodeWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!\n";
|
qDebug() << "Octree::recurseNodeWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ void Octree::recurseNodeWithOperationDistanceSorted(OctreeElement* node, Recurse
|
||||||
const glm::vec3& point, void* extraData, int recursionCount) {
|
const glm::vec3& point, void* extraData, int recursionCount) {
|
||||||
|
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
qDebug() << "Octree::recurseNodeWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!\n";
|
qDebug() << "Octree::recurseNodeWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ void Octree::reaverageOctreeElements(OctreeElement* startNode) {
|
||||||
recursionCount++;
|
recursionCount++;
|
||||||
}
|
}
|
||||||
if (recursionCount > UNREASONABLY_DEEP_RECURSION) {
|
if (recursionCount > UNREASONABLY_DEEP_RECURSION) {
|
||||||
qDebug("Octree::reaverageOctreeElements()... bailing out of UNREASONABLY_DEEP_RECURSION\n");
|
qDebug("Octree::reaverageOctreeElements()... bailing out of UNREASONABLY_DEEP_RECURSION");
|
||||||
recursionCount--;
|
recursionCount--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -674,7 +674,7 @@ int Octree::encodeTreeBitstream(OctreeElement* node,
|
||||||
|
|
||||||
// you can't call this without a valid node
|
// you can't call this without a valid node
|
||||||
if (!node) {
|
if (!node) {
|
||||||
qDebug("WARNING! encodeTreeBitstream() called with node=NULL\n");
|
qDebug("WARNING! encodeTreeBitstream() called with node=NULL");
|
||||||
params.stopReason = EncodeBitstreamParams::NULL_NODE;
|
params.stopReason = EncodeBitstreamParams::NULL_NODE;
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
@ -763,7 +763,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* node,
|
||||||
|
|
||||||
// you can't call this without a valid node
|
// you can't call this without a valid node
|
||||||
if (!node) {
|
if (!node) {
|
||||||
qDebug("WARNING! encodeTreeBitstreamRecursion() called with node=NULL\n");
|
qDebug("WARNING! encodeTreeBitstreamRecursion() called with node=NULL");
|
||||||
params.stopReason = EncodeBitstreamParams::NULL_NODE;
|
params.stopReason = EncodeBitstreamParams::NULL_NODE;
|
||||||
return bytesAtThisLevel;
|
return bytesAtThisLevel;
|
||||||
}
|
}
|
||||||
|
@ -1312,7 +1312,7 @@ bool Octree::readFromSVOFile(const char* fileName) {
|
||||||
emit importSize(1.0f, 1.0f, 1.0f);
|
emit importSize(1.0f, 1.0f, 1.0f);
|
||||||
emit importProgress(0);
|
emit importProgress(0);
|
||||||
|
|
||||||
qDebug("loading file %s...\n", fileName);
|
qDebug("Loading file %s...", fileName);
|
||||||
|
|
||||||
// get file length....
|
// get file length....
|
||||||
unsigned long fileLength = file.tellg();
|
unsigned long fileLength = file.tellg();
|
||||||
|
@ -1341,10 +1341,10 @@ bool Octree::readFromSVOFile(const char* fileName) {
|
||||||
dataLength -= sizeof(expectedVersion);
|
dataLength -= sizeof(expectedVersion);
|
||||||
fileOk = true;
|
fileOk = true;
|
||||||
} else {
|
} else {
|
||||||
qDebug("SVO file version mismatch. Expected: %d Got: %d\n", expectedVersion, gotVersion);
|
qDebug("SVO file version mismatch. Expected: %d Got: %d", expectedVersion, gotVersion);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug("SVO file type mismatch. Expected: %c Got: %c\n", expectedType, gotType);
|
qDebug("SVO file type mismatch. Expected: %c Got: %c", expectedType, gotType);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fileOk = true; // assume the file is ok
|
fileOk = true; // assume the file is ok
|
||||||
|
@ -1367,7 +1367,7 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* node) {
|
||||||
std::ofstream file(fileName, std::ios::out|std::ios::binary);
|
std::ofstream file(fileName, std::ios::out|std::ios::binary);
|
||||||
|
|
||||||
if(file.is_open()) {
|
if(file.is_open()) {
|
||||||
qDebug("saving to file %s...\n", fileName);
|
qDebug("Saving to file %s...", fileName);
|
||||||
|
|
||||||
// before reading the file, check to see if this version of the Octree supports file versions
|
// before reading the file, check to see if this version of the Octree supports file versions
|
||||||
if (getWantSVOfileVersions()) {
|
if (getWantSVOfileVersions()) {
|
||||||
|
|
|
@ -57,14 +57,15 @@ bool OctreeEditPacketSender::serversExist() const {
|
||||||
bool hasServers = false;
|
bool hasServers = false;
|
||||||
bool atLeastOnJurisdictionMissing = false; // assume the best
|
bool atLeastOnJurisdictionMissing = false; // assume the best
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
// only send to the NodeTypes that are getMyNodeType()
|
// only send to the NodeTypes that are getMyNodeType()
|
||||||
if (node->getType() == getMyNodeType()) {
|
if (node->getType() == getMyNodeType()) {
|
||||||
if (nodeList->getNodeActiveSocketOrPing(&(*node))) {
|
if (nodeList->getNodeActiveSocketOrPing(node.data())) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
// If we've got Jurisdictions set, then check to see if we know the jurisdiction for this server
|
// If we've got Jurisdictions set, then check to see if we know the jurisdiction for this server
|
||||||
if (_serverJurisdictions) {
|
if (_serverJurisdictions) {
|
||||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||||
// missing at least one jurisdiction
|
// missing at least one jurisdiction
|
||||||
if ((*_serverJurisdictions).find(nodeUUID) == (*_serverJurisdictions).end()) {
|
if ((*_serverJurisdictions).find(nodeUUID) == (*_serverJurisdictions).end()) {
|
||||||
atLeastOnJurisdictionMissing = true;
|
atLeastOnJurisdictionMissing = true;
|
||||||
|
@ -77,6 +78,7 @@ bool OctreeEditPacketSender::serversExist() const {
|
||||||
break; // no point in looking further...
|
break; // no point in looking further...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (hasServers && !atLeastOnJurisdictionMissing);
|
return (hasServers && !atLeastOnJurisdictionMissing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,11 +86,12 @@ bool OctreeEditPacketSender::serversExist() const {
|
||||||
// a known nodeID.
|
// a known nodeID.
|
||||||
void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned char* buffer, ssize_t length) {
|
void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned char* buffer, ssize_t length) {
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
|
||||||
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
// only send to the NodeTypes that are getMyNodeType()
|
// only send to the NodeTypes that are getMyNodeType()
|
||||||
if (node->getType() == getMyNodeType() &&
|
if (node->getType() == getMyNodeType() &&
|
||||||
((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
|
((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
|
||||||
if (nodeList->getNodeActiveSocketOrPing(&(*node))) {
|
if (nodeList->getNodeActiveSocketOrPing(node.data())) {
|
||||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||||
queuePacketForSending(*nodeAddress, buffer, length);
|
queuePacketForSending(*nodeAddress, buffer, length);
|
||||||
|
|
||||||
|
@ -100,11 +103,12 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c
|
||||||
uint64_t createdAt = (*((uint64_t*)(buffer + numBytesPacketHeader + sizeof(sequence))));
|
uint64_t createdAt = (*((uint64_t*)(buffer + numBytesPacketHeader + sizeof(sequence))));
|
||||||
uint64_t queuedAt = usecTimestampNow();
|
uint64_t queuedAt = usecTimestampNow();
|
||||||
uint64_t transitTime = queuedAt - createdAt;
|
uint64_t transitTime = queuedAt - createdAt;
|
||||||
|
|
||||||
qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] <<
|
qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] <<
|
||||||
" - command to node bytes=" << length <<
|
" - command to node bytes=" << length <<
|
||||||
" sequence=" << sequence <<
|
" sequence=" << sequence <<
|
||||||
" transitTimeSoFar=" << transitTime << " usecs\n";
|
" transitTimeSoFar=" << transitTime << " usecs";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,13 +170,13 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, ssize_t l
|
||||||
// But we can't really do that with a packed message, since each edit message could be destined
|
// But we can't really do that with a packed message, since each edit message could be destined
|
||||||
// for a different server... So we need to actually manage multiple queued packets... one
|
// for a different server... So we need to actually manage multiple queued packets... one
|
||||||
// for each server
|
// for each server
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
// only send to the NodeTypes that are getMyNodeType()
|
// only send to the NodeTypes that are getMyNodeType()
|
||||||
if (node->getActiveSocket() != NULL && node->getType() == getMyNodeType()) {
|
if (node->getActiveSocket() != NULL && node->getType() == getMyNodeType()) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
bool isMyJurisdiction = true;
|
bool isMyJurisdiction = true;
|
||||||
// we need to get the jurisdiction for this
|
// we need to get the jurisdiction for this
|
||||||
// here we need to get the "pending packet" for this server
|
// here we need to get the "pending packet" for this server
|
||||||
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
|
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
|
||||||
isMyJurisdiction = (map.isMyJurisdiction(octCode, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN);
|
isMyJurisdiction = (map.isMyJurisdiction(octCode, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN);
|
||||||
|
@ -212,15 +216,15 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PACKET_TYPE type, unsigned c
|
||||||
// But we can't really do that with a packed message, since each edit message could be destined
|
// But we can't really do that with a packed message, since each edit message could be destined
|
||||||
// for a different server... So we need to actually manage multiple queued packets... one
|
// for a different server... So we need to actually manage multiple queued packets... one
|
||||||
// for each server
|
// for each server
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
// only send to the NodeTypes that are getMyNodeType()
|
// only send to the NodeTypes that are getMyNodeType()
|
||||||
if (node->getActiveSocket() != NULL && node->getType() == getMyNodeType()) {
|
if (node->getActiveSocket() != NULL && node->getType() == getMyNodeType()) {
|
||||||
QUuid nodeUUID = node->getUUID();
|
QUuid nodeUUID = node->getUUID();
|
||||||
bool isMyJurisdiction = true;
|
bool isMyJurisdiction = true;
|
||||||
|
|
||||||
if (_serverJurisdictions) {
|
if (_serverJurisdictions) {
|
||||||
// we need to get the jurisdiction for this
|
// we need to get the jurisdiction for this
|
||||||
// here we need to get the "pending packet" for this server
|
// here we need to get the "pending packet" for this server
|
||||||
if ((*_serverJurisdictions).find(nodeUUID) != (*_serverJurisdictions).end()) {
|
if ((*_serverJurisdictions).find(nodeUUID) != (*_serverJurisdictions).end()) {
|
||||||
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
|
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
|
||||||
|
@ -232,19 +236,19 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PACKET_TYPE type, unsigned c
|
||||||
if (isMyJurisdiction) {
|
if (isMyJurisdiction) {
|
||||||
EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeUUID];
|
EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeUUID];
|
||||||
packetBuffer._nodeUUID = nodeUUID;
|
packetBuffer._nodeUUID = nodeUUID;
|
||||||
|
|
||||||
// If we're switching type, then we send the last one and start over
|
// If we're switching type, then we send the last one and start over
|
||||||
if ((type != packetBuffer._currentType && packetBuffer._currentSize > 0) ||
|
if ((type != packetBuffer._currentType && packetBuffer._currentSize > 0) ||
|
||||||
(packetBuffer._currentSize + length >= _maxPacketSize)) {
|
(packetBuffer._currentSize + length >= _maxPacketSize)) {
|
||||||
releaseQueuedPacket(packetBuffer);
|
releaseQueuedPacket(packetBuffer);
|
||||||
initializePacket(packetBuffer, type);
|
initializePacket(packetBuffer, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the buffer is empty and not correctly initialized for our type...
|
// If the buffer is empty and not correctly initialized for our type...
|
||||||
if (type != packetBuffer._currentType && packetBuffer._currentSize == 0) {
|
if (type != packetBuffer._currentType && packetBuffer._currentSize == 0) {
|
||||||
initializePacket(packetBuffer, type);
|
initializePacket(packetBuffer, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is really the first time we know which server/node this particular edit message
|
// This is really the first time we know which server/node this particular edit message
|
||||||
// is going to, so we couldn't adjust for clock skew till now. But here's our chance.
|
// is going to, so we couldn't adjust for clock skew till now. But here's our chance.
|
||||||
// We call this virtual function that allows our specific type of EditPacketSender to
|
// We call this virtual function that allows our specific type of EditPacketSender to
|
||||||
|
@ -252,7 +256,7 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PACKET_TYPE type, unsigned c
|
||||||
if (node->getClockSkewUsec() != 0) {
|
if (node->getClockSkewUsec() != 0) {
|
||||||
adjustEditPacketForClockSkew(codeColorBuffer, length, node->getClockSkewUsec());
|
adjustEditPacketForClockSkew(codeColorBuffer, length, node->getClockSkewUsec());
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&packetBuffer._currentBuffer[packetBuffer._currentSize], codeColorBuffer, length);
|
memcpy(&packetBuffer._currentBuffer[packetBuffer._currentSize], codeColorBuffer, length);
|
||||||
packetBuffer._currentSize += length;
|
packetBuffer._currentSize += length;
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,23 +246,25 @@ void OctreeElement::auditChildren(const char* label) const {
|
||||||
|
|
||||||
const bool alwaysReport = false; // set this to true to get additional debugging
|
const bool alwaysReport = false; // set this to true to get additional debugging
|
||||||
if (alwaysReport || auditFailed) {
|
if (alwaysReport || auditFailed) {
|
||||||
qDebug("%s... auditChildren() %s <<<< \n", label, (auditFailed ? "FAILED" : "PASSED"));
|
qDebug("%s... auditChildren() %s <<<<", label, (auditFailed ? "FAILED" : "PASSED"));
|
||||||
qDebug(" _childrenExternal=%s\n", debug::valueOf(_childrenExternal));
|
qDebug(" _childrenExternal=%s", debug::valueOf(_childrenExternal));
|
||||||
qDebug(" childCount=%d\n", getChildCount());
|
qDebug(" childCount=%d", getChildCount());
|
||||||
qDebug(" _childBitmask=");
|
|
||||||
outputBits(_childBitmask);
|
QDebug bitOutput = qDebug().nospace();
|
||||||
|
bitOutput << " _childBitmask=";
|
||||||
|
outputBits(_childBitmask, bitOutput);
|
||||||
|
|
||||||
|
|
||||||
for (int childIndex = 0; childIndex < NUMBER_OF_CHILDREN; childIndex++) {
|
for (int childIndex = 0; childIndex < NUMBER_OF_CHILDREN; childIndex++) {
|
||||||
OctreeElement* testChildNew = getChildAtIndex(childIndex);
|
OctreeElement* testChildNew = getChildAtIndex(childIndex);
|
||||||
OctreeElement* testChildOld = _childrenArray[childIndex];
|
OctreeElement* testChildOld = _childrenArray[childIndex];
|
||||||
|
|
||||||
qDebug("child at index %d... testChildOld=%p testChildNew=%p %s \n",
|
qDebug("child at index %d... testChildOld=%p testChildNew=%p %s",
|
||||||
childIndex, testChildOld, testChildNew ,
|
childIndex, testChildOld, testChildNew ,
|
||||||
((testChildNew != testChildOld) ? " DOES NOT MATCH <<<< BAD <<<<" : " - OK ")
|
((testChildNew != testChildOld) ? " DOES NOT MATCH <<<< BAD <<<<" : " - OK ")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
qDebug("%s... auditChildren() <<<< DONE <<<< \n", label);
|
qDebug("%s... auditChildren() <<<< DONE <<<<", label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // def HAS_AUDIT_CHILDREN
|
#endif // def HAS_AUDIT_CHILDREN
|
||||||
|
@ -410,7 +412,8 @@ OctreeElement* OctreeElement::getChildAtIndex(int childIndex) const {
|
||||||
if (externalIndex < childCount && externalIndex >= 0) {
|
if (externalIndex < childCount && externalIndex >= 0) {
|
||||||
result = _children.external[externalIndex];
|
result = _children.external[externalIndex];
|
||||||
} else {
|
} else {
|
||||||
qDebug("getChildAtIndex() attempt to access external client out of bounds externalIndex=%d <<<<<<<<<< WARNING!!! \n",externalIndex);
|
qDebug("getChildAtIndex() attempt to access external client out of bounds externalIndex=%d <<<<<<<<<< WARNING!!!
|
||||||
|
",externalIndex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +423,7 @@ OctreeElement* OctreeElement::getChildAtIndex(int childIndex) const {
|
||||||
}
|
}
|
||||||
#ifdef HAS_AUDIT_CHILDREN
|
#ifdef HAS_AUDIT_CHILDREN
|
||||||
if (result != _childrenArray[childIndex]) {
|
if (result != _childrenArray[childIndex]) {
|
||||||
qDebug("getChildAtIndex() case:%s result<%p> != _childrenArray[childIndex]<%p> <<<<<<<<<< WARNING!!! \n",
|
qDebug("getChildAtIndex() case:%s result<%p> != _childrenArray[childIndex]<%p> <<<<<<<<<< WARNING!!!",
|
||||||
caseStr, result,_childrenArray[childIndex]);
|
caseStr, result,_childrenArray[childIndex]);
|
||||||
}
|
}
|
||||||
#endif // def HAS_AUDIT_CHILDREN
|
#endif // def HAS_AUDIT_CHILDREN
|
||||||
|
@ -1083,7 +1086,7 @@ void OctreeElement::setChildAtIndex(int childIndex, OctreeElement* child) {
|
||||||
_externalChildrenMemoryUsage += newChildCount * sizeof(OctreeElement*);
|
_externalChildrenMemoryUsage += newChildCount * sizeof(OctreeElement*);
|
||||||
} else {
|
} else {
|
||||||
//assert(false);
|
//assert(false);
|
||||||
qDebug("THIS SHOULD NOT HAPPEN previousChildCount == %d && newChildCount == %d\n",previousChildCount, newChildCount);
|
qDebug("THIS SHOULD NOT HAPPEN previousChildCount == %d && newChildCount == %d",previousChildCount, newChildCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if we could store these 4 children locally
|
// check to see if we could store these 4 children locally
|
||||||
|
@ -1123,7 +1126,7 @@ OctreeElement* OctreeElement::addChildAtIndex(int childIndex) {
|
||||||
bool OctreeElement::safeDeepDeleteChildAtIndex(int childIndex, int recursionCount) {
|
bool OctreeElement::safeDeepDeleteChildAtIndex(int childIndex, int recursionCount) {
|
||||||
bool deleteApproved = false;
|
bool deleteApproved = false;
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
qDebug() << "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!\n";
|
qDebug() << "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return deleteApproved;
|
return deleteApproved;
|
||||||
}
|
}
|
||||||
OctreeElement* childToDelete = getChildAtIndex(childIndex);
|
OctreeElement* childToDelete = getChildAtIndex(childIndex);
|
||||||
|
@ -1162,13 +1165,17 @@ void OctreeElement::printDebugDetails(const char* label) const {
|
||||||
setAtBit(childBits,i);
|
setAtBit(childBits,i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDebug elementDebug = qDebug().nospace();
|
||||||
|
|
||||||
qDebug("%s - Voxel at corner=(%f,%f,%f) size=%f\n isLeaf=%s isDirty=%s shouldRender=%s\n children=", label,
|
QString resultString;
|
||||||
_box.getCorner().x, _box.getCorner().y, _box.getCorner().z, _box.getScale(),
|
resultString.sprintf("%s - Voxel at corner=(%f,%f,%f) size=%f\n isLeaf=%s isDirty=%s shouldRender=%s\n children=", label,
|
||||||
debug::valueOf(isLeaf()), debug::valueOf(isDirty()), debug::valueOf(getShouldRender()));
|
_box.getCorner().x, _box.getCorner().y, _box.getCorner().z, _box.getScale(),
|
||||||
|
debug::valueOf(isLeaf()), debug::valueOf(isDirty()), debug::valueOf(getShouldRender()));
|
||||||
|
elementDebug << resultString;
|
||||||
|
|
||||||
outputBits(childBits, false);
|
outputBits(childBits, &elementDebug);
|
||||||
qDebug("\n octalCode=");
|
qDebug("octalCode=");
|
||||||
printOctalCode(getOctalCode());
|
printOctalCode(getOctalCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ bool OctreePersistThread::process() {
|
||||||
|
|
||||||
if (!_initialLoadComplete) {
|
if (!_initialLoadComplete) {
|
||||||
uint64_t loadStarted = usecTimestampNow();
|
uint64_t loadStarted = usecTimestampNow();
|
||||||
qDebug() << "loading Octrees from file: " << _filename << "...\n";
|
qDebug() << "loading Octrees from file: " << _filename << "...";
|
||||||
|
|
||||||
bool persistantFileRead;
|
bool persistantFileRead;
|
||||||
|
|
||||||
|
@ -42,20 +42,20 @@ bool OctreePersistThread::process() {
|
||||||
_loadTimeUSecs = loadDone - loadStarted;
|
_loadTimeUSecs = loadDone - loadStarted;
|
||||||
|
|
||||||
_tree->clearDirtyBit(); // the tree is clean since we just loaded it
|
_tree->clearDirtyBit(); // the tree is clean since we just loaded it
|
||||||
qDebug("DONE loading Octrees from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
|
qDebug("DONE loading Octrees from file... fileRead=%s", debug::valueOf(persistantFileRead));
|
||||||
|
|
||||||
unsigned long nodeCount = OctreeElement::getNodeCount();
|
unsigned long nodeCount = OctreeElement::getNodeCount();
|
||||||
unsigned long internalNodeCount = OctreeElement::getInternalNodeCount();
|
unsigned long internalNodeCount = OctreeElement::getInternalNodeCount();
|
||||||
unsigned long leafNodeCount = OctreeElement::getLeafNodeCount();
|
unsigned long leafNodeCount = OctreeElement::getLeafNodeCount();
|
||||||
qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
|
qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves", nodeCount, internalNodeCount, leafNodeCount);
|
||||||
|
|
||||||
double usecPerGet = (double)OctreeElement::getGetChildAtIndexTime() / (double)OctreeElement::getGetChildAtIndexCalls();
|
double usecPerGet = (double)OctreeElement::getGetChildAtIndexTime() / (double)OctreeElement::getGetChildAtIndexCalls();
|
||||||
qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls()
|
qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls()
|
||||||
<< " getChildAtIndexTime=" << OctreeElement::getGetChildAtIndexTime() << " perGet=" << usecPerGet << " \n";
|
<< " getChildAtIndexTime=" << OctreeElement::getGetChildAtIndexTime() << " perGet=" << usecPerGet;
|
||||||
|
|
||||||
double usecPerSet = (double)OctreeElement::getSetChildAtIndexTime() / (double)OctreeElement::getSetChildAtIndexCalls();
|
double usecPerSet = (double)OctreeElement::getSetChildAtIndexTime() / (double)OctreeElement::getSetChildAtIndexCalls();
|
||||||
qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls()
|
qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls()
|
||||||
<< " setChildAtIndexTime=" << OctreeElement::getSetChildAtIndexTime() << " perset=" << usecPerSet << " \n";
|
<< " setChildAtIndexTime=" << OctreeElement::getSetChildAtIndexTime() << " perset=" << usecPerSet;
|
||||||
|
|
||||||
_initialLoadComplete = true;
|
_initialLoadComplete = true;
|
||||||
_lastCheck = usecTimestampNow(); // we just loaded, no need to save again
|
_lastCheck = usecTimestampNow(); // we just loaded, no need to save again
|
||||||
|
@ -81,10 +81,10 @@ bool OctreePersistThread::process() {
|
||||||
// check the dirty bit and persist here...
|
// check the dirty bit and persist here...
|
||||||
_lastCheck = usecTimestampNow();
|
_lastCheck = usecTimestampNow();
|
||||||
if (_tree->isDirty()) {
|
if (_tree->isDirty()) {
|
||||||
qDebug() << "saving Octrees to file " << _filename << "...\n";
|
qDebug() << "saving Octrees to file " << _filename << "...";
|
||||||
_tree->writeToSVOFile(_filename.toLocal8Bit().constData());
|
_tree->writeToSVOFile(_filename.toLocal8Bit().constData());
|
||||||
_tree->clearDirtyBit(); // tree is clean after saving
|
_tree->clearDirtyBit(); // tree is clean after saving
|
||||||
qDebug("DONE saving Octrees to file...\n");
|
qDebug("DONE saving Octrees to file...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,13 +90,9 @@ void BoundingBox::explandToInclude(const BoundingBox& box) {
|
||||||
|
|
||||||
|
|
||||||
void BoundingBox::printDebugDetails(const char* label) const {
|
void BoundingBox::printDebugDetails(const char* label) const {
|
||||||
if (label) {
|
qDebug("%s _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]",
|
||||||
qDebug() << label;
|
(label ? label : "BoundingBox"),
|
||||||
} else {
|
debug::valueOf(_set), corner.x, corner.y, size.x, size.y, corner.x, corner.y, corner.x+size.x, corner.y+size.y);
|
||||||
qDebug("BoundingBox");
|
|
||||||
}
|
|
||||||
qDebug("\n _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]\n",
|
|
||||||
debug::valueOf(_set), corner.x, corner.y, size.x, size.y, corner.x, corner.y, corner.x+size.x, corner.y+size.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,10 +65,9 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Hifi
|
||||||
|
|
||||||
if (extraDebugging) {
|
if (extraDebugging) {
|
||||||
qDebug("OctreeRenderer::processDatagram() ... Got Packet Section"
|
qDebug("OctreeRenderer::processDatagram() ... Got Packet Section"
|
||||||
" color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"
|
" color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d",
|
||||||
"\n",
|
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
||||||
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
sequence, flightTime, packetLength, dataBytes);
|
||||||
sequence, flightTime, packetLength, dataBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int subsection = 1;
|
int subsection = 1;
|
||||||
|
@ -96,9 +95,10 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Hifi
|
||||||
if (extraDebugging) {
|
if (extraDebugging) {
|
||||||
qDebug("OctreeRenderer::processDatagram() ... Got Packet Section"
|
qDebug("OctreeRenderer::processDatagram() ... Got Packet Section"
|
||||||
" color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"
|
" color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"
|
||||||
" subsection:%d sectionLength:%d uncompressed:%d\n",
|
" subsection:%d sectionLength:%d uncompressed:%d",
|
||||||
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
||||||
sequence, flightTime, packetLength, dataBytes, subsection, sectionLength, packetData.getUncompressedSize());
|
sequence, flightTime, packetLength, dataBytes, subsection, sectionLength,
|
||||||
|
packetData.getUncompressedSize());
|
||||||
}
|
}
|
||||||
_tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);
|
_tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);
|
||||||
_tree->unlock();
|
_tree->unlock();
|
||||||
|
|
|
@ -624,52 +624,51 @@ int OctreeSceneStats::unpackFromMessage(unsigned char* sourceBuffer, int availab
|
||||||
|
|
||||||
|
|
||||||
void OctreeSceneStats::printDebugDetails() {
|
void OctreeSceneStats::printDebugDetails() {
|
||||||
qDebug("\n------------------------------\n");
|
qDebug("\n------------------------------");
|
||||||
qDebug("OctreeSceneStats:\n");
|
qDebug("OctreeSceneStats:");
|
||||||
qDebug(" start : %llu \n", (long long unsigned int)_start);
|
qDebug(" start : %llu", (long long unsigned int)_start);
|
||||||
qDebug(" end : %llu \n", (long long unsigned int)_end);
|
qDebug(" end : %llu", (long long unsigned int)_end);
|
||||||
qDebug(" elapsed : %llu \n", (long long unsigned int)_elapsed);
|
qDebug(" elapsed : %llu", (long long unsigned int)_elapsed);
|
||||||
qDebug(" encoding : %llu \n", (long long unsigned int)_totalEncodeTime);
|
qDebug(" encoding : %llu", (long long unsigned int)_totalEncodeTime);
|
||||||
qDebug("\n");
|
qDebug();
|
||||||
qDebug(" full scene: %s\n", debug::valueOf(_isFullScene));
|
qDebug(" full scene: %s", debug::valueOf(_isFullScene));
|
||||||
qDebug(" moving: %s\n", debug::valueOf(_isMoving));
|
qDebug(" moving: %s", debug::valueOf(_isMoving));
|
||||||
qDebug("\n");
|
qDebug();
|
||||||
qDebug(" packets: %d\n", _packets);
|
qDebug(" packets: %d", _packets);
|
||||||
qDebug(" bytes : %ld\n", _bytes);
|
qDebug(" bytes : %ld", _bytes);
|
||||||
qDebug("\n");
|
qDebug();
|
||||||
qDebug(" total elements : %lu\n", _totalElements );
|
qDebug(" total elements : %lu", _totalElements );
|
||||||
qDebug(" internal : %lu\n", _totalInternal );
|
qDebug(" internal : %lu", _totalInternal );
|
||||||
qDebug(" leaves : %lu\n", _totalLeaves );
|
qDebug(" leaves : %lu", _totalLeaves );
|
||||||
qDebug(" traversed : %lu\n", _traversed );
|
qDebug(" traversed : %lu", _traversed );
|
||||||
qDebug(" internal : %lu\n", _internal );
|
qDebug(" internal : %lu", _internal );
|
||||||
qDebug(" leaves : %lu\n", _leaves );
|
qDebug(" leaves : %lu", _leaves );
|
||||||
qDebug(" skipped distance : %lu\n", _skippedDistance );
|
qDebug(" skipped distance : %lu", _skippedDistance );
|
||||||
qDebug(" internal : %lu\n", _internalSkippedDistance );
|
qDebug(" internal : %lu", _internalSkippedDistance );
|
||||||
qDebug(" leaves : %lu\n", _leavesSkippedDistance );
|
qDebug(" leaves : %lu", _leavesSkippedDistance );
|
||||||
qDebug(" skipped out of view : %lu\n", _skippedOutOfView );
|
qDebug(" skipped out of view : %lu", _skippedOutOfView );
|
||||||
qDebug(" internal : %lu\n", _internalSkippedOutOfView );
|
qDebug(" internal : %lu", _internalSkippedOutOfView );
|
||||||
qDebug(" leaves : %lu\n", _leavesSkippedOutOfView );
|
qDebug(" leaves : %lu", _leavesSkippedOutOfView );
|
||||||
qDebug(" skipped was in view : %lu\n", _skippedWasInView );
|
qDebug(" skipped was in view : %lu", _skippedWasInView );
|
||||||
qDebug(" internal : %lu\n", _internalSkippedWasInView );
|
qDebug(" internal : %lu", _internalSkippedWasInView );
|
||||||
qDebug(" leaves : %lu\n", _leavesSkippedWasInView );
|
qDebug(" leaves : %lu", _leavesSkippedWasInView );
|
||||||
qDebug(" skipped no change : %lu\n", _skippedNoChange );
|
qDebug(" skipped no change : %lu", _skippedNoChange );
|
||||||
qDebug(" internal : %lu\n", _internalSkippedNoChange );
|
qDebug(" internal : %lu", _internalSkippedNoChange );
|
||||||
qDebug(" leaves : %lu\n", _leavesSkippedNoChange );
|
qDebug(" leaves : %lu", _leavesSkippedNoChange );
|
||||||
qDebug(" skipped occluded : %lu\n", _skippedOccluded );
|
qDebug(" skipped occluded : %lu", _skippedOccluded );
|
||||||
qDebug(" internal : %lu\n", _internalSkippedOccluded );
|
qDebug(" internal : %lu", _internalSkippedOccluded );
|
||||||
qDebug(" leaves : %lu\n", _leavesSkippedOccluded );
|
qDebug(" leaves : %lu", _leavesSkippedOccluded );
|
||||||
|
qDebug();
|
||||||
qDebug("\n");
|
qDebug(" color sent : %lu", _colorSent );
|
||||||
qDebug(" color sent : %lu\n", _colorSent );
|
qDebug(" internal : %lu", _internalColorSent );
|
||||||
qDebug(" internal : %lu\n", _internalColorSent );
|
qDebug(" leaves : %lu", _leavesColorSent );
|
||||||
qDebug(" leaves : %lu\n", _leavesColorSent );
|
qDebug(" Didn't Fit : %lu", _didntFit );
|
||||||
qDebug(" Didn't Fit : %lu\n", _didntFit );
|
qDebug(" internal : %lu", _internalDidntFit );
|
||||||
qDebug(" internal : %lu\n", _internalDidntFit );
|
qDebug(" leaves : %lu", _leavesDidntFit );
|
||||||
qDebug(" leaves : %lu\n", _leavesDidntFit );
|
qDebug(" color bits : %lu", _colorBitsWritten );
|
||||||
qDebug(" color bits : %lu\n", _colorBitsWritten );
|
qDebug(" exists bits : %lu", _existsBitsWritten );
|
||||||
qDebug(" exists bits : %lu\n", _existsBitsWritten );
|
qDebug(" in packet bit : %lu", _existsInPacketBitsWritten);
|
||||||
qDebug(" in packet bit : %lu\n", _existsInPacketBitsWritten);
|
qDebug(" trees removed : %lu", _treesRemoved );
|
||||||
qDebug(" trees removed : %lu\n", _treesRemoved );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OctreeSceneStats::ItemInfo OctreeSceneStats::_ITEMS[] = {
|
OctreeSceneStats::ItemInfo OctreeSceneStats::_ITEMS[] = {
|
||||||
|
|
|
@ -326,43 +326,43 @@ bool ViewFrustum::matches(const ViewFrustum& compareTo, bool debug) const {
|
||||||
testMatches(compareTo._eyeOffsetOrientation, _eyeOffsetOrientation);
|
testMatches(compareTo._eyeOffsetOrientation, _eyeOffsetOrientation);
|
||||||
|
|
||||||
if (!result && debug) {
|
if (!result && debug) {
|
||||||
qDebug("ViewFrustum::matches()... result=%s\n", debug::valueOf(result));
|
qDebug("ViewFrustum::matches()... result=%s", debug::valueOf(result));
|
||||||
qDebug("%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f\n",
|
qDebug("%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f",
|
||||||
(testMatches(compareTo._position,_position) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._position,_position) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._position.x, compareTo._position.y, compareTo._position.z,
|
compareTo._position.x, compareTo._position.y, compareTo._position.z,
|
||||||
_position.x, _position.y, _position.z );
|
_position.x, _position.y, _position.z );
|
||||||
qDebug("%s -- compareTo._direction=%f,%f,%f _direction=%f,%f,%f\n",
|
qDebug("%s -- compareTo._direction=%f,%f,%f _direction=%f,%f,%f",
|
||||||
(testMatches(compareTo._direction, _direction) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._direction, _direction) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._direction.x, compareTo._direction.y, compareTo._direction.z,
|
compareTo._direction.x, compareTo._direction.y, compareTo._direction.z,
|
||||||
_direction.x, _direction.y, _direction.z );
|
_direction.x, _direction.y, _direction.z );
|
||||||
qDebug("%s -- compareTo._up=%f,%f,%f _up=%f,%f,%f\n",
|
qDebug("%s -- compareTo._up=%f,%f,%f _up=%f,%f,%f",
|
||||||
(testMatches(compareTo._up, _up) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._up, _up) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._up.x, compareTo._up.y, compareTo._up.z,
|
compareTo._up.x, compareTo._up.y, compareTo._up.z,
|
||||||
_up.x, _up.y, _up.z );
|
_up.x, _up.y, _up.z );
|
||||||
qDebug("%s -- compareTo._right=%f,%f,%f _right=%f,%f,%f\n",
|
qDebug("%s -- compareTo._right=%f,%f,%f _right=%f,%f,%f",
|
||||||
(testMatches(compareTo._right, _right) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._right, _right) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._right.x, compareTo._right.y, compareTo._right.z,
|
compareTo._right.x, compareTo._right.y, compareTo._right.z,
|
||||||
_right.x, _right.y, _right.z );
|
_right.x, _right.y, _right.z );
|
||||||
qDebug("%s -- compareTo._fieldOfView=%f _fieldOfView=%f\n",
|
qDebug("%s -- compareTo._fieldOfView=%f _fieldOfView=%f",
|
||||||
(testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._fieldOfView, _fieldOfView);
|
compareTo._fieldOfView, _fieldOfView);
|
||||||
qDebug("%s -- compareTo._aspectRatio=%f _aspectRatio=%f\n",
|
qDebug("%s -- compareTo._aspectRatio=%f _aspectRatio=%f",
|
||||||
(testMatches(compareTo._aspectRatio, _aspectRatio) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._aspectRatio, _aspectRatio) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._aspectRatio, _aspectRatio);
|
compareTo._aspectRatio, _aspectRatio);
|
||||||
qDebug("%s -- compareTo._nearClip=%f _nearClip=%f\n",
|
qDebug("%s -- compareTo._nearClip=%f _nearClip=%f",
|
||||||
(testMatches(compareTo._nearClip, _nearClip) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._nearClip, _nearClip) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._nearClip, _nearClip);
|
compareTo._nearClip, _nearClip);
|
||||||
qDebug("%s -- compareTo._farClip=%f _farClip=%f\n",
|
qDebug("%s -- compareTo._farClip=%f _farClip=%f",
|
||||||
(testMatches(compareTo._farClip, _farClip) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._farClip, _farClip) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._farClip, _farClip);
|
compareTo._farClip, _farClip);
|
||||||
qDebug("%s -- compareTo._focalLength=%f _focalLength=%f\n",
|
qDebug("%s -- compareTo._focalLength=%f _focalLength=%f",
|
||||||
(testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._focalLength, _focalLength);
|
compareTo._focalLength, _focalLength);
|
||||||
qDebug("%s -- compareTo._eyeOffsetPosition=%f,%f,%f _eyeOffsetPosition=%f,%f,%f\n",
|
qDebug("%s -- compareTo._eyeOffsetPosition=%f,%f,%f _eyeOffsetPosition=%f,%f,%f",
|
||||||
(testMatches(compareTo._eyeOffsetPosition, _eyeOffsetPosition) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._eyeOffsetPosition, _eyeOffsetPosition) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._eyeOffsetPosition.x, compareTo._eyeOffsetPosition.y, compareTo._eyeOffsetPosition.z,
|
compareTo._eyeOffsetPosition.x, compareTo._eyeOffsetPosition.y, compareTo._eyeOffsetPosition.z,
|
||||||
_eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z);
|
_eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z);
|
||||||
qDebug("%s -- compareTo._eyeOffsetOrientation=%f,%f,%f,%f _eyeOffsetOrientation=%f,%f,%f,%f\n",
|
qDebug("%s -- compareTo._eyeOffsetOrientation=%f,%f,%f,%f _eyeOffsetOrientation=%f,%f,%f,%f",
|
||||||
(testMatches(compareTo._eyeOffsetOrientation, _eyeOffsetOrientation) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._eyeOffsetOrientation, _eyeOffsetOrientation) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._eyeOffsetOrientation.x, compareTo._eyeOffsetOrientation.y,
|
compareTo._eyeOffsetOrientation.x, compareTo._eyeOffsetOrientation.y,
|
||||||
compareTo._eyeOffsetOrientation.z, compareTo._eyeOffsetOrientation.w,
|
compareTo._eyeOffsetOrientation.z, compareTo._eyeOffsetOrientation.w,
|
||||||
|
@ -413,45 +413,45 @@ bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const
|
||||||
|
|
||||||
if (!result && debug) {
|
if (!result && debug) {
|
||||||
qDebug("ViewFrustum::isVerySimilar()... result=%s\n", debug::valueOf(result));
|
qDebug("ViewFrustum::isVerySimilar()... result=%s\n", debug::valueOf(result));
|
||||||
qDebug("%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f\n",
|
qDebug("%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f",
|
||||||
(testMatches(compareTo._position,_position, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
(testMatches(compareTo._position,_position, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||||
compareTo._position.x, compareTo._position.y, compareTo._position.z,
|
compareTo._position.x, compareTo._position.y, compareTo._position.z,
|
||||||
_position.x, _position.y, _position.z );
|
_position.x, _position.y, _position.z );
|
||||||
|
|
||||||
qDebug("%s -- positionDistance=%f\n",
|
qDebug("%s -- positionDistance=%f",
|
||||||
(testMatches(0,positionDistance, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
(testMatches(0,positionDistance, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||||
positionDistance);
|
positionDistance);
|
||||||
|
|
||||||
qDebug("%s -- angleOrientation=%f\n",
|
qDebug("%s -- angleOrientation=%f",
|
||||||
(testMatches(0, angleOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
(testMatches(0, angleOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||||
angleOrientation);
|
angleOrientation);
|
||||||
|
|
||||||
qDebug("%s -- compareTo._fieldOfView=%f _fieldOfView=%f\n",
|
qDebug("%s -- compareTo._fieldOfView=%f _fieldOfView=%f",
|
||||||
(testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._fieldOfView, _fieldOfView);
|
compareTo._fieldOfView, _fieldOfView);
|
||||||
qDebug("%s -- compareTo._aspectRatio=%f _aspectRatio=%f\n",
|
qDebug("%s -- compareTo._aspectRatio=%f _aspectRatio=%f",
|
||||||
(testMatches(compareTo._aspectRatio, _aspectRatio) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._aspectRatio, _aspectRatio) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._aspectRatio, _aspectRatio);
|
compareTo._aspectRatio, _aspectRatio);
|
||||||
qDebug("%s -- compareTo._nearClip=%f _nearClip=%f\n",
|
qDebug("%s -- compareTo._nearClip=%f _nearClip=%f",
|
||||||
(testMatches(compareTo._nearClip, _nearClip) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._nearClip, _nearClip) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._nearClip, _nearClip);
|
compareTo._nearClip, _nearClip);
|
||||||
qDebug("%s -- compareTo._farClip=%f _farClip=%f\n",
|
qDebug("%s -- compareTo._farClip=%f _farClip=%f",
|
||||||
(testMatches(compareTo._farClip, _farClip) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._farClip, _farClip) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._farClip, _farClip);
|
compareTo._farClip, _farClip);
|
||||||
qDebug("%s -- compareTo._focalLength=%f _focalLength=%f\n",
|
qDebug("%s -- compareTo._focalLength=%f _focalLength=%f",
|
||||||
(testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"),
|
(testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"),
|
||||||
compareTo._focalLength, _focalLength);
|
compareTo._focalLength, _focalLength);
|
||||||
|
|
||||||
qDebug("%s -- compareTo._eyeOffsetPosition=%f,%f,%f _eyeOffsetPosition=%f,%f,%f\n",
|
qDebug("%s -- compareTo._eyeOffsetPosition=%f,%f,%f _eyeOffsetPosition=%f,%f,%f",
|
||||||
(testMatches(compareTo._eyeOffsetPosition, _eyeOffsetPosition, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
(testMatches(compareTo._eyeOffsetPosition, _eyeOffsetPosition, POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||||
compareTo._eyeOffsetPosition.x, compareTo._eyeOffsetPosition.y, compareTo._eyeOffsetPosition.z,
|
compareTo._eyeOffsetPosition.x, compareTo._eyeOffsetPosition.y, compareTo._eyeOffsetPosition.z,
|
||||||
_eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z);
|
_eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z);
|
||||||
|
|
||||||
qDebug("%s -- eyeOffsetpositionDistance=%f\n",
|
qDebug("%s -- eyeOffsetpositionDistance=%f",
|
||||||
(testMatches(0,eyeOffsetpositionDistance, EYEOFFSET_POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
(testMatches(0,eyeOffsetpositionDistance, EYEOFFSET_POSITION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||||
eyeOffsetpositionDistance);
|
eyeOffsetpositionDistance);
|
||||||
|
|
||||||
qDebug("%s -- angleEyeOffsetOrientation=%f\n",
|
qDebug("%s -- angleEyeOffsetOrientation=%f",
|
||||||
(testMatches(0, angleEyeOffsetOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
(testMatches(0, angleEyeOffsetOrientation, ORIENTATION_SIMILAR_ENOUGH) ? "IS SIMILAR ENOUGH " : "IS NOT SIMILAR ENOUGH"),
|
||||||
angleEyeOffsetOrientation);
|
angleEyeOffsetOrientation);
|
||||||
}
|
}
|
||||||
|
@ -518,19 +518,19 @@ void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewFrustum::printDebugDetails() const {
|
void ViewFrustum::printDebugDetails() const {
|
||||||
qDebug("ViewFrustum::printDebugDetails()... \n");
|
qDebug("ViewFrustum::printDebugDetails()...");
|
||||||
qDebug("_position=%f,%f,%f\n", _position.x, _position.y, _position.z );
|
qDebug("_position=%f,%f,%f", _position.x, _position.y, _position.z );
|
||||||
qDebug("_direction=%f,%f,%f\n", _direction.x, _direction.y, _direction.z );
|
qDebug("_direction=%f,%f,%f", _direction.x, _direction.y, _direction.z );
|
||||||
qDebug("_up=%f,%f,%f\n", _up.x, _up.y, _up.z );
|
qDebug("_up=%f,%f,%f", _up.x, _up.y, _up.z );
|
||||||
qDebug("_right=%f,%f,%f\n", _right.x, _right.y, _right.z );
|
qDebug("_right=%f,%f,%f", _right.x, _right.y, _right.z );
|
||||||
qDebug("_fieldOfView=%f\n", _fieldOfView);
|
qDebug("_fieldOfView=%f", _fieldOfView);
|
||||||
qDebug("_aspectRatio=%f\n", _aspectRatio);
|
qDebug("_aspectRatio=%f", _aspectRatio);
|
||||||
qDebug("_keyHoleRadius=%f\n", _keyholeRadius);
|
qDebug("_keyHoleRadius=%f", _keyholeRadius);
|
||||||
qDebug("_nearClip=%f\n", _nearClip);
|
qDebug("_nearClip=%f", _nearClip);
|
||||||
qDebug("_farClip=%f\n", _farClip);
|
qDebug("_farClip=%f", _farClip);
|
||||||
qDebug("_focalLength=%f\n", _focalLength);
|
qDebug("_focalLength=%f", _focalLength);
|
||||||
qDebug("_eyeOffsetPosition=%f,%f,%f\n", _eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z );
|
qDebug("_eyeOffsetPosition=%f,%f,%f", _eyeOffsetPosition.x, _eyeOffsetPosition.y, _eyeOffsetPosition.z );
|
||||||
qDebug("_eyeOffsetOrientation=%f,%f,%f,%f\n", _eyeOffsetOrientation.x, _eyeOffsetOrientation.y, _eyeOffsetOrientation.z,
|
qDebug("_eyeOffsetOrientation=%f,%f,%f,%f", _eyeOffsetOrientation.x, _eyeOffsetOrientation.y, _eyeOffsetOrientation.z,
|
||||||
_eyeOffsetOrientation.w );
|
_eyeOffsetOrientation.w );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -467,10 +467,10 @@ void Particle::adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssiz
|
||||||
memcpy(dataAt, &lastEditedInServerTime, sizeof(lastEditedInServerTime));
|
memcpy(dataAt, &lastEditedInServerTime, sizeof(lastEditedInServerTime));
|
||||||
const bool wantDebug = false;
|
const bool wantDebug = false;
|
||||||
if (wantDebug) {
|
if (wantDebug) {
|
||||||
qDebug("Particle::adjustEditPacketForClockSkew()...\n");
|
qDebug("Particle::adjustEditPacketForClockSkew()...");
|
||||||
qDebug() << " lastEditedInLocalTime: " << lastEditedInLocalTime << "\n";
|
qDebug() << " lastEditedInLocalTime: " << lastEditedInLocalTime;
|
||||||
qDebug() << " clockSkew: " << clockSkew << "\n";
|
qDebug() << " clockSkew: " << clockSkew;
|
||||||
qDebug() << " lastEditedInServerTime: " << lastEditedInServerTime << "\n";
|
qDebug() << " lastEditedInServerTime: " << lastEditedInServerTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,22 +187,22 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop through all the other avatars for potential interactions...
|
// loop through all the other avatars for potential interactions...
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
//qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n";
|
//qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n";
|
||||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||||
// TODO: dot collidingPalm and hand velocities and skip collision when they are moving apart.
|
// TODO: dot collidingPalm and hand velocities and skip collision when they are moving apart.
|
||||||
AvatarData* avatar = static_cast<AvatarData*>(node->getLinkedData());
|
AvatarData* avatar = static_cast<AvatarData*>(node->getLinkedData());
|
||||||
//printf("updateCollisionWithAvatars()...avatar=%p\n", avatar);
|
//printf("updateCollisionWithAvatars()...avatar=%p\n", avatar);
|
||||||
|
|
||||||
// check hands...
|
// check hands...
|
||||||
const HandData* handData = avatar->getHandData();
|
const HandData* handData = avatar->getHandData();
|
||||||
|
|
||||||
if (handData->findSpherePenetration(center, radius, penetration, collidingPalm)) {
|
if (handData->findSpherePenetration(center, radius, penetration, collidingPalm)) {
|
||||||
// apply a hard collision when ball collides with hand
|
// apply a hard collision when ball collides with hand
|
||||||
penetration /= (float)(TREE_SCALE);
|
penetration /= (float)(TREE_SCALE);
|
||||||
updateCollisionSound(particle, penetration, COLLISION_FREQUENCY);
|
updateCollisionSound(particle, penetration, COLLISION_FREQUENCY);
|
||||||
|
|
||||||
// determine if the palm that collided was moving, if so, then we add that palm velocity as well...
|
// determine if the palm that collided was moving, if so, then we add that palm velocity as well...
|
||||||
glm::vec3 addedVelocity = NO_ADDED_VELOCITY;
|
glm::vec3 addedVelocity = NO_ADDED_VELOCITY;
|
||||||
if (collidingPalm) {
|
if (collidingPalm) {
|
||||||
|
@ -210,9 +210,9 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
||||||
//printf("collidingPalm Velocity=%f,%f,%f\n", palmVelocity.x, palmVelocity.y, palmVelocity.z);
|
//printf("collidingPalm Velocity=%f,%f,%f\n", palmVelocity.x, palmVelocity.y, palmVelocity.z);
|
||||||
addedVelocity = palmVelocity;
|
addedVelocity = palmVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyHardCollision(particle, penetration, ELASTICITY, DAMPING, addedVelocity);
|
applyHardCollision(particle, penetration, ELASTICITY, DAMPING, addedVelocity);
|
||||||
|
|
||||||
} else if (avatar->findSpherePenetration(center, radius, penetration)) {
|
} else if (avatar->findSpherePenetration(center, radius, penetration)) {
|
||||||
penetration /= (float)(TREE_SCALE);
|
penetration /= (float)(TREE_SCALE);
|
||||||
updateCollisionSound(particle, penetration, COLLISION_FREQUENCY);
|
updateCollisionSound(particle, penetration, COLLISION_FREQUENCY);
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
#include <GeometryUtil.h>
|
#include <GeometryUtil.h>
|
||||||
|
|
||||||
#include "ParticleTree.h"
|
#include "ParticleTree.h"
|
||||||
|
|
|
@ -145,11 +145,11 @@ void ScriptEngine::evaluate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue result = _engine.evaluate(_scriptContents);
|
QScriptValue result = _engine.evaluate(_scriptContents);
|
||||||
qDebug() << "Evaluated script.\n";
|
qDebug("Evaluated script.");
|
||||||
|
|
||||||
if (_engine.hasUncaughtException()) {
|
if (_engine.hasUncaughtException()) {
|
||||||
int line = _engine.uncaughtExceptionLineNumber();
|
int line = _engine.uncaughtExceptionLineNumber();
|
||||||
qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n";
|
qDebug() << "Uncaught exception at line" << line << ":" << result.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,11 +160,11 @@ void ScriptEngine::run() {
|
||||||
_isRunning = true;
|
_isRunning = true;
|
||||||
|
|
||||||
QScriptValue result = _engine.evaluate(_scriptContents);
|
QScriptValue result = _engine.evaluate(_scriptContents);
|
||||||
qDebug() << "Evaluated script.\n";
|
qDebug("Evaluated script");
|
||||||
|
|
||||||
if (_engine.hasUncaughtException()) {
|
if (_engine.hasUncaughtException()) {
|
||||||
int line = _engine.uncaughtExceptionLineNumber();
|
int line = _engine.uncaughtExceptionLineNumber();
|
||||||
qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n";
|
qDebug() << "Uncaught exception at line" << line << ":" << result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
timeval startTime;
|
timeval startTime;
|
||||||
|
@ -221,7 +221,7 @@ void ScriptEngine::run() {
|
||||||
|
|
||||||
if (_engine.hasUncaughtException()) {
|
if (_engine.hasUncaughtException()) {
|
||||||
int line = _engine.uncaughtExceptionLineNumber();
|
int line = _engine.uncaughtExceptionLineNumber();
|
||||||
qDebug() << "Uncaught exception at line" << line << ":" << _engine.uncaughtException().toString() << "\n";
|
qDebug() << "Uncaught exception at line" << line << ":" << _engine.uncaughtException().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanMenuItems();
|
cleanMenuItems();
|
||||||
|
|
|
@ -149,7 +149,7 @@ void Assignment::swap(Assignment& otherAssignment) {
|
||||||
void Assignment::setPayload(const uchar* payload, int numBytes) {
|
void Assignment::setPayload(const uchar* payload, int numBytes) {
|
||||||
|
|
||||||
if (numBytes > MAX_PAYLOAD_BYTES) {
|
if (numBytes > MAX_PAYLOAD_BYTES) {
|
||||||
qDebug("Set payload called with number of bytes greater than maximum (%d). Will only transfer %d bytes.\n",
|
qDebug("Set payload called with number of bytes greater than maximum (%d). Will only transfer %d bytes.",
|
||||||
MAX_PAYLOAD_BYTES,
|
MAX_PAYLOAD_BYTES,
|
||||||
MAX_PAYLOAD_BYTES);
|
MAX_PAYLOAD_BYTES);
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
#include "GeometryUtil.h"
|
#include "GeometryUtil.h"
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ quint32 getHostOrderLocalAddress() {
|
||||||
foreach(const QNetworkAddressEntry &entry, interface.addressEntries()) {
|
foreach(const QNetworkAddressEntry &entry, interface.addressEntries()) {
|
||||||
// make sure it's an IPv4 address that isn't the loopback
|
// make sure it's an IPv4 address that isn't the loopback
|
||||||
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) {
|
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) {
|
||||||
qDebug("Node's local address is %s\n", entry.ip().toString().toLocal8Bit().constData());
|
qDebug("Node's local address is %s", entry.ip().toString().toLocal8Bit().constData());
|
||||||
|
|
||||||
// set our localAddress and break out
|
// set our localAddress and break out
|
||||||
localAddress = entry.ip().toIPv4Address();
|
localAddress = entry.ip().toIPv4Address();
|
||||||
|
|
|
@ -117,5 +117,5 @@ void Logging::verboseMessageHandler(QtMsgType type, const QMessageLogContext& co
|
||||||
prefixString.append(QString(" [%1]").arg(Logging::targetName));
|
prefixString.append(QString(" [%1]").arg(Logging::targetName));
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "%s %s", prefixString.toLocal8Bit().constData(), message.toLocal8Bit().constData());
|
fprintf(stdout, "%s %s\n", prefixString.toLocal8Bit().constData(), message.toLocal8Bit().constData());
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@ void NetworkPacket::copyContents(const HifiSockAddr& sockAddr, const unsigned ch
|
||||||
_packetLength = packetLength;
|
_packetLength = packetLength;
|
||||||
memcpy(&_packetData[0], packetData, packetLength);
|
memcpy(&_packetData[0], packetData, packetLength);
|
||||||
} else {
|
} else {
|
||||||
qDebug(">>> NetworkPacket::copyContents() unexpected length=%lu\n",packetLength);
|
qDebug(">>> NetworkPacket::copyContents() unexpected length=%lu",packetLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,10 @@ Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const
|
||||||
_bytesReceivedMovingAverage(NULL),
|
_bytesReceivedMovingAverage(NULL),
|
||||||
_linkedData(NULL),
|
_linkedData(NULL),
|
||||||
_isAlive(true),
|
_isAlive(true),
|
||||||
_clockSkewUsec(0)
|
_clockSkewUsec(0),
|
||||||
|
_mutex()
|
||||||
{
|
{
|
||||||
pthread_mutex_init(&_mutex, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::~Node() {
|
Node::~Node() {
|
||||||
|
@ -44,8 +45,6 @@ Node::~Node() {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete _bytesReceivedMovingAverage;
|
delete _bytesReceivedMovingAverage;
|
||||||
|
|
||||||
pthread_mutex_destroy(&_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Names of Node Types
|
// Names of Node Types
|
||||||
|
@ -107,12 +106,12 @@ void Node::setLocalSocket(const HifiSockAddr& localSocket) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::activateLocalSocket() {
|
void Node::activateLocalSocket() {
|
||||||
qDebug() << "Activating local socket for node" << *this << "\n";
|
qDebug() << "Activating local socket for node" << *this;
|
||||||
_activeSocket = &_localSocket;
|
_activeSocket = &_localSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::activatePublicSocket() {
|
void Node::activatePublicSocket() {
|
||||||
qDebug() << "Activating public socket for node" << *this << "\n";
|
qDebug() << "Activating public socket for node" << *this;
|
||||||
_activeSocket = &_publicSocket;
|
_activeSocket = &_publicSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,15 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QMutex>
|
||||||
#include <QtCore/QUuid>
|
#include <QtCore/QUuid>
|
||||||
|
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
#include "NodeData.h"
|
#include "NodeData.h"
|
||||||
#include "SimpleMovingAverage.h"
|
#include "SimpleMovingAverage.h"
|
||||||
|
|
||||||
class Node {
|
class Node : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||||
~Node();
|
~Node();
|
||||||
|
@ -72,13 +74,7 @@ public:
|
||||||
int getClockSkewUsec() const { return _clockSkewUsec; }
|
int getClockSkewUsec() const { return _clockSkewUsec; }
|
||||||
void setClockSkewUsec(int clockSkew) { _clockSkewUsec = clockSkew; }
|
void setClockSkewUsec(int clockSkew) { _clockSkewUsec = clockSkew; }
|
||||||
|
|
||||||
void lock() { pthread_mutex_lock(&_mutex); }
|
QMutex& getMutex() { return _mutex; }
|
||||||
|
|
||||||
/// returns false if lock failed, true if you got the lock
|
|
||||||
bool trylock() { return (pthread_mutex_trylock(&_mutex) == 0); }
|
|
||||||
void unlock() { pthread_mutex_unlock(&_mutex); }
|
|
||||||
|
|
||||||
static void printLog(Node const&);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// privatize copy and assignment operator to disallow Node copying
|
// privatize copy and assignment operator to disallow Node copying
|
||||||
|
@ -97,12 +93,9 @@ private:
|
||||||
bool _isAlive;
|
bool _isAlive;
|
||||||
int _pingMs;
|
int _pingMs;
|
||||||
int _clockSkewUsec;
|
int _clockSkewUsec;
|
||||||
pthread_mutex_t _mutex;
|
QMutex _mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
int unpackNodeId(unsigned char *packedData, uint16_t *nodeId);
|
|
||||||
int packNodeId(unsigned char *packStore, uint16_t nodeId);
|
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const Node &message);
|
QDebug operator<<(QDebug debug, const Node &message);
|
||||||
|
|
||||||
#endif /* defined(__hifi__Node__) */
|
#endif /* defined(__hifi__Node__) */
|
||||||
|
|
|
@ -36,6 +36,9 @@ NodeList* NodeList::_sharedInstance = NULL;
|
||||||
NodeList* NodeList::createInstance(char ownerType, unsigned short int socketListenPort) {
|
NodeList* NodeList::createInstance(char ownerType, unsigned short int socketListenPort) {
|
||||||
if (!_sharedInstance) {
|
if (!_sharedInstance) {
|
||||||
_sharedInstance = new NodeList(ownerType, socketListenPort);
|
_sharedInstance = new NodeList(ownerType, socketListenPort);
|
||||||
|
|
||||||
|
// register the SharedNodePointer meta-type for signals/slots
|
||||||
|
qRegisterMetaType<SharedNodePointer>();
|
||||||
} else {
|
} else {
|
||||||
qDebug("NodeList createInstance called with existing instance.");
|
qDebug("NodeList createInstance called with existing instance.");
|
||||||
}
|
}
|
||||||
|
@ -52,10 +55,9 @@ NodeList* NodeList::getInstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
|
NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
|
||||||
|
_nodeHash(),
|
||||||
_domainHostname(DEFAULT_DOMAIN_HOSTNAME),
|
_domainHostname(DEFAULT_DOMAIN_HOSTNAME),
|
||||||
_domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
_domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
||||||
_nodeBuckets(),
|
|
||||||
_numNodes(0),
|
|
||||||
_nodeSocket(),
|
_nodeSocket(),
|
||||||
_ownerType(newOwnerType),
|
_ownerType(newOwnerType),
|
||||||
_nodeTypesOfInterest(NULL),
|
_nodeTypesOfInterest(NULL),
|
||||||
|
@ -67,7 +69,7 @@ NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
|
||||||
_stunRequestsSinceSuccess(0)
|
_stunRequestsSinceSuccess(0)
|
||||||
{
|
{
|
||||||
_nodeSocket.bind(QHostAddress::AnyIPv4, newSocketListenPort);
|
_nodeSocket.bind(QHostAddress::AnyIPv4, newSocketListenPort);
|
||||||
qDebug() << "NodeList socket is listening on" << _nodeSocket.localPort() << "\n";
|
qDebug() << "NodeList socket is listening on" << _nodeSocket.localPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList::~NodeList() {
|
NodeList::~NodeList() {
|
||||||
|
@ -90,7 +92,7 @@ void NodeList::setDomainHostname(const QString& domainHostname) {
|
||||||
// grab the port by reading the string after the colon
|
// grab the port by reading the string after the colon
|
||||||
_domainSockAddr.setPort(atoi(domainHostname.mid(colonIndex + 1, domainHostname.size()).toLocal8Bit().constData()));
|
_domainSockAddr.setPort(atoi(domainHostname.mid(colonIndex + 1, domainHostname.size()).toLocal8Bit().constData()));
|
||||||
|
|
||||||
qDebug() << "Updated hostname to" << _domainHostname << "and port to" << _domainSockAddr.getPort() << "\n";
|
qDebug() << "Updated hostname to" << _domainHostname << "and port to" << _domainSockAddr.getPort();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// no port included with the hostname, simply set the member variable and reset the domain server port to default
|
// no port included with the hostname, simply set the member variable and reset the domain server port to default
|
||||||
|
@ -103,15 +105,15 @@ void NodeList::setDomainHostname(const QString& domainHostname) {
|
||||||
|
|
||||||
// reset our _domainIP to the null address so that a lookup happens on next check in
|
// reset our _domainIP to the null address so that a lookup happens on next check in
|
||||||
_domainSockAddr.setAddress(QHostAddress::Null);
|
_domainSockAddr.setAddress(QHostAddress::Null);
|
||||||
notifyDomainChanged();
|
emit domainChanged(_domainHostname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData) {
|
void NodeList::timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData) {
|
||||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
foreach (const SharedNodePointer& node, _nodeHash) {
|
||||||
if (node->getPublicSocket() == nodeAddress ||
|
if (node->getPublicSocket() == nodeAddress ||
|
||||||
node->getLocalSocket() == nodeAddress) {
|
node->getLocalSocket() == nodeAddress) {
|
||||||
|
|
||||||
unsigned char* dataAt = packetData + numBytesForPacketHeader(packetData);
|
unsigned char* dataAt = packetData + numBytesForPacketHeader(packetData);
|
||||||
uint64_t ourOriginalTime = *(uint64_t*)(dataAt);
|
uint64_t ourOriginalTime = *(uint64_t*)(dataAt);
|
||||||
dataAt += sizeof(ourOriginalTime);
|
dataAt += sizeof(ourOriginalTime);
|
||||||
|
@ -129,7 +131,7 @@ void NodeList::timePingReply(const HifiSockAddr& nodeAddress, unsigned char *pac
|
||||||
node->setClockSkewUsec(clockSkew);
|
node->setClockSkewUsec(clockSkew);
|
||||||
|
|
||||||
const bool wantDebug = false;
|
const bool wantDebug = false;
|
||||||
if (wantDebug) {
|
if (wantDebug) {
|
||||||
qDebug() << "PING_REPLY from node " << *node << "\n" <<
|
qDebug() << "PING_REPLY from node " << *node << "\n" <<
|
||||||
" now: " << now << "\n" <<
|
" now: " << now << "\n" <<
|
||||||
" ourTime: " << ourOriginalTime << "\n" <<
|
" ourTime: " << ourOriginalTime << "\n" <<
|
||||||
|
@ -137,7 +139,7 @@ void NodeList::timePingReply(const HifiSockAddr& nodeAddress, unsigned char *pac
|
||||||
" oneWayFlightTime: " << oneWayFlightTime << "\n" <<
|
" oneWayFlightTime: " << oneWayFlightTime << "\n" <<
|
||||||
" othersReplyTime: " << othersReplyTime << "\n" <<
|
" othersReplyTime: " << othersReplyTime << "\n" <<
|
||||||
" othersExprectedReply: " << othersExprectedReply << "\n" <<
|
" othersExprectedReply: " << othersExprectedReply << "\n" <<
|
||||||
" clockSkew: " << clockSkew << "\n";
|
" clockSkew: " << clockSkew;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -184,10 +186,9 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, unsigned char
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned char *packetData, int numTotalBytes) {
|
void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned char *packetData, int numTotalBytes) {
|
||||||
|
SharedNodePointer bulkSendNode = nodeWithAddress(senderAddress);
|
||||||
|
|
||||||
// find the avatar mixer in our node list and update the lastRecvTime from it
|
// find the avatar mixer in our node list and update the lastRecvTime from it
|
||||||
Node* bulkSendNode = nodeWithAddress(senderAddress);
|
|
||||||
|
|
||||||
if (bulkSendNode) {
|
if (bulkSendNode) {
|
||||||
|
|
||||||
bulkSendNode->setLastHeardMicrostamp(usecTimestampNow());
|
bulkSendNode->setLastHeardMicrostamp(usecTimestampNow());
|
||||||
|
@ -209,14 +210,14 @@ void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned c
|
||||||
numTotalBytes - (currentPosition - startPosition));
|
numTotalBytes - (currentPosition - startPosition));
|
||||||
|
|
||||||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)currentPosition, NUM_BYTES_RFC4122_UUID));
|
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)currentPosition, NUM_BYTES_RFC4122_UUID));
|
||||||
Node* matchingNode = nodeWithUUID(nodeUUID);
|
SharedNodePointer matchingNode = nodeWithUUID(nodeUUID);
|
||||||
|
|
||||||
if (!matchingNode) {
|
if (!matchingNode) {
|
||||||
// we're missing this node, we need to add it to the list
|
// we're missing this node, we need to add it to the list
|
||||||
matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, HifiSockAddr(), HifiSockAddr());
|
matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, HifiSockAddr(), HifiSockAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
currentPosition += updateNodeWithData(matchingNode,
|
currentPosition += updateNodeWithData(matchingNode.data(),
|
||||||
HifiSockAddr(),
|
HifiSockAddr(),
|
||||||
packetHolder,
|
packetHolder,
|
||||||
numTotalBytes - (currentPosition - startPosition));
|
numTotalBytes - (currentPosition - startPosition));
|
||||||
|
@ -226,7 +227,7 @@ void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned c
|
||||||
}
|
}
|
||||||
|
|
||||||
int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes) {
|
int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes) {
|
||||||
node->lock();
|
QMutexLocker(&node->getMutex());
|
||||||
|
|
||||||
node->setLastHeardMicrostamp(usecTimestampNow());
|
node->setLastHeardMicrostamp(usecTimestampNow());
|
||||||
|
|
||||||
|
@ -243,63 +244,43 @@ int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr,
|
||||||
|
|
||||||
int numParsedBytes = node->getLinkedData()->parseData(packetData, dataBytes);
|
int numParsedBytes = node->getLinkedData()->parseData(packetData, dataBytes);
|
||||||
|
|
||||||
node->unlock();
|
|
||||||
|
|
||||||
return numParsedBytes;
|
return numParsedBytes;
|
||||||
} else {
|
} else {
|
||||||
// we weren't able to match the sender address to the address we have for this node, unlock and don't parse
|
// we weren't able to match the sender address to the address we have for this node, unlock and don't parse
|
||||||
node->unlock();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* NodeList::nodeWithAddress(const HifiSockAddr &senderSockAddr) {
|
SharedNodePointer NodeList::nodeWithAddress(const HifiSockAddr &senderSockAddr) {
|
||||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
// naively returns the first node that has a matching active HifiSockAddr
|
||||||
|
// note that there can be multiple nodes that have a matching active socket, so this isn't a good way to uniquely identify
|
||||||
|
foreach (const SharedNodePointer& node, _nodeHash) {
|
||||||
if (node->getActiveSocket() && *node->getActiveSocket() == senderSockAddr) {
|
if (node->getActiveSocket() && *node->getActiveSocket() == senderSockAddr) {
|
||||||
return &(*node);
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return SharedNodePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* NodeList::nodeWithUUID(const QUuid& nodeUUID) {
|
SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID) {
|
||||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
QHash<QUuid, QSharedPointer<Node> >::const_iterator foundIterator = _nodeHash.find(nodeUUID);
|
||||||
if (node->getUUID() == nodeUUID) {
|
if (foundIterator != _nodeHash.end()) {
|
||||||
return &(*node);
|
return foundIterator.value();
|
||||||
}
|
} else {
|
||||||
|
return SharedNodePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NodeList::getNumAliveNodes() const {
|
|
||||||
int numAliveNodes = 0;
|
|
||||||
|
|
||||||
for (NodeList::iterator node = begin(); node != end(); node++) {
|
|
||||||
if (node->isAlive()) {
|
|
||||||
++numAliveNodes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return numAliveNodes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::clear() {
|
void NodeList::clear() {
|
||||||
qDebug() << "Clearing the NodeList. Deleting all nodes in list.\n";
|
qDebug() << "Clearing the NodeList. Deleting all nodes in list.";
|
||||||
|
|
||||||
// delete all of the nodes in the list, set the pointers back to NULL and the number of nodes to 0
|
NodeHash::iterator nodeItem = _nodeHash.begin();
|
||||||
for (int i = 0; i < _numNodes; i++) {
|
|
||||||
Node** nodeBucket = _nodeBuckets[i / NODES_PER_BUCKET];
|
// iterate the nodes in the list
|
||||||
Node* node = nodeBucket[i % NODES_PER_BUCKET];
|
while (nodeItem != _nodeHash.end()) {
|
||||||
|
nodeItem = killNodeAtHashIterator(nodeItem);
|
||||||
node->lock();
|
|
||||||
notifyHooksOfKilledNode(&*node);
|
|
||||||
|
|
||||||
delete node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_numNodes = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::reset() {
|
void NodeList::reset() {
|
||||||
|
@ -358,7 +339,7 @@ void NodeList::sendSTUNRequest() {
|
||||||
static HifiSockAddr stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT);
|
static HifiSockAddr stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT);
|
||||||
|
|
||||||
if (!_hasCompletedInitialSTUNFailure) {
|
if (!_hasCompletedInitialSTUNFailure) {
|
||||||
qDebug("Sending intial stun request to %s\n", stunSockAddr.getAddress().toString().toLocal8Bit().constData());
|
qDebug("Sending intial stun request to %s", stunSockAddr.getAddress().toString().toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
_nodeSocket.writeDatagram((char*) stunRequestPacket, sizeof(stunRequestPacket),
|
_nodeSocket.writeDatagram((char*) stunRequestPacket, sizeof(stunRequestPacket),
|
||||||
|
@ -370,7 +351,7 @@ void NodeList::sendSTUNRequest() {
|
||||||
if (!_hasCompletedInitialSTUNFailure) {
|
if (!_hasCompletedInitialSTUNFailure) {
|
||||||
// if we're here this was the last failed STUN request
|
// if we're here this was the last failed STUN request
|
||||||
// use our DS as our stun server
|
// use our DS as our stun server
|
||||||
qDebug("Failed to lookup public address via STUN server at %s:%hu. Using DS for STUN.\n",
|
qDebug("Failed to lookup public address via STUN server at %s:%hu. Using DS for STUN.",
|
||||||
STUN_SERVER_HOSTNAME, STUN_SERVER_PORT);
|
STUN_SERVER_HOSTNAME, STUN_SERVER_PORT);
|
||||||
|
|
||||||
_hasCompletedInitialSTUNFailure = true;
|
_hasCompletedInitialSTUNFailure = true;
|
||||||
|
@ -433,7 +414,7 @@ void NodeList::processSTUNResponse(unsigned char* packetData, size_t dataBytes)
|
||||||
if (newPublicAddress != _publicSockAddr.getAddress() || newPublicPort != _publicSockAddr.getPort()) {
|
if (newPublicAddress != _publicSockAddr.getAddress() || newPublicPort != _publicSockAddr.getPort()) {
|
||||||
_publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort);
|
_publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort);
|
||||||
|
|
||||||
qDebug("New public socket received from STUN server is %s:%hu\n",
|
qDebug("New public socket received from STUN server is %s:%hu",
|
||||||
_publicSockAddr.getAddress().toString().toLocal8Bit().constData(),
|
_publicSockAddr.getAddress().toString().toLocal8Bit().constData(),
|
||||||
_publicSockAddr.getPort());
|
_publicSockAddr.getPort());
|
||||||
|
|
||||||
|
@ -457,6 +438,21 @@ void NodeList::processSTUNResponse(unsigned char* packetData, size_t dataBytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeList::killNodeWithUUID(const QUuid& nodeUUID) {
|
||||||
|
NodeHash::iterator nodeItemToKill = _nodeHash.find(nodeUUID);
|
||||||
|
if (nodeItemToKill != _nodeHash.end()) {
|
||||||
|
killNodeAtHashIterator(nodeItemToKill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeHash::iterator NodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill) {
|
||||||
|
qDebug() << "Killed" << *nodeItemToKill.value();
|
||||||
|
emit nodeKilled(nodeItemToKill.value());
|
||||||
|
|
||||||
|
return _nodeHash.erase(nodeItemToKill);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void NodeList::sendKillNode(const char* nodeTypes, int numNodeTypes) {
|
void NodeList::sendKillNode(const char* nodeTypes, int numNodeTypes) {
|
||||||
unsigned char packet[MAX_PACKET_SIZE];
|
unsigned char packet[MAX_PACKET_SIZE];
|
||||||
unsigned char* packetPosition = packet;
|
unsigned char* packetPosition = packet;
|
||||||
|
@ -482,11 +478,8 @@ void NodeList::processKillNode(unsigned char* packetData, size_t dataBytes) {
|
||||||
packetData += NUM_BYTES_RFC4122_UUID;
|
packetData += NUM_BYTES_RFC4122_UUID;
|
||||||
dataBytes -= NUM_BYTES_RFC4122_UUID;
|
dataBytes -= NUM_BYTES_RFC4122_UUID;
|
||||||
|
|
||||||
// make sure the node exists
|
// kill the node with this UUID, if it exists
|
||||||
Node* node = nodeWithUUID(nodeUUID);
|
killNodeWithUUID(nodeUUID);
|
||||||
if (node) {
|
|
||||||
killNode(node, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::sendDomainServerCheckIn() {
|
void NodeList::sendDomainServerCheckIn() {
|
||||||
|
@ -494,7 +487,7 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
|
|
||||||
// Lookup the IP address of the domain server if we need to
|
// Lookup the IP address of the domain server if we need to
|
||||||
if (_domainSockAddr.getAddress().isNull()) {
|
if (_domainSockAddr.getAddress().isNull()) {
|
||||||
qDebug("Looking up DS hostname %s.\n", _domainHostname.toLocal8Bit().constData());
|
qDebug("Looking up DS hostname %s.", _domainHostname.toLocal8Bit().constData());
|
||||||
|
|
||||||
QHostInfo domainServerHostInfo = QHostInfo::fromName(_domainHostname);
|
QHostInfo domainServerHostInfo = QHostInfo::fromName(_domainHostname);
|
||||||
|
|
||||||
|
@ -502,7 +495,7 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
if (domainServerHostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) {
|
if (domainServerHostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
_domainSockAddr.setAddress(domainServerHostInfo.addresses()[i]);
|
_domainSockAddr.setAddress(domainServerHostInfo.addresses()[i]);
|
||||||
|
|
||||||
qDebug("DS at %s is at %s\n", _domainHostname.toLocal8Bit().constData(),
|
qDebug("DS at %s is at %s", _domainHostname.toLocal8Bit().constData(),
|
||||||
_domainSockAddr.getAddress().toString().toLocal8Bit().constData());
|
_domainSockAddr.getAddress().toString().toLocal8Bit().constData());
|
||||||
|
|
||||||
printedDomainServerIP = true;
|
printedDomainServerIP = true;
|
||||||
|
@ -512,11 +505,11 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
|
|
||||||
// if we got here without a break out of the for loop then we failed to lookup the address
|
// if we got here without a break out of the for loop then we failed to lookup the address
|
||||||
if (i == domainServerHostInfo.addresses().size() - 1) {
|
if (i == domainServerHostInfo.addresses().size() - 1) {
|
||||||
qDebug("Failed domain server lookup\n");
|
qDebug("Failed domain server lookup");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!printedDomainServerIP) {
|
} else if (!printedDomainServerIP) {
|
||||||
qDebug("Domain Server IP: %s\n", _domainSockAddr.getAddress().toString().toLocal8Bit().constData());
|
qDebug("Domain Server IP: %s", _domainSockAddr.getAddress().toString().toLocal8Bit().constData());
|
||||||
printedDomainServerIP = true;
|
printedDomainServerIP = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,26 +674,25 @@ void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) {
|
||||||
node->getPublicSocket().getAddress(), node->getPublicSocket().getPort());
|
node->getPublicSocket().getAddress(), node->getPublicSocket().getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
||||||
NodeList::iterator node = end();
|
NodeHash::iterator matchingNodeItem = _nodeHash.find(uuid);
|
||||||
|
|
||||||
for (node = begin(); node != end(); node++) {
|
if (matchingNodeItem == _nodeHash.end()) {
|
||||||
if (node->getUUID() == uuid) {
|
|
||||||
// we already have this node, stop checking
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node == end()) {
|
|
||||||
// we didn't have this node, so add them
|
// we didn't have this node, so add them
|
||||||
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket);
|
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket);
|
||||||
|
SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater);
|
||||||
|
|
||||||
addNodeToList(newNode);
|
_nodeHash.insert(newNode->getUUID(), newNodeSharedPointer);
|
||||||
|
|
||||||
return newNode;
|
qDebug() << "Added" << *newNode;
|
||||||
|
|
||||||
|
emit nodeAdded(newNodeSharedPointer);
|
||||||
|
|
||||||
|
return newNodeSharedPointer;
|
||||||
} else {
|
} else {
|
||||||
node->lock();
|
SharedNodePointer node = matchingNodeItem.value();
|
||||||
|
QMutexLocker(&node->getMutex());
|
||||||
|
|
||||||
if (node->getType() == NODE_TYPE_AUDIO_MIXER ||
|
if (node->getType() == NODE_TYPE_AUDIO_MIXER ||
|
||||||
node->getType() == NODE_TYPE_VOXEL_SERVER ||
|
node->getType() == NODE_TYPE_VOXEL_SERVER ||
|
||||||
|
@ -713,44 +705,26 @@ Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
||||||
// check if we need to change this node's public or local sockets
|
// check if we need to change this node's public or local sockets
|
||||||
if (publicSocket != node->getPublicSocket()) {
|
if (publicSocket != node->getPublicSocket()) {
|
||||||
node->setPublicSocket(publicSocket);
|
node->setPublicSocket(publicSocket);
|
||||||
qDebug() << "Public socket change for node" << *node << "\n";
|
qDebug() << "Public socket change for node" << *node;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localSocket != node->getLocalSocket()) {
|
if (localSocket != node->getLocalSocket()) {
|
||||||
node->setLocalSocket(localSocket);
|
node->setLocalSocket(localSocket);
|
||||||
qDebug() << "Local socket change for node" << *node << "\n";
|
qDebug() << "Local socket change for node" << *node;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->unlock();
|
|
||||||
|
|
||||||
// we had this node already, do nothing for now
|
// we had this node already, do nothing for now
|
||||||
return &*node;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::addNodeToList(Node* newNode) {
|
|
||||||
// find the correct array to add this node to
|
|
||||||
int bucketIndex = _numNodes / NODES_PER_BUCKET;
|
|
||||||
|
|
||||||
if (!_nodeBuckets[bucketIndex]) {
|
|
||||||
_nodeBuckets[bucketIndex] = new Node*[NODES_PER_BUCKET]();
|
|
||||||
}
|
|
||||||
|
|
||||||
_nodeBuckets[bucketIndex][_numNodes % NODES_PER_BUCKET] = newNode;
|
|
||||||
|
|
||||||
++_numNodes;
|
|
||||||
|
|
||||||
qDebug() << "Added" << *newNode << "\n";
|
|
||||||
|
|
||||||
notifyHooksOfAddedNode(newNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes) {
|
unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes) {
|
||||||
unsigned n = 0;
|
unsigned n = 0;
|
||||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
|
||||||
|
foreach (const SharedNodePointer& node, _nodeHash) {
|
||||||
// only send to the NodeTypes we are asked to send to.
|
// only send to the NodeTypes we are asked to send to.
|
||||||
if (memchr(nodeTypes, node->getType(), numNodeTypes)) {
|
if (memchr(nodeTypes, node->getType(), numNodeTypes)) {
|
||||||
if (getNodeActiveSocketOrPing(&(*node))) {
|
if (getNodeActiveSocketOrPing(node.data())) {
|
||||||
// we know which socket is good for this node, send there
|
// we know which socket is good for this node, send there
|
||||||
_nodeSocket.writeDatagram((char*) broadcastData, dataBytes,
|
_nodeSocket.writeDatagram((char*) broadcastData, dataBytes,
|
||||||
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
||||||
|
@ -758,14 +732,15 @@ unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataByt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::pingInactiveNodes() {
|
void NodeList::pingInactiveNodes() {
|
||||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
foreach (const SharedNodePointer& node, _nodeHash) {
|
||||||
if (!node->getActiveSocket()) {
|
if (!node->getActiveSocket()) {
|
||||||
// we don't have an active link to this node, ping it to set that up
|
// we don't have an active link to this node, ping it to set that up
|
||||||
pingPublicAndLocalSocketsForInactiveNode(&(*node));
|
pingPublicAndLocalSocketsForInactiveNode(node.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,7 +755,8 @@ const HifiSockAddr* NodeList::getNodeActiveSocketOrPing(Node* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddress) {
|
void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddress) {
|
||||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
|
||||||
|
foreach (const SharedNodePointer& node, _nodeHash) {
|
||||||
if (!node->getActiveSocket()) {
|
if (!node->getActiveSocket()) {
|
||||||
// check both the public and local addresses for each node to see if we find a match
|
// check both the public and local addresses for each node to see if we find a match
|
||||||
// prioritize the private address so that we prune erroneous local matches
|
// prioritize the private address so that we prune erroneous local matches
|
||||||
|
@ -795,46 +771,35 @@ void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddre
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* NodeList::soloNodeOfType(char nodeType) {
|
SharedNodePointer NodeList::soloNodeOfType(char nodeType) {
|
||||||
|
|
||||||
if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES)) != NULL) {
|
if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES)) != NULL) {
|
||||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
foreach (const SharedNodePointer& node, _nodeHash) {
|
||||||
if (node->getType() == nodeType) {
|
if (node->getType() == nodeType) {
|
||||||
return &(*node);
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return SharedNodePointer();
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::killNode(Node* node, bool mustLockNode) {
|
|
||||||
if (mustLockNode) {
|
|
||||||
node->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "Killed " << *node << "\n";
|
|
||||||
|
|
||||||
notifyHooksOfKilledNode(&*node);
|
|
||||||
|
|
||||||
node->setAlive(false);
|
|
||||||
|
|
||||||
if (mustLockNode) {
|
|
||||||
node->unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::removeSilentNodes() {
|
void NodeList::removeSilentNodes() {
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
|
|
||||||
for(NodeList::iterator node = nodeList->begin(); node != nodeList->end(); ++node) {
|
NodeHash::iterator nodeItem = _nodeHash.begin();
|
||||||
node->lock();
|
|
||||||
|
while (nodeItem != _nodeHash.end()) {
|
||||||
|
SharedNodePointer node = nodeItem.value();
|
||||||
|
|
||||||
|
QMutexLocker(&node->getMutex());
|
||||||
|
|
||||||
if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) {
|
if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) {
|
||||||
// kill this node, don't lock - we already did it
|
// call our private method to kill this node (removes it and emits the right signal)
|
||||||
nodeList->killNode(&(*node), false);
|
nodeItem = killNodeAtHashIterator(nodeItem);
|
||||||
|
} else {
|
||||||
|
// we didn't kill this node, push the iterator forwards
|
||||||
|
++nodeItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,7 +813,7 @@ void NodeList::loadData(QSettings *settings) {
|
||||||
|
|
||||||
if (domainServerHostname.size() > 0) {
|
if (domainServerHostname.size() > 0) {
|
||||||
_domainHostname = domainServerHostname;
|
_domainHostname = domainServerHostname;
|
||||||
notifyDomainChanged();
|
emit domainChanged(_domainHostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
@ -867,125 +832,3 @@ void NodeList::saveData(QSettings* settings) {
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList::iterator NodeList::begin() const {
|
|
||||||
Node** nodeBucket = NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < _numNodes; i++) {
|
|
||||||
if (i % NODES_PER_BUCKET == 0) {
|
|
||||||
nodeBucket = _nodeBuckets[i / NODES_PER_BUCKET];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeBucket[i % NODES_PER_BUCKET]->isAlive()) {
|
|
||||||
return NodeListIterator(this, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// there's no alive node to start from - return the end
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeList::iterator NodeList::end() const {
|
|
||||||
return NodeListIterator(this, _numNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeListIterator::NodeListIterator(const NodeList* nodeList, int nodeIndex) :
|
|
||||||
_nodeIndex(nodeIndex) {
|
|
||||||
_nodeList = nodeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeListIterator& NodeListIterator::operator=(const NodeListIterator& otherValue) {
|
|
||||||
_nodeList = otherValue._nodeList;
|
|
||||||
_nodeIndex = otherValue._nodeIndex;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeListIterator::operator==(const NodeListIterator &otherValue) {
|
|
||||||
return _nodeIndex == otherValue._nodeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeListIterator::operator!=(const NodeListIterator &otherValue) {
|
|
||||||
return !(*this == otherValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node& NodeListIterator::operator*() {
|
|
||||||
Node** nodeBucket = _nodeList->_nodeBuckets[_nodeIndex / NODES_PER_BUCKET];
|
|
||||||
return *nodeBucket[_nodeIndex % NODES_PER_BUCKET];
|
|
||||||
}
|
|
||||||
|
|
||||||
Node* NodeListIterator::operator->() {
|
|
||||||
Node** nodeBucket = _nodeList->_nodeBuckets[_nodeIndex / NODES_PER_BUCKET];
|
|
||||||
return nodeBucket[_nodeIndex % NODES_PER_BUCKET];
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeListIterator& NodeListIterator::operator++() {
|
|
||||||
skipDeadAndStopIncrement();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeList::iterator NodeListIterator::operator++(int) {
|
|
||||||
NodeListIterator newIterator = NodeListIterator(*this);
|
|
||||||
skipDeadAndStopIncrement();
|
|
||||||
return newIterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeListIterator::skipDeadAndStopIncrement() {
|
|
||||||
while (_nodeIndex != _nodeList->_numNodes) {
|
|
||||||
++_nodeIndex;
|
|
||||||
|
|
||||||
if (_nodeIndex == _nodeList->_numNodes) {
|
|
||||||
break;
|
|
||||||
} else if ((*(*this)).isAlive()) {
|
|
||||||
// skip over the dead nodes
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::addDomainListener(DomainChangeListener* listener) {
|
|
||||||
_domainListeners.push_back(listener);
|
|
||||||
QString domain = _domainHostname.isEmpty() ? _domainSockAddr.getAddress().toString() : _domainHostname;
|
|
||||||
listener->domainChanged(domain);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::removeDomainListener(DomainChangeListener* listener) {
|
|
||||||
for (int i = 0; i < _domainListeners.size(); i++) {
|
|
||||||
if (_domainListeners[i] == listener) {
|
|
||||||
_domainListeners.erase(_domainListeners.begin() + i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::addHook(NodeListHook* hook) {
|
|
||||||
_hooks.push_back(hook);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::removeHook(NodeListHook* hook) {
|
|
||||||
for (int i = 0; i < _hooks.size(); i++) {
|
|
||||||
if (_hooks[i] == hook) {
|
|
||||||
_hooks.erase(_hooks.begin() + i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::notifyHooksOfAddedNode(Node* node) {
|
|
||||||
for (int i = 0; i < _hooks.size(); i++) {
|
|
||||||
//printf("NodeList::notifyHooksOfAddedNode() i=%d\n", i);
|
|
||||||
_hooks[i]->nodeAdded(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::notifyHooksOfKilledNode(Node* node) {
|
|
||||||
for (int i = 0; i < _hooks.size(); i++) {
|
|
||||||
//printf("NodeList::notifyHooksOfKilledNode() i=%d\n", i);
|
|
||||||
_hooks[i]->nodeKilled(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeList::notifyDomainChanged() {
|
|
||||||
for (int i = 0; i < _domainListeners.size(); i++) {
|
|
||||||
_domainListeners[i]->domainChanged(_domainHostname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,9 +14,10 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
#include <QtCore/QSharedPointer>
|
||||||
#include <QtNetwork/QHostAddress>
|
#include <QtNetwork/QHostAddress>
|
||||||
#include <QtNetwork/QUdpSocket>
|
#include <QtNetwork/QUdpSocket>
|
||||||
#include <QtCore/QSettings>
|
|
||||||
|
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
#include "NodeTypes.h"
|
#include "NodeTypes.h"
|
||||||
|
@ -43,19 +44,10 @@ const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5;
|
||||||
|
|
||||||
class Assignment;
|
class Assignment;
|
||||||
class HifiSockAddr;
|
class HifiSockAddr;
|
||||||
class NodeListIterator;
|
|
||||||
|
|
||||||
// Callers who want to hook add/kill callbacks should implement this class
|
typedef QSharedPointer<Node> SharedNodePointer;
|
||||||
class NodeListHook {
|
typedef QHash<QUuid, SharedNodePointer> NodeHash;
|
||||||
public:
|
Q_DECLARE_METATYPE(SharedNodePointer)
|
||||||
virtual void nodeAdded(Node* node) = 0;
|
|
||||||
virtual void nodeKilled(Node* node) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DomainChangeListener {
|
|
||||||
public:
|
|
||||||
virtual void domainChanged(QString domain) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class NodeList : public QObject {
|
class NodeList : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -63,11 +55,6 @@ public:
|
||||||
static NodeList* createInstance(char ownerType, unsigned short int socketListenPort = 0);
|
static NodeList* createInstance(char ownerType, unsigned short int socketListenPort = 0);
|
||||||
static NodeList* getInstance();
|
static NodeList* getInstance();
|
||||||
|
|
||||||
typedef NodeListIterator iterator;
|
|
||||||
|
|
||||||
NodeListIterator begin() const;
|
|
||||||
NodeListIterator end() const;
|
|
||||||
|
|
||||||
NODE_TYPE getOwnerType() const { return _ownerType; }
|
NODE_TYPE getOwnerType() const { return _ownerType; }
|
||||||
void setOwnerType(NODE_TYPE ownerType) { _ownerType = ownerType; }
|
void setOwnerType(NODE_TYPE ownerType) { _ownerType = ownerType; }
|
||||||
|
|
||||||
|
@ -88,8 +75,9 @@ public:
|
||||||
|
|
||||||
void(*linkedDataCreateCallback)(Node *);
|
void(*linkedDataCreateCallback)(Node *);
|
||||||
|
|
||||||
int size() { return _numNodes; }
|
const NodeHash& getNodeHash() { return _nodeHash; }
|
||||||
int getNumAliveNodes() const;
|
|
||||||
|
int size() const { return _nodeHash.size(); }
|
||||||
|
|
||||||
int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; }
|
int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; }
|
||||||
|
|
||||||
|
@ -107,13 +95,13 @@ public:
|
||||||
int fillPingReplyPacket(unsigned char* pingBuffer, unsigned char* replyBuffer);
|
int fillPingReplyPacket(unsigned char* pingBuffer, unsigned char* replyBuffer);
|
||||||
void pingPublicAndLocalSocketsForInactiveNode(Node* node);
|
void pingPublicAndLocalSocketsForInactiveNode(Node* node);
|
||||||
|
|
||||||
|
void killNodeWithUUID(const QUuid& nodeUUID);
|
||||||
void sendKillNode(const char* nodeTypes, int numNodeTypes);
|
void sendKillNode(const char* nodeTypes, int numNodeTypes);
|
||||||
|
|
||||||
Node* nodeWithAddress(const HifiSockAddr& senderSockAddr);
|
SharedNodePointer nodeWithAddress(const HifiSockAddr& senderSockAddr);
|
||||||
Node* nodeWithUUID(const QUuid& nodeUUID);
|
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID);
|
||||||
|
|
||||||
Node* addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||||
void killNode(Node* node, bool mustLockNode = true);
|
|
||||||
|
|
||||||
void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes);
|
void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes);
|
||||||
void processBulkNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, int numTotalBytes);
|
void processBulkNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, int numTotalBytes);
|
||||||
|
@ -122,26 +110,20 @@ public:
|
||||||
|
|
||||||
unsigned broadcastToNodes(unsigned char *broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes);
|
unsigned broadcastToNodes(unsigned char *broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes);
|
||||||
|
|
||||||
Node* soloNodeOfType(char nodeType);
|
SharedNodePointer soloNodeOfType(char nodeType);
|
||||||
|
|
||||||
void loadData(QSettings* settings);
|
void loadData(QSettings* settings);
|
||||||
void saveData(QSettings* settings);
|
void saveData(QSettings* settings);
|
||||||
|
|
||||||
friend class NodeListIterator;
|
|
||||||
|
|
||||||
void addHook(NodeListHook* hook);
|
|
||||||
void removeHook(NodeListHook* hook);
|
|
||||||
void notifyHooksOfAddedNode(Node* node);
|
|
||||||
void notifyHooksOfKilledNode(Node* node);
|
|
||||||
|
|
||||||
void addDomainListener(DomainChangeListener* listener);
|
|
||||||
void removeDomainListener(DomainChangeListener* listener);
|
|
||||||
|
|
||||||
const HifiSockAddr* getNodeActiveSocketOrPing(Node* node);
|
const HifiSockAddr* getNodeActiveSocketOrPing(Node* node);
|
||||||
public slots:
|
public slots:
|
||||||
void sendDomainServerCheckIn();
|
void sendDomainServerCheckIn();
|
||||||
void pingInactiveNodes();
|
void pingInactiveNodes();
|
||||||
void removeSilentNodes();
|
void removeSilentNodes();
|
||||||
|
signals:
|
||||||
|
void domainChanged(const QString& domainHostname);
|
||||||
|
void nodeAdded(SharedNodePointer);
|
||||||
|
void nodeKilled(SharedNodePointer);
|
||||||
private:
|
private:
|
||||||
static NodeList* _sharedInstance;
|
static NodeList* _sharedInstance;
|
||||||
|
|
||||||
|
@ -150,17 +132,16 @@ private:
|
||||||
NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||||
void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||||
|
|
||||||
void addNodeToList(Node* newNode);
|
|
||||||
|
|
||||||
void sendSTUNRequest();
|
void sendSTUNRequest();
|
||||||
void processSTUNResponse(unsigned char* packetData, size_t dataBytes);
|
void processSTUNResponse(unsigned char* packetData, size_t dataBytes);
|
||||||
|
|
||||||
void processKillNode(unsigned char* packetData, size_t dataBytes);
|
void processKillNode(unsigned char* packetData, size_t dataBytes);
|
||||||
|
|
||||||
|
NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill);
|
||||||
|
|
||||||
|
NodeHash _nodeHash;
|
||||||
QString _domainHostname;
|
QString _domainHostname;
|
||||||
HifiSockAddr _domainSockAddr;
|
HifiSockAddr _domainSockAddr;
|
||||||
Node** _nodeBuckets[MAX_NUM_NODES / NODES_PER_BUCKET];
|
|
||||||
int _numNodes;
|
|
||||||
QUdpSocket _nodeSocket;
|
QUdpSocket _nodeSocket;
|
||||||
char _ownerType;
|
char _ownerType;
|
||||||
char* _nodeTypesOfInterest;
|
char* _nodeTypesOfInterest;
|
||||||
|
@ -174,35 +155,8 @@ private:
|
||||||
void activateSocketFromNodeCommunication(const HifiSockAddr& nodeSockAddr);
|
void activateSocketFromNodeCommunication(const HifiSockAddr& nodeSockAddr);
|
||||||
void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData);
|
void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData);
|
||||||
|
|
||||||
std::vector<NodeListHook*> _hooks;
|
|
||||||
std::vector<DomainChangeListener*> _domainListeners;
|
|
||||||
|
|
||||||
void resetDomainData(char domainField[], const char* domainData);
|
void resetDomainData(char domainField[], const char* domainData);
|
||||||
void notifyDomainChanged();
|
|
||||||
void domainLookup();
|
void domainLookup();
|
||||||
};
|
};
|
||||||
|
|
||||||
class NodeListIterator : public std::iterator<std::input_iterator_tag, Node> {
|
|
||||||
public:
|
|
||||||
NodeListIterator(const NodeList* nodeList, int nodeIndex);
|
|
||||||
|
|
||||||
int getNodeIndex() { return _nodeIndex; }
|
|
||||||
|
|
||||||
NodeListIterator& operator=(const NodeListIterator& otherValue);
|
|
||||||
|
|
||||||
bool operator==(const NodeListIterator& otherValue);
|
|
||||||
bool operator!= (const NodeListIterator& otherValue);
|
|
||||||
|
|
||||||
Node& operator*();
|
|
||||||
Node* operator->();
|
|
||||||
|
|
||||||
NodeListIterator& operator++();
|
|
||||||
NodeListIterator operator++(int);
|
|
||||||
private:
|
|
||||||
void skipDeadAndStopIncrement();
|
|
||||||
|
|
||||||
const NodeList* _nodeList;
|
|
||||||
int _nodeIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* defined(__hifi__NodeList__) */
|
#endif /* defined(__hifi__NodeList__) */
|
||||||
|
|
|
@ -32,12 +32,12 @@ int numberOfThreeBitSectionsInCode(const unsigned char* octalCode, int maxBytes)
|
||||||
|
|
||||||
void printOctalCode(const unsigned char* octalCode) {
|
void printOctalCode(const unsigned char* octalCode) {
|
||||||
if (!octalCode) {
|
if (!octalCode) {
|
||||||
qDebug("NULL\n");
|
qDebug("NULL");
|
||||||
} else {
|
} else {
|
||||||
|
QDebug continuedDebug = qDebug().nospace();
|
||||||
for (int i = 0; i < bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(octalCode)); i++) {
|
for (int i = 0; i < bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(octalCode)); i++) {
|
||||||
outputBits(octalCode[i],false);
|
outputBits(octalCode[i], &continuedDebug);
|
||||||
}
|
}
|
||||||
qDebug("\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case PACKET_TYPE_HEAD_DATA:
|
case PACKET_TYPE_HEAD_DATA:
|
||||||
return 12;
|
return 13;
|
||||||
|
|
||||||
case PACKET_TYPE_AVATAR_URLS:
|
case PACKET_TYPE_AVATAR_URLS:
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -70,7 +70,7 @@ bool packetVersionMatch(unsigned char* packetHeader) {
|
||||||
if (packetHeader[1] == versionForPacketType(packetHeader[0]) || packetHeader[0] == PACKET_TYPE_STUN_RESPONSE) {
|
if (packetHeader[1] == versionForPacketType(packetHeader[0]) || packetHeader[0] == PACKET_TYPE_STUN_RESPONSE) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
qDebug("There is a packet version mismatch for packet with header %c\n", packetHeader[0]);
|
qDebug("There is a packet version mismatch for packet with header %c", packetHeader[0]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ PerfStat::~PerfStat() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantDebugOut) {
|
if (wantDebugOut) {
|
||||||
qDebug("PerfStats: %s elapsed:%f average:%lf count:%ld total:%lf ut:%ld us:%ld ue:%ld t:%ld s:%ld e:%ld\n",
|
qDebug("PerfStats: %s elapsed:%f average:%lf count:%ld total:%lf ut:%ld us:%ld ue:%ld t:%ld s:%ld e:%ld",
|
||||||
this->group.c_str(),elapsed,average,count,totalTime,
|
this->group.c_str(),elapsed,average,count,totalTime,
|
||||||
(long)(end.tv_usec-start.tv_usec), (long)start.tv_usec, (long)end.tv_usec,
|
(long)(end.tv_usec-start.tv_usec), (long)start.tv_usec, (long)end.tv_usec,
|
||||||
(long)(end.tv_sec-start.tv_sec), (long)start.tv_sec, (long)end.tv_sec
|
(long)(end.tv_sec-start.tv_sec), (long)start.tv_sec, (long)end.tv_sec
|
||||||
|
@ -113,20 +113,20 @@ PerformanceWarning::~PerformanceWarning() {
|
||||||
if ((_alwaysDisplay || _renderWarningsOn) && elapsedmsec > 1) {
|
if ((_alwaysDisplay || _renderWarningsOn) && elapsedmsec > 1) {
|
||||||
if (elapsedmsec > 1000) {
|
if (elapsedmsec > 1000) {
|
||||||
double elapsedsec = (end - _start) / 1000000.0;
|
double elapsedsec = (end - _start) / 1000000.0;
|
||||||
qDebug("%s took %.2lf seconds %s\n", _message, elapsedsec, (_alwaysDisplay ? "" : "WARNING!") );
|
qDebug("%s took %.2lf seconds %s", _message, elapsedsec, (_alwaysDisplay ? "" : "WARNING!") );
|
||||||
} else {
|
} else {
|
||||||
if (_suppressShortTimings) {
|
if (_suppressShortTimings) {
|
||||||
if (elapsedmsec > 10) {
|
if (elapsedmsec > 10) {
|
||||||
qDebug("%s took %.1lf milliseconds %s\n", _message, elapsedmsec,
|
qDebug("%s took %.1lf milliseconds %s", _message, elapsedmsec,
|
||||||
(_alwaysDisplay || (elapsedmsec < 10) ? "" : "WARNING!"));
|
(_alwaysDisplay || (elapsedmsec < 10) ? "" : "WARNING!"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug("%s took %.2lf milliseconds %s\n", _message, elapsedmsec,
|
qDebug("%s took %.2lf milliseconds %s", _message, elapsedmsec,
|
||||||
(_alwaysDisplay || (elapsedmsec < 10) ? "" : "WARNING!"));
|
(_alwaysDisplay || (elapsedmsec < 10) ? "" : "WARNING!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_alwaysDisplay) {
|
} else if (_alwaysDisplay) {
|
||||||
qDebug("%s took %.2lf milliseconds\n", _message, elapsedmsec);
|
qDebug("%s took %.2lf milliseconds", _message, elapsedmsec);
|
||||||
}
|
}
|
||||||
// if the caller gave us a pointer to store the running total, track it now.
|
// if the caller gave us a pointer to store the running total, track it now.
|
||||||
if (_runningTotal) {
|
if (_runningTotal) {
|
||||||
|
|
|
@ -18,7 +18,7 @@ ReceivedPacketProcessor::ReceivedPacketProcessor() {
|
||||||
|
|
||||||
void ReceivedPacketProcessor::queueReceivedPacket(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength) {
|
void ReceivedPacketProcessor::queueReceivedPacket(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength) {
|
||||||
// Make sure our Node and NodeList knows we've heard from this node.
|
// Make sure our Node and NodeList knows we've heard from this node.
|
||||||
Node* node = NodeList::getInstance()->nodeWithAddress(address);
|
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(address);
|
||||||
if (node) {
|
if (node) {
|
||||||
node->setLastHeardMicrostamp(usecTimestampNow());
|
node->setLastHeardMicrostamp(usecTimestampNow());
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue