From 8affca612095b4a7e24840a6079331fb41cc3e0c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 3 Mar 2015 14:58:53 -0800 Subject: [PATCH 01/13] pass -t to children even if run in parent mode. monitor (parent) only interacts with its own children --- assignment-client/src/AssignmentClient.cpp | 12 +++++----- assignment-client/src/AssignmentClient.h | 4 ++-- assignment-client/src/AssignmentClientApp.cpp | 12 ++++++++-- assignment-client/src/AssignmentClientApp.h | 1 + .../src/AssignmentClientMonitor.cpp | 22 +++++++++++++++---- .../src/AssignmentClientMonitor.h | 7 ++++-- 6 files changed, 42 insertions(+), 16 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index fba96c4967..a0da273462 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -40,8 +40,8 @@ SharedAssignmentPointer AssignmentClient::_currentAssignment; int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); -AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, QUuid walletUUID, - QString assignmentServerHostname, quint16 assignmentServerPort) : +AssignmentClient::AssignmentClient(int ppid, Assignment::Type requestAssignmentType, QString assignmentPool, + QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort) : _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME), _localASPortSharedMem(NULL), _localACMPortSharedMem(NULL) @@ -106,7 +106,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri NetworkAccessManager::getInstance(); // Hook up a timer to send this child's status to the Monitor once per second - setUpStatsToMonitor(); + setUpStatsToMonitor(ppid); } @@ -118,13 +118,13 @@ void AssignmentClient::stopAssignmentClient() { } -void AssignmentClient::setUpStatsToMonitor() { +void AssignmentClient::setUpStatsToMonitor(int ppid) { // Figure out the address to send out stats to quint16 localMonitorServerPort = DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT; auto nodeList = DependencyManager::get(); - nodeList->getLocalServerPortFromSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY, - _localACMPortSharedMem, localMonitorServerPort); + nodeList->getLocalServerPortFromSharedMemory(QString(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY) + "-" + + QString::number(ppid), _localACMPortSharedMem, localMonitorServerPort); _assignmentClientMonitorSocket = HifiSockAddr(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME, localMonitorServerPort, true); // send a stats packet every 1 seconds diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index d1d93c78dc..08673ab04c 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -22,7 +22,7 @@ class AssignmentClient : public QObject { Q_OBJECT public: - AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, + AssignmentClient(int ppid, Assignment::Type requestAssignmentType, QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort); static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } @@ -35,7 +35,7 @@ private slots: void stopAssignmentClient(); private: - void setUpStatsToMonitor(); + void setUpStatsToMonitor(int ppid); Assignment _requestAssignment; static SharedAssignmentPointer _currentAssignment; QString _assignmentServerHostname; diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index cfb77c8542..17f2eac70d 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -78,6 +78,9 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : const QCommandLineOption maxChildsOption(ASSIGNMENT_MAX_FORKS_OPTION, "maximum number of children", "child-count"); parser.addOption(maxChildsOption); + const QCommandLineOption ppidOption(PARENT_PID_OPTION, "parent's process id", "pid"); + parser.addOption(ppidOption); + if (!parser.parse(QCoreApplication::arguments())) { qCritical() << parser.errorText() << endl; @@ -109,6 +112,11 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : maxForks = parser.value(maxChildsOption).toInt(); } + int ppid = 0; + if (parser.isSet(ppidOption)) { + ppid = parser.value(ppidOption).toInt(); + } + if (!numForks && minForks) { // if the user specified --min but not -n, set -n to --min numForks = minForks; @@ -174,11 +182,11 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : if (numForks || minForks || maxForks) { - AssignmentClientMonitor monitor(numForks, minForks, maxForks, assignmentPool, + AssignmentClientMonitor monitor(numForks, minForks, maxForks, requestAssignmentType, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); exec(); } else { - AssignmentClient client(requestAssignmentType, assignmentPool, + AssignmentClient client(ppid, requestAssignmentType, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); exec(); } diff --git a/assignment-client/src/AssignmentClientApp.h b/assignment-client/src/AssignmentClientApp.h index 531035ef0e..7f75f63755 100644 --- a/assignment-client/src/AssignmentClientApp.h +++ b/assignment-client/src/AssignmentClientApp.h @@ -23,6 +23,7 @@ const QString CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION = "p"; const QString ASSIGNMENT_NUM_FORKS_OPTION = "n"; const QString ASSIGNMENT_MIN_FORKS_OPTION = "min"; const QString ASSIGNMENT_MAX_FORKS_OPTION = "max"; +const QString PARENT_PID_OPTION = "ppid"; class AssignmentClientApp : public QCoreApplication { diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index a315fce1a9..1280b55b12 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -20,23 +20,26 @@ #include "PacketHeaders.h" #include "SharedUtil.h" -const char* NUM_FORKS_PARAMETER = "-n"; const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor"; AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmentClientForks, const unsigned int minAssignmentClientForks, const unsigned int maxAssignmentClientForks, - QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, + Assignment::Type requestAssignmentType, QString assignmentPool, + QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort) : _numAssignmentClientForks(numAssignmentClientForks), _minAssignmentClientForks(minAssignmentClientForks), _maxAssignmentClientForks(maxAssignmentClientForks), + _requestAssignmentType(requestAssignmentType), _assignmentPool(assignmentPool), _walletUUID(walletUUID), _assignmentServerHostname(assignmentServerHostname), _assignmentServerPort(assignmentServerPort) { + qDebug() << "_requestAssignmentType =" << _requestAssignmentType; + // start the Logging class with the parent's target name LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); @@ -47,8 +50,10 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClientMonitor::readPendingDatagrams); - nodeList->putLocalPortIntoSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY, this, - nodeList->getNodeSocket().localPort()); + qint64 pid = QCoreApplication::applicationPid (); + + nodeList->putLocalPortIntoSharedMemory(QString(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY) + "-" + QString::number(pid), + this, nodeList->getNodeSocket().localPort()); // use QProcess to fork off a process for each of the child assignment clients for (unsigned int i = 0; i < _numAssignmentClientForks; i++) { @@ -96,6 +101,15 @@ void AssignmentClientMonitor::spawnChildClient() { _childArguments.append("--" + CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION); _childArguments.append(QString::number(_assignmentServerPort)); } + if (_requestAssignmentType != Assignment::AllTypes) { + _childArguments.append("--" + ASSIGNMENT_TYPE_OVERRIDE_OPTION); + _childArguments.append(QString::number(_requestAssignmentType)); + } + + // tell children which shared memory key to use + qint64 pid = QCoreApplication::applicationPid (); + _childArguments.append("--" + PARENT_PID_OPTION); + _childArguments.append(QString::number(pid)); // make sure that the output from the child process appears in our output assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels); diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index dc88bfcd95..996220b1b4 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -28,8 +28,9 @@ class AssignmentClientMonitor : public QObject { Q_OBJECT public: AssignmentClientMonitor(const unsigned int numAssignmentClientForks, const unsigned int minAssignmentClientForks, - const unsigned int maxAssignmentClientForks, QString assignmentPool, QUuid walletUUID, - QString assignmentServerHostname, quint16 assignmentServerPort); + const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType, + QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, + quint16 assignmentServerPort); ~AssignmentClientMonitor(); void stopChildProcesses(); @@ -45,10 +46,12 @@ private: const unsigned int _minAssignmentClientForks; const unsigned int _maxAssignmentClientForks; + Assignment::Type _requestAssignmentType; QString _assignmentPool; QUuid _walletUUID; QString _assignmentServerHostname; quint16 _assignmentServerPort; + }; #endif // hifi_AssignmentClientMonitor_h From 2c68d560594b0b9c8daba51367ca86f4f5d7c16d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Mar 2015 12:34:05 -0800 Subject: [PATCH 02/13] Update Entity::sendEntities to return new entity ids --- libraries/entities/src/EntityTree.cpp | 7 ++++++- libraries/entities/src/EntityTree.h | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 978ba43960..99095aa251 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1000,13 +1000,17 @@ void EntityTree::pruneTree() { recurseTreeWithOperator(&theOperator); } -void EntityTree::sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z) { +QVector EntityTree::sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z) { SendEntitiesOperationArgs args; args.packetSender = packetSender; args.localTree = localTree; args.root = glm::vec3(x, y, z); + QVector newEntityIDs; + args.newEntityIDs = &newEntityIDs; recurseTreeWithOperation(sendEntitiesOperation, &args); packetSender->releaseQueuedMessages(); + + return newEntityIDs; } bool EntityTree::sendEntitiesOperation(OctreeElement* element, void* extraData) { @@ -1016,6 +1020,7 @@ bool EntityTree::sendEntitiesOperation(OctreeElement* element, void* extraData) const QList& entities = entityTreeElement->getEntities(); for (int i = 0; i < entities.size(); i++) { EntityItemID newID(NEW_ENTITY, EntityItemID::getNextCreatorTokenID(), false); + args->newEntityIDs->append(newID); EntityItemProperties properties = entities[i]->getProperties(); properties.setPosition(properties.getPosition() + args->root); properties.markAllChanged(); // so the entire property set is considered new, since we're making a new entity diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index d8b9b9f38f..2935cf56d2 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -39,6 +39,7 @@ public: glm::vec3 root; EntityTree* localTree; EntityEditPacketSender* packetSender; + QVector* newEntityIDs; }; @@ -144,7 +145,7 @@ public: virtual void dumpTree(); virtual void pruneTree(); - void sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z); + QVector sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z); void entityChanged(EntityItem* entity); From a922619ebc2e77db3ff3c99e8728b112bf4b4b34 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Mar 2015 12:36:10 -0800 Subject: [PATCH 03/13] Add Clipboard.exportEntities that takes a list of entity IDs --- interface/src/Application.h | 1 + interface/src/scripting/ClipboardScriptingInterface.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/interface/src/Application.h b/interface/src/Application.h index 91a5f7547b..9c32f32b8f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -324,6 +324,7 @@ public slots: void packetSent(quint64 length); void pasteEntities(float x, float y, float z); + bool exportEntities(const QString& filename, const QStringList& entityIDs); bool exportEntities(const QString& filename, float x, float y, float z, float scale); bool importEntities(const QString& filename); diff --git a/interface/src/scripting/ClipboardScriptingInterface.cpp b/interface/src/scripting/ClipboardScriptingInterface.cpp index 2411cc08eb..6002661011 100644 --- a/interface/src/scripting/ClipboardScriptingInterface.cpp +++ b/interface/src/scripting/ClipboardScriptingInterface.cpp @@ -14,6 +14,10 @@ ClipboardScriptingInterface::ClipboardScriptingInterface() { } +bool ClipboardScriptingInterface::exportEntities(const QString& filename, QStringList entityIDs) { + return Application::getInstance()->exportEntities(filename, entityIDs); +} + bool ClipboardScriptingInterface::exportEntities(const QString& filename, float x, float y, float z, float s) { return Application::getInstance()->exportEntities(filename, x, y, z, s); } From 71768ef27573bba0a6d0740ece7d4f20dccfb7be Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Mar 2015 12:36:45 -0800 Subject: [PATCH 04/13] Return entity IDs on paste --- interface/src/Application.cpp | 4 ++-- interface/src/Application.h | 2 +- interface/src/scripting/ClipboardScriptingInterface.cpp | 4 ++-- interface/src/scripting/ClipboardScriptingInterface.h | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6484e364bc..6f5239a6b2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1683,8 +1683,8 @@ bool Application::importEntities(const QString& filename) { return success; } -void Application::pasteEntities(float x, float y, float z) { - _entityClipboard.sendEntities(&_entityEditSender, _entities.getTree(), x, y, z); +QVector Application::pasteEntities(float x, float y, float z) { + return _entityClipboard.sendEntities(&_entityEditSender, _entities.getTree(), x, y, z); } void Application::initDisplay() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 9c32f32b8f..e027f85538 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -323,7 +323,7 @@ public slots: void nodeKilled(SharedNodePointer node); void packetSent(quint64 length); - void pasteEntities(float x, float y, float z); + QVector pasteEntities(float x, float y, float z); bool exportEntities(const QString& filename, const QStringList& entityIDs); bool exportEntities(const QString& filename, float x, float y, float z, float scale); bool importEntities(const QString& filename); diff --git a/interface/src/scripting/ClipboardScriptingInterface.cpp b/interface/src/scripting/ClipboardScriptingInterface.cpp index 6002661011..a06a0500f3 100644 --- a/interface/src/scripting/ClipboardScriptingInterface.cpp +++ b/interface/src/scripting/ClipboardScriptingInterface.cpp @@ -26,6 +26,6 @@ bool ClipboardScriptingInterface::importEntities(const QString& filename) { return Application::getInstance()->importEntities(filename); } -void ClipboardScriptingInterface::pasteEntities(float x, float y, float z, float s) { - Application::getInstance()->pasteEntities(x, y, z); +QVector ClipboardScriptingInterface::pasteEntities(float x, float y, float z, float s) { + return Application::getInstance()->pasteEntities(x, y, z); } diff --git a/interface/src/scripting/ClipboardScriptingInterface.h b/interface/src/scripting/ClipboardScriptingInterface.h index bc270210dc..bb993c32a4 100644 --- a/interface/src/scripting/ClipboardScriptingInterface.h +++ b/interface/src/scripting/ClipboardScriptingInterface.h @@ -23,8 +23,9 @@ signals: public slots: bool importEntities(const QString& filename); + bool exportEntities(const QString& filename, QStringList entityIDs); bool exportEntities(const QString& filename, float x, float y, float z, float s); - void pasteEntities(float x, float y, float z, float s); + QVector pasteEntities(float x, float y, float z, float s); }; #endif // hifi_ClipboardScriptingInterface_h From 684802550454295528c2fbadb85e6a66c6456e24 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Mar 2015 13:36:16 -0800 Subject: [PATCH 05/13] Add exporting by entity ID to Application --- interface/src/Application.cpp | 41 +++++++++++++++++++ interface/src/Application.h | 2 +- .../scripting/ClipboardScriptingInterface.cpp | 2 +- .../scripting/ClipboardScriptingInterface.h | 2 +- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6f5239a6b2..e63e9f6de5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1633,6 +1633,47 @@ void Application::setActiveFaceTracker() { #endif } +bool Application::exportEntities(const QString& filename, const QVector& entityIDs) { + QVector entities; + + auto entityTree = _entities.getTree(); + EntityTree exportTree; + + glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); + for (auto entityID : entityIDs) { + auto entityItem = entityTree->findEntityByEntityItemID(entityID); + if (!entityItem) { + continue; + } + + auto properties = entityItem->getProperties(); + auto position = properties.getPosition(); + + root.x = glm::min(root.x, position.x); + root.y = glm::min(root.y, position.y); + root.z = glm::min(root.z, position.z); + + entities << entityItem; + } + + if (entities.size() == 0) { + return false; + } + + for (auto entityItem : entities) { + auto properties = entityItem->getProperties(); + + properties.setPosition(properties.getPosition() - root); + exportTree.addEntity(entityItem->getEntityItemID(), properties); + } + + exportTree.writeToSVOFile(filename.toLocal8Bit().constData()); + + // restore the main window's active state + _window->activateWindow(); + return true; +} + bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) { QVector entities; _entities.getTree()->findEntities(AACube(glm::vec3(x / (float)TREE_SCALE, diff --git a/interface/src/Application.h b/interface/src/Application.h index e027f85538..73a3f1658b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -324,7 +324,7 @@ public slots: void packetSent(quint64 length); QVector pasteEntities(float x, float y, float z); - bool exportEntities(const QString& filename, const QStringList& entityIDs); + bool exportEntities(const QString& filename, const QVector& entityIDs); bool exportEntities(const QString& filename, float x, float y, float z, float scale); bool importEntities(const QString& filename); diff --git a/interface/src/scripting/ClipboardScriptingInterface.cpp b/interface/src/scripting/ClipboardScriptingInterface.cpp index a06a0500f3..5c9370771c 100644 --- a/interface/src/scripting/ClipboardScriptingInterface.cpp +++ b/interface/src/scripting/ClipboardScriptingInterface.cpp @@ -14,7 +14,7 @@ ClipboardScriptingInterface::ClipboardScriptingInterface() { } -bool ClipboardScriptingInterface::exportEntities(const QString& filename, QStringList entityIDs) { +bool ClipboardScriptingInterface::exportEntities(const QString& filename, const QVector& entityIDs) { return Application::getInstance()->exportEntities(filename, entityIDs); } diff --git a/interface/src/scripting/ClipboardScriptingInterface.h b/interface/src/scripting/ClipboardScriptingInterface.h index bb993c32a4..9fe676ad03 100644 --- a/interface/src/scripting/ClipboardScriptingInterface.h +++ b/interface/src/scripting/ClipboardScriptingInterface.h @@ -23,7 +23,7 @@ signals: public slots: bool importEntities(const QString& filename); - bool exportEntities(const QString& filename, QStringList entityIDs); + bool exportEntities(const QString& filename, const QVector& entityIDs); bool exportEntities(const QString& filename, float x, float y, float z, float s); QVector pasteEntities(float x, float y, float z, float s); }; From 03c03a20f9866c8a85a3b31e4fb07bb272eb57ef Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Mar 2015 13:52:30 -0800 Subject: [PATCH 06/13] Update pasteEntities to use vec3 --- interface/src/scripting/ClipboardScriptingInterface.cpp | 4 ++-- interface/src/scripting/ClipboardScriptingInterface.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/scripting/ClipboardScriptingInterface.cpp b/interface/src/scripting/ClipboardScriptingInterface.cpp index 5c9370771c..616fc5f141 100644 --- a/interface/src/scripting/ClipboardScriptingInterface.cpp +++ b/interface/src/scripting/ClipboardScriptingInterface.cpp @@ -26,6 +26,6 @@ bool ClipboardScriptingInterface::importEntities(const QString& filename) { return Application::getInstance()->importEntities(filename); } -QVector ClipboardScriptingInterface::pasteEntities(float x, float y, float z, float s) { - return Application::getInstance()->pasteEntities(x, y, z); +QVector ClipboardScriptingInterface::pasteEntities(glm::vec3 position) { + return Application::getInstance()->pasteEntities(position.x, position.y, position.z); } diff --git a/interface/src/scripting/ClipboardScriptingInterface.h b/interface/src/scripting/ClipboardScriptingInterface.h index 9fe676ad03..92204af60d 100644 --- a/interface/src/scripting/ClipboardScriptingInterface.h +++ b/interface/src/scripting/ClipboardScriptingInterface.h @@ -25,7 +25,7 @@ public slots: bool importEntities(const QString& filename); bool exportEntities(const QString& filename, const QVector& entityIDs); bool exportEntities(const QString& filename, float x, float y, float z, float s); - QVector pasteEntities(float x, float y, float z, float s); + QVector pasteEntities(glm::vec3 position); }; #endif // hifi_ClipboardScriptingInterface_h From a2617b2c9668f2d7493e7e40a0d2f9f2120a90cb Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Mar 2015 13:52:59 -0800 Subject: [PATCH 07/13] Update editEntities import/export --- examples/editEntities.js | 42 +++++++++++++++++++++++--------- examples/libraries/ExportMenu.js | 1 - 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index a0f3cdc167..c4d814ff43 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -420,8 +420,6 @@ var toolBar = (function () { }()); -var exportMenu = null; - function isLocked(properties) { // special case to lock the ground plane model in hq. if (location.hostname == "hq.highfidelity.io" && @@ -749,9 +747,6 @@ Script.scriptEnding.connect(function() { tooltip.cleanup(); modelImporter.cleanup(); selectionDisplay.cleanup(); - if (exportMenu) { - exportMenu.close(); - } Entities.setLightsArePickable(originalLightsArePickable); }); @@ -796,15 +791,40 @@ function handeMenuEvent(menuItem) { } else if (menuItem == "Paste Models") { modelImporter.paste(); } else if (menuItem == "Export Models") { - if (!exportMenu) { - exportMenu = new ExportMenu({ - onClose: function () { - exportMenu = null; + if (!selectionManager.hasSelection()) { + Window.alert("No entities have been selected."); + } else { + var filename = "models__" + Window.location.hostname + "__.svo"; + filename = Window.save("Select where to save", filename, "*.svo") + if (filename) { + var success = Clipboard.exportEntities(filename, selectionManager.selections); + if (!success) { + Window.alert("Export failed."); } - }); + } } } else if (menuItem == "Import Models") { - modelImporter.doImport(); + var filename = Window.browse("Select models to import", "", "*.svo") + if (filename) { + var success = Clipboard.importEntities(filename); + + if (success) { + var distance = cameraManager.enabled ? cameraManager.zoomDistance : DEFAULT_ENTITY_DRAG_DROP_DISTANCE; + var direction = Quat.getFront(Camera.orientation); + var offset = Vec3.multiply(distance, direction); + var position = Vec3.sum(Camera.position, offset); + + position.x = Math.max(0, position.x); + position.y = Math.max(0, position.y); + position.z = Math.max(0, position.z); + + var pastedEntityIDs = Clipboard.pasteEntities(position); + + selectionManager.setSelections(pastedEntityIDs); + } else { + Window.alert("There was an error importing the entity file."); + } + } } else if (menuItem == "Entity List...") { entityListTool.toggleVisible(); } diff --git a/examples/libraries/ExportMenu.js b/examples/libraries/ExportMenu.js index 247391808f..dd6dcd4324 100644 --- a/examples/libraries/ExportMenu.js +++ b/examples/libraries/ExportMenu.js @@ -219,6 +219,5 @@ ExportMenu = function (opts) { Overlays.deleteOverlay(scaleView); }; - print("CONNECTING!"); Controller.mouseReleaseEvent.connect(this.mouseReleaseEvent); }; From 08b905095d50c1c09e5ee7223046f450e4bc5b95 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Mar 2015 13:54:27 -0800 Subject: [PATCH 08/13] Remove Paste Models and rename Import/Export to Entities --- examples/editEntities.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index c4d814ff43..6d7d0c7cb4 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -692,17 +692,16 @@ function setupModelMenus() { } Menu.addMenuItem({ menuName: "Edit", menuItemName: "Entity List...", shortcutKey: "CTRL+META+L", afterItem: "Models" }); - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Paste Models", shortcutKey: "CTRL+META+V", afterItem: "Entity List..." }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Large Models", shortcutKey: "CTRL+META+L", - afterItem: "Paste Models", isCheckable: true, isChecked: true }); + afterItem: "Entity List...", isCheckable: true, isChecked: true }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Small Models", shortcutKey: "CTRL+META+S", afterItem: "Allow Selecting of Large Models", isCheckable: true, isChecked: true }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Lights", shortcutKey: "CTRL+SHIFT+META+L", afterItem: "Allow Selecting of Small Models", isCheckable: true }); Menu.addMenuItem({ menuName: "File", menuItemName: "Models", isSeparator: true, beforeItem: "Settings" }); - Menu.addMenuItem({ menuName: "File", menuItemName: "Export Models", shortcutKey: "CTRL+META+E", afterItem: "Models" }); - Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" }); + Menu.addMenuItem({ menuName: "File", menuItemName: "Export Entities", shortcutKey: "CTRL+META+E", afterItem: "Models" }); + Menu.addMenuItem({ menuName: "File", menuItemName: "Import Entities", shortcutKey: "CTRL+META+I", afterItem: "Export Entities" }); Menu.addMenuItem({ menuName: "View", menuItemName: MENU_AUTO_FOCUS_ON_SELECT, afterItem: MENU_INSPECT_TOOL_ENABLED, @@ -723,14 +722,13 @@ function cleanupModelMenus() { } Menu.removeMenuItem("Edit", "Entity List..."); - Menu.removeMenuItem("Edit", "Paste Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Large Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Small Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Lights"); Menu.removeSeparator("File", "Models"); - Menu.removeMenuItem("File", "Export Models"); - Menu.removeMenuItem("File", "Import Models"); + Menu.removeMenuItem("File", "Export Entities"); + Menu.removeMenuItem("File", "Import Entities"); Menu.removeMenuItem("View", MENU_INSPECT_TOOL_ENABLED); Menu.removeMenuItem("View", MENU_AUTO_FOCUS_ON_SELECT); @@ -745,7 +743,6 @@ Script.scriptEnding.connect(function() { toolBar.cleanup(); cleanupModelMenus(); tooltip.cleanup(); - modelImporter.cleanup(); selectionDisplay.cleanup(); Entities.setLightsArePickable(originalLightsArePickable); }); @@ -788,9 +785,7 @@ function handeMenuEvent(menuItem) { Entities.setLightsArePickable(Menu.isOptionChecked("Allow Selecting of Lights")); } else if (menuItem == "Delete") { deleteSelectedEntities(); - } else if (menuItem == "Paste Models") { - modelImporter.paste(); - } else if (menuItem == "Export Models") { + } else if (menuItem == "Export Entities") { if (!selectionManager.hasSelection()) { Window.alert("No entities have been selected."); } else { @@ -803,7 +798,7 @@ function handeMenuEvent(menuItem) { } } } - } else if (menuItem == "Import Models") { + } else if (menuItem == "Import Entities") { var filename = Window.browse("Select models to import", "", "*.svo") if (filename) { var success = Clipboard.importEntities(filename); From 9247ccd7b321d21f1faad788022933923e9b0945 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Mar 2015 13:55:22 -0800 Subject: [PATCH 09/13] Remove ExportMenu.js and ModelImporter.js --- examples/editEntities.js | 3 - examples/libraries/ExportMenu.js | 223 ---------------------------- examples/libraries/ModelImporter.js | 200 ------------------------- 3 files changed, 426 deletions(-) delete mode 100644 examples/libraries/ExportMenu.js delete mode 100644 examples/libraries/ModelImporter.js diff --git a/examples/editEntities.js b/examples/editEntities.js index 6d7d0c7cb4..e6d4534b86 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -22,9 +22,7 @@ Script.include([ "libraries/progressDialog.js", "libraries/entitySelectionTool.js", - "libraries/ModelImporter.js", - "libraries/ExportMenu.js", "libraries/ToolTip.js", "libraries/entityPropertyDialogBox.js", @@ -35,7 +33,6 @@ Script.include([ var selectionDisplay = SelectionDisplay; var selectionManager = SelectionManager; -var modelImporter = new ModelImporter(); var entityPropertyDialogBox = EntityPropertyDialogBox; var cameraManager = new CameraManager(); diff --git a/examples/libraries/ExportMenu.js b/examples/libraries/ExportMenu.js deleted file mode 100644 index dd6dcd4324..0000000000 --- a/examples/libraries/ExportMenu.js +++ /dev/null @@ -1,223 +0,0 @@ -// -// ExportMenu.js -// examples/libraries -// -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -ExportMenu = function (opts) { - var self = this; - - var windowDimensions = Controller.getViewportDimensions(); - var pos = { x: windowDimensions.x / 2, y: windowDimensions.y - 100 }; - - this._onClose = opts.onClose || function () { }; - this._position = { x: 0.0, y: 0.0, z: 0.0 }; - this._scale = 1.0; - - var minScale = 1; - var maxScale = 32768; - var titleWidth = 120; - var locationWidth = 100; - var scaleWidth = 144; - var exportWidth = 100; - var cancelWidth = 100; - var margin = 4; - var height = 30; - var outerHeight = height + (2 * margin); - var buttonColor = { red: 128, green: 128, blue: 128 }; - - var SCALE_MINUS = scaleWidth * 40.0 / 100.0; - var SCALE_PLUS = scaleWidth * 63.0 / 100.0; - - var fullWidth = locationWidth + scaleWidth + exportWidth + cancelWidth + (2 * margin); - var offset = fullWidth / 2; - pos.x -= offset; - - var background = Overlays.addOverlay("text", { - x: pos.x, - y: pos.y, - opacity: 1, - width: fullWidth, - height: outerHeight, - backgroundColor: { red: 200, green: 200, blue: 200 }, - text: "", - }); - - var titleText = Overlays.addOverlay("text", { - x: pos.x, - y: pos.y - height, - font: { size: 14 }, - width: titleWidth, - height: height, - backgroundColor: { red: 255, green: 255, blue: 255 }, - color: { red: 255, green: 255, blue: 255 }, - text: "Export Models" - }); - - var locationButton = Overlays.addOverlay("text", { - x: pos.x + margin, - y: pos.y + margin, - width: locationWidth, - height: height, - color: { red: 255, green: 255, blue: 255 }, - text: "0, 0, 0", - }); - var scaleOverlay = Overlays.addOverlay("image", { - x: pos.x + margin + locationWidth, - y: pos.y + margin, - width: scaleWidth, - height: height, - subImage: { x: 0, y: 3, width: 144, height: height }, - imageURL: toolIconUrl + "voxel-size-selector.svg", - alpha: 0.9, - }); - var scaleViewWidth = 40; - var scaleView = Overlays.addOverlay("text", { - x: pos.x + margin + locationWidth + SCALE_MINUS, - y: pos.y + margin, - width: scaleViewWidth, - height: height, - backgroundAlpha: 0.0, - color: { red: 255, green: 255, blue: 255 }, - text: "1" - }); - var exportButton = Overlays.addOverlay("text", { - x: pos.x + margin + locationWidth + scaleWidth, - y: pos.y + margin, - width: exportWidth, - height: height, - color: { red: 0, green: 255, blue: 255 }, - text: "Export" - }); - var cancelButton = Overlays.addOverlay("text", { - x: pos.x + margin + locationWidth + scaleWidth + exportWidth, - y: pos.y + margin, - width: cancelWidth, - height: height, - color: { red: 255, green: 255, blue: 255 }, - text: "Cancel" - }); - - var voxelPreview = Overlays.addOverlay("cube", { - position: { x: 0, y: 0, z: 0 }, - size: this._scale, - color: { red: 255, green: 255, blue: 0 }, - alpha: 1, - solid: false, - visible: true, - lineWidth: 4 - }); - - this.parsePosition = function (str) { - var parts = str.split(','); - if (parts.length == 3) { - var x = parseFloat(parts[0]); - var y = parseFloat(parts[1]); - var z = parseFloat(parts[2]); - if (isFinite(x) && isFinite(y) && isFinite(z)) { - return { x: x, y: y, z: z }; - } - } - return null; - }; - - this.showPositionPrompt = function () { - var positionStr = self._position.x + ", " + self._position.y + ", " + self._position.z; - while (1) { - positionStr = Window.prompt("Position to export form:", positionStr); - if (positionStr == null) { - break; - } - var position = self.parsePosition(positionStr); - if (position != null) { - self.setPosition(position.x, position.y, position.z); - break; - } - Window.alert("The position you entered was invalid."); - } - }; - - this.setScale = function (scale) { - self._scale = Math.min(maxScale, Math.max(minScale, scale)); - Overlays.editOverlay(scaleView, { text: self._scale }); - Overlays.editOverlay(voxelPreview, { size: self._scale }); - } - - this.decreaseScale = function () { - self.setScale(self._scale /= 2); - } - - this.increaseScale = function () { - self.setScale(self._scale *= 2); - } - - this.exportEntities = function() { - var x = self._position.x; - var y = self._position.y; - var z = self._position.z; - var s = self._scale; - var filename = "models__" + Window.location.hostname + "__" + x + "_" + y + "_" + z + "_" + s + "__.svo"; - filename = Window.save("Select where to save", filename, "*.svo") - if (filename) { - var success = Clipboard.exportEntities(filename, x, y, z, s); - if (!success) { - Window.alert("Export failed: no models found in selected area."); - } - } - self.close(); - }; - - this.getPosition = function () { - return self._position; - }; - - this.setPosition = function (x, y, z) { - self._position = { x: x, y: y, z: z }; - var positionStr = x + ", " + y + ", " + z; - Overlays.editOverlay(locationButton, { text: positionStr }); - Overlays.editOverlay(voxelPreview, { position: self._position }); - - }; - - this.mouseReleaseEvent = function (event) { - var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); - - if (clickedOverlay == locationButton) { - self.showPositionPrompt(); - } else if (clickedOverlay == exportButton) { - self.exportEntities(); - } else if (clickedOverlay == cancelButton) { - self.close(); - } else if (clickedOverlay == scaleOverlay) { - var x = event.x - pos.x - margin - locationWidth; - print(x); - if (x < SCALE_MINUS) { - self.decreaseScale(); - } else if (x > SCALE_PLUS) { - self.increaseScale(); - } - } - }; - - this.close = function () { - this.cleanup(); - this._onClose(); - }; - - this.cleanup = function () { - Overlays.deleteOverlay(background); - Overlays.deleteOverlay(titleText); - Overlays.deleteOverlay(locationButton); - Overlays.deleteOverlay(exportButton); - Overlays.deleteOverlay(cancelButton); - Overlays.deleteOverlay(voxelPreview); - Overlays.deleteOverlay(scaleOverlay); - Overlays.deleteOverlay(scaleView); - }; - - Controller.mouseReleaseEvent.connect(this.mouseReleaseEvent); -}; diff --git a/examples/libraries/ModelImporter.js b/examples/libraries/ModelImporter.js deleted file mode 100644 index 1e52c8fdec..0000000000 --- a/examples/libraries/ModelImporter.js +++ /dev/null @@ -1,200 +0,0 @@ -// -// ModelImporter.js -// examples/libraries -// -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - - -ModelImporter = function (opts) { - var self = this; - - var windowDimensions = Controller.getViewportDimensions(); - - var height = 30; - var margin = 4; - var outerHeight = height + (2 * margin); - var titleWidth = 120; - var cancelWidth = 100; - var fullWidth = titleWidth + cancelWidth + (2 * margin); - - var localModels = Overlays.addOverlay("localmodels", { - position: { x: 1, y: 1, z: 1 }, - scale: 1, - visible: false - }); - var importScale = 1; - var importBoundaries = Overlays.addOverlay("cube", { - position: { x: 0, y: 0, z: 0 }, - size: 1, - color: { red: 128, blue: 128, green: 128 }, - lineWidth: 4, - solid: false, - visible: false - }); - - var pos = { x: windowDimensions.x / 2 - (fullWidth / 2), y: windowDimensions.y - 100 }; - - var background = Overlays.addOverlay("text", { - x: pos.x, - y: pos.y, - opacity: 1, - width: fullWidth, - height: outerHeight, - backgroundColor: { red: 200, green: 200, blue: 200 }, - visible: false, - text: "", - }); - - var titleText = Overlays.addOverlay("text", { - x: pos.x + margin, - y: pos.y + margin, - font: { size: 14 }, - width: titleWidth, - height: height, - backgroundColor: { red: 255, green: 255, blue: 255 }, - color: { red: 255, green: 255, blue: 255 }, - visible: false, - text: "Import Models" - }); - var cancelButton = Overlays.addOverlay("text", { - x: pos.x + margin + titleWidth, - y: pos.y + margin, - width: cancelWidth, - height: height, - color: { red: 255, green: 255, blue: 255 }, - visible: false, - text: "Close" - }); - this._importing = false; - - this.setImportVisible = function (visible) { - Overlays.editOverlay(importBoundaries, { visible: visible }); - Overlays.editOverlay(localModels, { visible: visible }); - Overlays.editOverlay(cancelButton, { visible: visible }); - Overlays.editOverlay(titleText, { visible: visible }); - Overlays.editOverlay(background, { visible: visible }); - }; - - var importPosition = { x: 0, y: 0, z: 0 }; - this.moveImport = function (position) { - importPosition = position; - Overlays.editOverlay(localModels, { - position: { x: importPosition.x, y: importPosition.y, z: importPosition.z } - }); - Overlays.editOverlay(importBoundaries, { - position: { x: importPosition.x, y: importPosition.y, z: importPosition.z } - }); - } - - this.mouseMoveEvent = function (event) { - if (self._importing) { - var pickRay = Camera.computePickRay(event.x, event.y); - var intersection = Entities.findRayIntersection(pickRay); - - var distance = 2;// * self._scale; - - if (false) {//intersection.intersects) { - var intersectionDistance = Vec3.length(Vec3.subtract(pickRay.origin, intersection.intersection)); - if (intersectionDistance < distance) { - distance = intersectionDistance * 0.99; - } - - } - - var targetPosition = { - x: pickRay.origin.x + (pickRay.direction.x * distance), - y: pickRay.origin.y + (pickRay.direction.y * distance), - z: pickRay.origin.z + (pickRay.direction.z * distance) - }; - - if (targetPosition.x < 0) targetPosition.x = 0; - if (targetPosition.y < 0) targetPosition.y = 0; - if (targetPosition.z < 0) targetPosition.z = 0; - - var nudgeFactor = 1; - var newPosition = { - x: Math.floor(targetPosition.x / nudgeFactor) * nudgeFactor, - y: Math.floor(targetPosition.y / nudgeFactor) * nudgeFactor, - z: Math.floor(targetPosition.z / nudgeFactor) * nudgeFactor - } - - self.moveImport(newPosition); - } - } - - this.mouseReleaseEvent = function (event) { - var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); - - if (clickedOverlay == cancelButton) { - self._importing = false; - self.setImportVisible(false); - } - }; - - // Would prefer to use {4} for the coords, but it would only capture the last digit. - var fileRegex = /__(.+)__(\d+(?:\.\d+)?)_(\d+(?:\.\d+)?)_(\d+(?:\.\d+)?)_(\d+(?:\.\d+)?)__/; - this.doImport = function () { - if (!self._importing) { - var filename = Window.browse("Select models to import", "", "*.svo") - if (filename) { - parts = fileRegex.exec(filename); - if (parts == null) { - Window.alert("The file you selected does not contain source domain or location information"); - } else { - var hostname = parts[1]; - var x = parts[2]; - var y = parts[3]; - var z = parts[4]; - var s = parts[5]; - importScale = s; - if (hostname != location.hostname) { - if (!Window.confirm(("These models were not originally exported from this domain. Continue?"))) { - return; - } - } else { - if (Window.confirm(("Would you like to import back to the source location?"))) { - var success = Clipboard.importEntities(filename); - if (success) { - Clipboard.pasteEntities(x, y, z, 1); - } else { - Window.alert("There was an error importing the entity file."); - } - return; - } - } - } - var success = Clipboard.importEntities(filename); - if (success) { - self._importing = true; - self.setImportVisible(true); - Overlays.editOverlay(importBoundaries, { size: s }); - } else { - Window.alert("There was an error importing the entity file."); - } - } - } - } - - this.paste = function () { - if (self._importing) { - // self._importing = false; - // self.setImportVisible(false); - Clipboard.pasteEntities(importPosition.x, importPosition.y, importPosition.z, 1); - } - } - - this.cleanup = function () { - Overlays.deleteOverlay(localModels); - Overlays.deleteOverlay(importBoundaries); - Overlays.deleteOverlay(cancelButton); - Overlays.deleteOverlay(titleText); - Overlays.deleteOverlay(background); - } - - Controller.mouseReleaseEvent.connect(this.mouseReleaseEvent); - Controller.mouseMoveEvent.connect(this.mouseMoveEvent); -}; From b3631de93c4564e6b53d01acc56819941e0db5a1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 6 Mar 2015 12:03:36 -0800 Subject: [PATCH 10/13] Remove print statements from entityList.js --- examples/libraries/entityList.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/libraries/entityList.js b/examples/libraries/entityList.js index 8fbc40698f..942edf18b6 100644 --- a/examples/libraries/entityList.js +++ b/examples/libraries/entityList.js @@ -28,7 +28,6 @@ EntityListTool = function(opts) { type: 'selectionUpdate', selectedIDs: selectedIDs, }; - print("Sending: " + JSON.stringify(data)); webView.eventBridge.emitScriptEvent(JSON.stringify(data)); }); @@ -59,7 +58,6 @@ EntityListTool = function(opts) { } webView.eventBridge.webEventReceived.connect(function(data) { - print("Got: " + data); data = JSON.parse(data); if (data.type == "selectionUpdate") { var ids = data.entityIds; From ffab6ffe489ae6b2853c499c5830fc1348e9dc36 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 6 Mar 2015 15:11:02 -0800 Subject: [PATCH 11/13] tweaks to hacks for detecting mixamo files --- interface/src/ModelUploader.cpp | 14 ++++++++++++-- libraries/fbx/src/FBXReader.cpp | 3 +++ libraries/fbx/src/FBXReader.h | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index ad73d119a3..a2b729ad39 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -311,8 +311,18 @@ void ModelUploader::populateBasicMapping(QVariantHash& mapping, QString filename mapping.insertMulti(FREE_JOINT_FIELD, "RightForeArm"); } - // mixamo blendshapes - if (!mapping.contains(BLENDSHAPE_FIELD) && geometry.applicationName == "mixamo.com") { + // mixamo blendshapes - in the event that a mixamo file was edited by some other tool, it's likely the applicationName will + // be rewritten, so we detect the existence of several different blendshapes which indicate we're likely a mixamo file + bool likelyMixamoFile = geometry.applicationName == "mixamo.com" || + (geometry.blendshapeChannelNames.contains("BrowsDown_Left") && + geometry.blendshapeChannelNames.contains("BrowsDown_Right") && + geometry.blendshapeChannelNames.contains("MouthOpen") && + geometry.blendshapeChannelNames.contains("TongueUp") && + geometry.blendshapeChannelNames.contains("MouthWhistle_NarrowAdjust_Left") && + geometry.blendshapeChannelNames.contains("NoseScrunch_Left") && + geometry.blendshapeChannelNames.contains("Squint_Right")); + + if (!mapping.contains(BLENDSHAPE_FIELD) && likelyMixamoFile) { QVariantHash blendshapes; blendshapes.insertMulti("BrowsD_L", QVariantList() << "BrowsDown_Left" << 1.0); blendshapes.insertMulti("BrowsD_R", QVariantList() << "BrowsDown_Right" << 1.0); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 72d153289a..cbbaae3d82 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1266,6 +1266,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, QVector humanIKJointIDs(humanIKJointNames.size()); QVariantHash blendshapeMappings = mapping.value("bs").toHash(); + QMultiHash blendshapeIndices; for (int i = 0;; i++) { QByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i]; @@ -1720,12 +1721,14 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, } else if (object.properties.last() == "BlendShapeChannel") { QByteArray name = object.properties.at(1).toByteArray(); + name = name.left(name.indexOf('\0')); if (!blendshapeIndices.contains(name)) { // try everything after the dot name = name.mid(name.lastIndexOf('.') + 1); } QString id = getID(object.properties); + geometry.blendshapeChannelNames << name; foreach (const WeightedIndex& index, blendshapeIndices.values(name)) { blendshapeChannelIndices.insert(id, index); } diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 3f6f836950..6912dd730f 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -257,6 +257,8 @@ public: /// given a meshIndex this will return the name of the model that mesh belongs to if known QString getModelNameOfMesh(int meshIndex) const; + + QList blendshapeChannelNames; }; Q_DECLARE_METATYPE(FBXGeometry) From 7c78e598b84c1cae1f7d346498effd2a83258ffb Mon Sep 17 00:00:00 2001 From: Grayson Stebbins Date: Fri, 6 Mar 2015 15:15:48 -0800 Subject: [PATCH 12/13] Update to .com instead of .io in Welcome dialog --- interface/resources/html/interface-welcome.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/html/interface-welcome.html b/interface/resources/html/interface-welcome.html index d632cb0e5c..ed905eb392 100644 --- a/interface/resources/html/interface-welcome.html +++ b/interface/resources/html/interface-welcome.html @@ -154,7 +154,7 @@ devour all we've written and make
suggestions where necessary.
Documentation is always at
- docs.highfidelity.io + docs.highfidelity.com

@@ -187,4 +187,4 @@ } - \ No newline at end of file + From a4963f18953a974a72148c39385b1b55c0b78336 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 6 Mar 2015 15:22:25 -0800 Subject: [PATCH 13/13] render application overlay only if enabled --- interface/src/Application.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6484e364bc..5aff8f0310 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -772,13 +772,10 @@ void Application::paintGL() { DependencyManager::get()->render(); - { + if (Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) { PerformanceTimer perfTimer("renderOverlay"); - // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() _applicationOverlay.renderOverlay(true); - if (Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) { - _applicationOverlay.displayOverlayTexture(); - } + _applicationOverlay.displayOverlayTexture(); } }