diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 05dbc0ca13..35e1e87303 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1428,6 +1428,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _connectionMonitor.init(); + // Monitor model assets (e.g., from Clara.io) added to the world that may need resizing. + static const int ADD_ASSET_TO_WORLD_TIMER_INTERVAL_MS = 1000; + _addAssetToWorldTimer.setInterval(ADD_ASSET_TO_WORLD_TIMER_INTERVAL_MS); + connect(&_addAssetToWorldTimer, &QTimer::timeout, this, &Application::addAssetToWorldCheckModelSize); + // After all of the constructor is completed, then set firstRun to false. firstRun.set(false); } @@ -5546,7 +5551,7 @@ void Application::addAssetToWorld(QString filePath) { QString path = QUrl(filePath).toLocalFile(); QString mapping = path.right(path.length() - path.lastIndexOf("/")); - _addAssetToWorldMessageBox->setProperty("text", "Adding " + mapping.mid(1) + " to Asset Server"); + _addAssetToWorldMessageBox->setProperty("text", "Adding " + mapping.mid(1) + " to Asset Server."); addAssetToWorldWithNewMapping(path, mapping, 0); } @@ -5645,16 +5650,26 @@ void Application::addAssetToWorldAddEntity(QString mapping) { properties.setName(mapping.right(mapping.length() - 1)); properties.setModelURL("atp:" + mapping); properties.setShapeType(SHAPE_TYPE_SIMPLE_COMPOUND); + properties.setCollisionless(true); // Temporarily set so that doesn't collide with avatar. properties.setDynamic(false); properties.setPosition(getMyAvatar()->getPosition() + getMyAvatar()->getOrientation() * glm::vec3(0.0f, 0.0f, -2.0f)); properties.setGravity(glm::vec3(0.0f, 0.0f, 0.0f)); - auto result = DependencyManager::get()->addEntity(properties); + auto entityID = DependencyManager::get()->addEntity(properties); + // Note: Model dimensions are not available here; model is scaled per FBX mesh in RenderableModelEntityItem::update() later + // on. But FBX dimensions may be in cm or mm, so we monitor for the dimension change and rescale again if warranted. - if (result == QUuid()) { + if (entityID == QUuid()) { QString errorInfo = "Could not add asset " + mapping + " to world."; qWarning(interfaceapp) << "Could not add asset to world: " + errorInfo; addAssetToWorldError(errorInfo); } else { + // Monitor when asset is rendered in world so that can resize if necessary. + _addAssetToWorldResizeList.insert(entityID, 0); // List value is count of checks performed. + if (!_addAssetToWorldTimer.isActive()) { + _addAssetToWorldTimer.start(); + } + + // Inform user. QString successInfo = "Asset " + mapping.mid(1) + " added to world."; qInfo() << "Downloading asset completed: " + successInfo; _addAssetToWorldMessageBox->setProperty("text", successInfo); @@ -5663,6 +5678,62 @@ void Application::addAssetToWorldAddEntity(QString mapping) { } } +void Application::addAssetToWorldCheckModelSize() { + if (_addAssetToWorldResizeList.size() == 0) { + return; + } + + auto item = _addAssetToWorldResizeList.begin(); + while (item != _addAssetToWorldResizeList.end()) { + auto entityID = item.key(); + auto count = item.value(); + + auto entityScriptingInterface = DependencyManager::get(); + auto properties = entityScriptingInterface->getEntityProperties(entityID, EntityPropertyFlags("dimensions")); + auto dimensions = properties.getDimensions(); + const glm::vec3 DEFAULT_DIMENSIONS = glm::vec3(0.1f, 0.1f, 0.1f); + if (dimensions != DEFAULT_DIMENSIONS) { + // Entity has been auto-resized; adjust dimensions if it seems too big. + + const float RESCALE_THRESHOLD = 10.0f; // Resize entities larger than this as the FBX is likely in cm or mm. + if (dimensions.x > RESCALE_THRESHOLD || dimensions.y > RESCALE_THRESHOLD || dimensions.z > RESCALE_THRESHOLD) { + dimensions *= 0.1f; + EntityItemProperties properties; + properties.setDimensions(dimensions); + properties.setCollisionless(false); // Reset to default. + entityScriptingInterface->editEntity(entityID, properties); + qInfo() << "Asset auto-resized"; + } + + item = _addAssetToWorldResizeList.erase(item); // Finished with this entity. + + } else { + // Increment count of checks done. + _addAssetToWorldResizeList[entityID]++; + + const int CHECK_MODEL_SIZE_MAX_CHECKS = 10; + if (_addAssetToWorldResizeList[entityID] > CHECK_MODEL_SIZE_MAX_CHECKS) { + // Have done enough checks; model was either the default size or something's gone wrong. + + EntityItemProperties properties; + properties.setCollisionless(false); // Reset to default. + entityScriptingInterface->editEntity(entityID, properties); + + item = _addAssetToWorldResizeList.erase(item); // Finished with this entity. + + } else { + // No action on this entity; advance to next. + ++item; + } + } + } + + // Stop timer if nothing in list to check. + if (_addAssetToWorldResizeList.size() == 0) { + _addAssetToWorldTimer.stop(); + } +} + void Application::handleUnzip(QString filePath, bool autoAdd) { if (autoAdd && !filePath.isEmpty()) { addAssetToWorld(filePath); diff --git a/interface/src/Application.h b/interface/src/Application.h index 85b8873282..6d3ae90e23 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -320,6 +320,8 @@ public slots: void addAssetToWorldUpload(QString path, QString mapping); void addAssetToWorldSetMapping(QString mapping, QString hash); void addAssetToWorldAddEntity(QString mapping); + void addAssetToWorldCheckModelSize(); + void handleUnzip(QString filePath = "", bool autoAdd = false); FileScriptingInterface* getFileDownloadInterface() { return _fileDownload; } @@ -633,6 +635,8 @@ private: QQuickItem* _addAssetToWorldMessageBox{ nullptr }; void addAssetToWorldError(QString errorText); + QTimer _addAssetToWorldTimer; + QHash _addAssetToWorldResizeList; FileScriptingInterface* _fileDownload; };