From 1965ff286ba2b57e3a0913f15b3fe71a13f9a8a1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 09:16:55 -0700 Subject: [PATCH 01/10] fix unix build buster for starfield --- interface/src/starfield/renderer/Tiling.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/starfield/renderer/Tiling.h b/interface/src/starfield/renderer/Tiling.h index 7edbfd6656..53b17a9844 100755 --- a/interface/src/starfield/renderer/Tiling.h +++ b/interface/src/starfield/renderer/Tiling.h @@ -12,10 +12,10 @@ #include "starfield/Config.h" namespace starfield { - + const float LOG2 = 1.4426950408889634; + class Tiling { public: - Tiling(unsigned tileResolution) : _tileResolution(tileResolution), _rcpSlice(tileResolution / Radians::twicePi()) { _nBits = ceil(log(getTileCount()) * LOG2); } @@ -39,10 +39,7 @@ namespace starfield { unsigned _tileResolution; float _rcpSlice; unsigned _nBits; - - const float LOG2 = 1.4426950408889634; }; - } #endif From 2fcdd708cbbf43e58050a33b1728b60c4d38fc92 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 09:28:36 -0700 Subject: [PATCH 02/10] fix for audio-mixer crash with node from DS --- assignment-client/src/audio/AudioMixer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 1ae67c4063..de762cb628 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -171,7 +171,8 @@ void AudioMixer::run() { // loop through all other nodes that have sufficient audio to mix for (NodeList::iterator otherNode = nodeList->begin(); otherNode != nodeList->end(); otherNode++) { - if (((PositionalAudioRingBuffer*) otherNode->getLinkedData())->willBeAddedToMix() + if (otherNode->getLinkedData() + && ((PositionalAudioRingBuffer*) otherNode->getLinkedData())->willBeAddedToMix() && (otherNode != node || (otherNode == node && nodeRingBuffer->shouldLoopbackForNode()))) { PositionalAudioRingBuffer* otherNodeBuffer = (PositionalAudioRingBuffer*) otherNode->getLinkedData(); // based on our listen mode we will do this mixing... From acbd664cabd145a0448de4922de455f153d00198 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 09:34:38 -0700 Subject: [PATCH 03/10] fix audio send to wrong socket --- assignment-client/src/audio/AudioMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index de762cb628..bf2e6ebb97 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -340,7 +340,7 @@ void AudioMixer::run() { } memcpy(clientPacket + numBytesPacketHeader, clientSamples, sizeof(clientSamples)); - nodeList->getNodeSocket()->send(node->getPublicSocket(), clientPacket, sizeof(clientPacket)); + nodeList->getNodeSocket()->send(node->getActiveSocket(), clientPacket, sizeof(clientPacket)); } } From 9c950d4c23fd21002569e3c77f3313dff3b46c15 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 09:53:23 -0700 Subject: [PATCH 04/10] trivial change to Agent to trigger re-deploy --- assignment-client/src/Agent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index ba70fd58ec..552910e04d 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -36,4 +36,4 @@ private: std::vector _audioInjectors; }; -#endif /* defined(__hifi__Operative__) */ +#endif /* defined(__hifi__Agent__) */ From fc36e38d1ce95fc91e902732a97fa488d6111dcd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 10:03:02 -0700 Subject: [PATCH 05/10] fix a crash in AudioMixer with active socket but no linked data --- assignment-client/src/audio/AudioMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index bf2e6ebb97..aab11b1317 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -163,7 +163,7 @@ void AudioMixer::run() { const int PHASE_DELAY_AT_90 = 20; - if (node->getType() == NODE_TYPE_AGENT && node->getActiveSocket()) { + if (node->getType() == NODE_TYPE_AGENT && node->getActiveSocket() && node->getLinkedData()) { AvatarAudioRingBuffer* nodeRingBuffer = (AvatarAudioRingBuffer*) node->getLinkedData(); // zero out the client mix for this node From d85c0bb88ae77d60f145aa42986b5e4d3649f883 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 10:25:35 -0700 Subject: [PATCH 06/10] add a DELETE method to civetweb to delete assignment by UUID --- domain-server/src/DomainServer.cpp | 73 ++++++++++++++++++++++-------- domain-server/src/DomainServer.h | 1 + libraries/shared/src/NodeList.cpp | 24 +++++++--- libraries/shared/src/NodeList.h | 1 + 4 files changed, 74 insertions(+), 25 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 39c68d550f..18fa3cb2f8 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -46,6 +46,9 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { const struct mg_request_info* ri = mg_get_request_info(connection); const char RESPONSE_200[] = "HTTP/1.0 200 OK\r\n\r\n"; + const char RESPONSE_400[] = "HTTP/1.0 400 Bad Request\r\n\r\n"; + + const char ASSIGNMENT_URI[] = "/assignment"; if (strcmp(ri->uri, "/assignment") == 0 && strcmp(ri->request_method, "POST") == 0) { // return a 200 @@ -120,6 +123,35 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { // we've processed this request return 1; + } else if (strcmp(ri->request_method, "DELETE") == 0) { + // this is a DELETE request + + // check if it is for an assignment + if (memcmp(ri->uri, ASSIGNMENT_URI, sizeof(ASSIGNMENT_URI) - sizeof('\0')) == 0) { + // pull the UUID from the url + QUuid deleteUUID = QUuid(QString(ri->uri + strlen(ASSIGNMENT_URI) + sizeof('/'))); + + if (!deleteUUID.isNull()) { + Node *nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID); + + if (nodeToKill) { + // start with a 200 response + mg_printf(connection, "%s", RESPONSE_200); + + // we have a valid UUID and node - kill the node that has this assignment + NodeList::getInstance()->killNode(nodeToKill); + + // successfully processed request + return 1; + } + } + } + + // request not processed - bad request + mg_printf(connection, "%s", RESPONSE_400); + + // this was processed by civetweb + return 1; } else { // have mongoose process this request from the document_root return 0; @@ -160,6 +192,27 @@ void DomainServer::civetwebUploadHandler(struct mg_connection *connection, const domainServerInstance->_assignmentQueueMutex.unlock(); } +void DomainServer::addDeletedAssignmentBackToQueue(Assignment* deletedAssignment) { + qDebug() << "Adding assignment" << *deletedAssignment << " back to queue.\n"; + + // find this assignment in the static file + for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) { + if (_staticAssignments[i].getUUID() == deletedAssignment->getUUID()) { + // reset the UUID on the static assignment + _staticAssignments[i].resetUUID(); + + // put this assignment back in the queue so it goes out + _assignmentQueueMutex.lock(); + _assignmentQueue.push_back(&_staticAssignments[i]); + _assignmentQueueMutex.unlock(); + + } else if (_staticAssignments[i].getUUID().isNull()) { + // we are at the blank part of the static assignments - break out + break; + } + } +} + void DomainServer::nodeAdded(Node* node) { } @@ -169,26 +222,8 @@ void DomainServer::nodeKilled(Node* node) { if (node->getLinkedData()) { Assignment* nodeAssignment = (Assignment*) node->getLinkedData(); - qDebug() << "Adding assignment" << *nodeAssignment << " back to queue.\n"; - - // find this assignment in the static file - for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) { - if (_staticAssignments[i].getUUID() == nodeAssignment->getUUID()) { - // reset the UUID on the static assignment - _staticAssignments[i].resetUUID(); - - // put this assignment back in the queue so it goes out - _assignmentQueueMutex.lock(); - _assignmentQueue.push_back(&_staticAssignments[i]); - _assignmentQueueMutex.unlock(); - - } else if (_staticAssignments[i].getUUID().isNull()) { - // we are at the blank part of the static assignments - break out - break; - } - } + addDeletedAssignmentBackToQueue(nodeAssignment); } - } unsigned char* DomainServer::addNodeToBroadcastPacket(unsigned char* currentPosition, Node* nodeToAdd) { diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 205d9e8f6e..78e1f06587 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -47,6 +47,7 @@ private: void removeAssignmentFromQueue(Assignment* removableAssignment); bool checkInWithUUIDMatchesExistingNode(sockaddr* nodePublicSocket, sockaddr* nodeLocalSocket, const QUuid& checkInUUI); void possiblyAddStaticAssignmentsBackToQueueAfterRestart(timeval* startTime); + void addDeletedAssignmentBackToQueue(Assignment* deletedAssignment); void cleanup(); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index e067c7afa9..a7a6dac5aa 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -715,6 +715,22 @@ Node* NodeList::soloNodeOfType(char nodeType) { return NULL; } +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* removeSilentNodes(void *args) { NodeList* nodeList = (NodeList*) args; uint64_t checkTimeUsecs = 0; @@ -728,12 +744,8 @@ void* removeSilentNodes(void *args) { node->lock(); if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) { - - qDebug() << "Killed " << *node << "\n"; - - nodeList->notifyHooksOfKilledNode(&*node); - - node->setAlive(false); + // kill this node, don't lock - we already did it + nodeList->killNode(&(*node), false); } node->unlock(); diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index f98ae7070c..5361f12ca6 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -113,6 +113,7 @@ public: Node* nodeWithUUID(const QUuid& nodeUUID); Node* addOrUpdateNode(const QUuid& uuid, char nodeType, sockaddr* publicSocket, sockaddr* localSocket); + void killNode(Node* node, bool mustLockNode = true); void processNodeData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); void processBulkNodeData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes); From f6c9c575850dff0373f7d5f54037af4f8232c665 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 10:33:22 -0700 Subject: [PATCH 07/10] cleanup checking of request method, clarify that node is being deleted --- domain-server/src/DomainServer.cpp | 148 +++++++++++++++-------------- 1 file changed, 79 insertions(+), 69 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 18fa3cb2f8..2bfd2629fe 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -49,87 +49,97 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { const char RESPONSE_400[] = "HTTP/1.0 400 Bad Request\r\n\r\n"; const char ASSIGNMENT_URI[] = "/assignment"; + const char NODE_URI[] = "/node"; - if (strcmp(ri->uri, "/assignment") == 0 && strcmp(ri->request_method, "POST") == 0) { - // return a 200 - mg_printf(connection, "%s", RESPONSE_200); - // upload the file - mg_upload(connection, "/tmp"); - - return 1; - } else if (strcmp(ri->uri, "/assignments.json") == 0) { - // user is asking for json list of assignments - - // start with a 200 response - mg_printf(connection, "%s", RESPONSE_200); - - // setup the JSON - QJsonObject assignmentJSON; - - QJsonObject assignedNodesJSON; - - // enumerate the NodeList to find the assigned nodes - NodeList* nodeList = NodeList::getInstance(); - - const char ASSIGNMENT_JSON_UUID_KEY[] = "UUID"; - - for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { - if (node->getLinkedData()) { - // this is a node with assignment - QJsonObject assignedNodeJSON; - - // add the assignment UUID - QString assignmentUUID = uuidStringWithoutCurlyBraces(((Assignment*) node->getLinkedData())->getUUID()); - assignedNodeJSON[ASSIGNMENT_JSON_UUID_KEY] = assignmentUUID; - - // add the node socket information - assignedNodeJSON["public"] = jsonForSocket(node->getPublicSocket()); - assignedNodeJSON["local"] = jsonForSocket(node->getLocalSocket()); - - // re-format the type name so it matches the target name - QString nodeTypeName(node->getTypeName()); - nodeTypeName = nodeTypeName.toLower(); - nodeTypeName.replace(' ', '-'); - - assignedNodesJSON[nodeTypeName] = assignedNodeJSON; + if (strcmp(ri->request_method, "GET") == 0) { + if (strcmp(ri->uri, "/assignments.json") == 0) { + // user is asking for json list of assignments + + // start with a 200 response + mg_printf(connection, "%s", RESPONSE_200); + + // setup the JSON + QJsonObject assignmentJSON; + + QJsonObject assignedNodesJSON; + + // enumerate the NodeList to find the assigned nodes + NodeList* nodeList = NodeList::getInstance(); + + const char ASSIGNMENT_JSON_UUID_KEY[] = "UUID"; + + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { + if (node->getLinkedData()) { + // this is a node with assignment + QJsonObject assignedNodeJSON; + + // add the assignment UUID + QString assignmentUUID = uuidStringWithoutCurlyBraces(((Assignment*) node->getLinkedData())->getUUID()); + assignedNodeJSON[ASSIGNMENT_JSON_UUID_KEY] = assignmentUUID; + + // add the node socket information + assignedNodeJSON["public"] = jsonForSocket(node->getPublicSocket()); + assignedNodeJSON["local"] = jsonForSocket(node->getLocalSocket()); + + // re-format the type name so it matches the target name + QString nodeTypeName(node->getTypeName()); + nodeTypeName = nodeTypeName.toLower(); + nodeTypeName.replace(' ', '-'); + + assignedNodesJSON[nodeTypeName] = assignedNodeJSON; + } } + + assignmentJSON["fulfilled"] = assignedNodesJSON; + + QJsonObject queuedAssignmentsJSON; + + // add the queued but unfilled assignments to the json + std::deque::iterator assignment = domainServerInstance->_assignmentQueue.begin(); + + while (assignment != domainServerInstance->_assignmentQueue.end()) { + QJsonObject queuedAssignmentJSON; + + QString uuidString = uuidStringWithoutCurlyBraces((*assignment)->getUUID()); + queuedAssignmentJSON[ASSIGNMENT_JSON_UUID_KEY] = uuidString; + + // add this queued assignment to the JSON + queuedAssignmentsJSON[(*assignment)->getTypeName()] = queuedAssignmentJSON; + + // push forward the iterator to check the next assignment + assignment++; + } + + assignmentJSON["queued"] = queuedAssignmentsJSON; + + // print out the created JSON + QJsonDocument assignmentDocument(assignmentJSON); + mg_printf(connection, "%s", assignmentDocument.toJson().constData()); + + // we've processed this request + return 1; } - assignmentJSON["fulfilled"] = assignedNodesJSON; - - QJsonObject queuedAssignmentsJSON; - - // add the queued but unfilled assignments to the json - std::deque::iterator assignment = domainServerInstance->_assignmentQueue.begin(); - - while (assignment != domainServerInstance->_assignmentQueue.end()) { - QJsonObject queuedAssignmentJSON; + // not processed, pass to document root + return 0; + } else if (strcmp(ri->request_method, "POST") == 0) { + if (strcmp(ri->uri, ASSIGNMENT_URI) == 0) { + // return a 200 + mg_printf(connection, "%s", RESPONSE_200); + // upload the file + mg_upload(connection, "/tmp"); - QString uuidString = uuidStringWithoutCurlyBraces((*assignment)->getUUID()); - queuedAssignmentJSON[ASSIGNMENT_JSON_UUID_KEY] = uuidString; - - // add this queued assignment to the JSON - queuedAssignmentsJSON[(*assignment)->getTypeName()] = queuedAssignmentJSON; - - // push forward the iterator to check the next assignment - assignment++; + return 1; } - assignmentJSON["queued"] = queuedAssignmentsJSON; - - // print out the created JSON - QJsonDocument assignmentDocument(assignmentJSON); - mg_printf(connection, "%s", assignmentDocument.toJson().constData()); - - // we've processed this request - return 1; + return 0; } else if (strcmp(ri->request_method, "DELETE") == 0) { // this is a DELETE request // check if it is for an assignment - if (memcmp(ri->uri, ASSIGNMENT_URI, sizeof(ASSIGNMENT_URI) - sizeof('\0')) == 0) { + if (memcmp(ri->uri, NODE_URI, strlen(NODE_URI)) == 0) { // pull the UUID from the url - QUuid deleteUUID = QUuid(QString(ri->uri + strlen(ASSIGNMENT_URI) + sizeof('/'))); + QUuid deleteUUID = QUuid(QString(ri->uri + strlen(NODE_URI) + sizeof('/'))); if (!deleteUUID.isNull()) { Node *nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID); From 0d69349ba905fa527dcee548391cbe9c4cafb9da Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 10:39:23 -0700 Subject: [PATCH 08/10] fix prefixed constants --- domain-server/src/DomainServer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 2bfd2629fe..b608483133 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -48,8 +48,8 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { const char RESPONSE_200[] = "HTTP/1.0 200 OK\r\n\r\n"; const char RESPONSE_400[] = "HTTP/1.0 400 Bad Request\r\n\r\n"; - const char ASSIGNMENT_URI[] = "/assignment"; - const char NODE_URI[] = "/node"; + const char URI_ASSIGNMENT[] = "/assignment"; + const char URI_NODE[] = "/node"; if (strcmp(ri->request_method, "GET") == 0) { if (strcmp(ri->uri, "/assignments.json") == 0) { @@ -123,7 +123,7 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { // not processed, pass to document root return 0; } else if (strcmp(ri->request_method, "POST") == 0) { - if (strcmp(ri->uri, ASSIGNMENT_URI) == 0) { + if (strcmp(ri->uri, URI_ASSIGNMENT) == 0) { // return a 200 mg_printf(connection, "%s", RESPONSE_200); // upload the file @@ -137,9 +137,9 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { // this is a DELETE request // check if it is for an assignment - if (memcmp(ri->uri, NODE_URI, strlen(NODE_URI)) == 0) { + if (memcmp(ri->uri, URI_NODE, strlen(URI_NODE)) == 0) { // pull the UUID from the url - QUuid deleteUUID = QUuid(QString(ri->uri + strlen(NODE_URI) + sizeof('/'))); + QUuid deleteUUID = QUuid(QString(ri->uri + strlen(URI_NODE) + sizeof('/'))); if (!deleteUUID.isNull()) { Node *nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID); From 7ca0a26c18f7e9e1b4d88efda691a1e4c4e0b6ac Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 10:44:39 -0700 Subject: [PATCH 09/10] rename method to add assignments back to queue --- domain-server/src/DomainServer.cpp | 8 ++++---- domain-server/src/DomainServer.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index b608483133..565dfb9e2b 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -202,12 +202,12 @@ void DomainServer::civetwebUploadHandler(struct mg_connection *connection, const domainServerInstance->_assignmentQueueMutex.unlock(); } -void DomainServer::addDeletedAssignmentBackToQueue(Assignment* deletedAssignment) { - qDebug() << "Adding assignment" << *deletedAssignment << " back to queue.\n"; +void DomainServer::addReleasedAssignmentBackToQueue(Assignment* releasedAssignment) { + qDebug() << "Adding assignment" << *releasedAssignment << " back to queue.\n"; // find this assignment in the static file for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) { - if (_staticAssignments[i].getUUID() == deletedAssignment->getUUID()) { + if (_staticAssignments[i].getUUID() == releasedAssignment->getUUID()) { // reset the UUID on the static assignment _staticAssignments[i].resetUUID(); @@ -232,7 +232,7 @@ void DomainServer::nodeKilled(Node* node) { if (node->getLinkedData()) { Assignment* nodeAssignment = (Assignment*) node->getLinkedData(); - addDeletedAssignmentBackToQueue(nodeAssignment); + addReleasedAssignmentBackToQueue(nodeAssignment); } } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 78e1f06587..45730847ac 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -47,7 +47,7 @@ private: void removeAssignmentFromQueue(Assignment* removableAssignment); bool checkInWithUUIDMatchesExistingNode(sockaddr* nodePublicSocket, sockaddr* nodeLocalSocket, const QUuid& checkInUUI); void possiblyAddStaticAssignmentsBackToQueueAfterRestart(timeval* startTime); - void addDeletedAssignmentBackToQueue(Assignment* deletedAssignment); + void addReleasedAssignmentBackToQueue(Assignment* releasedAssignment); void cleanup(); From 58b4139dbcd1076f36be91c6600e024702a9b3fc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 18 Oct 2013 14:26:42 -0700 Subject: [PATCH 10/10] Added support for RotationOffset, which the Lulu model uses. --- interface/src/renderer/FBXReader.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/interface/src/renderer/FBXReader.cpp b/interface/src/renderer/FBXReader.cpp index b2d193d106..67acf2f4e2 100644 --- a/interface/src/renderer/FBXReader.cpp +++ b/interface/src/renderer/FBXReader.cpp @@ -565,6 +565,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) jointNeckID = object.properties.at(0).value(); } glm::vec3 translation; + glm::vec3 rotationOffset; glm::vec3 preRotation, rotation, postRotation; glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f); glm::vec3 scalePivot, rotationPivot; @@ -578,6 +579,11 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) property.properties.at(5).value(), property.properties.at(6).value()); + } else if (property.properties.at(0) == "RotationOffset") { + rotationOffset = glm::vec3(property.properties.at(4).value(), + property.properties.at(5).value(), + property.properties.at(6).value()); + } else if (property.properties.at(0) == "RotationPivot") { rotationPivot = glm::vec3(property.properties.at(4).value(), property.properties.at(5).value(), @@ -613,11 +619,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } } // see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html - model.preRotation = glm::translate(translation) * glm::translate(rotationPivot) * - glm::mat4_cast(glm::quat(glm::radians(preRotation))); + model.preRotation = glm::translate(translation) * glm::translate(rotationOffset) * + glm::translate(rotationPivot) * glm::mat4_cast(glm::quat(glm::radians(preRotation))); model.rotation = glm::quat(glm::radians(rotation)); - model.postRotation = glm::mat4_cast(glm::quat(glm::radians(postRotation))) * glm::translate(-rotationPivot) * - glm::translate(scalePivot) * glm::scale(scale) * glm::translate(-scalePivot); + model.postRotation = glm::mat4_cast(glm::quat(glm::radians(postRotation))) * + glm::translate(-rotationPivot) * glm::translate(scalePivot) * + glm::scale(scale) * glm::translate(-scalePivot); models.insert(object.properties.at(0).value(), model); } else if (object.name == "Texture") {