diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index e50c7180d1..4efc3343d1 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -354,15 +354,16 @@ void Agent::scriptRequestFinished() { void Agent::executeScript() { - _scriptEngine = std::unique_ptr(new ScriptEngine(ScriptEngine::AGENT_SCRIPT, _scriptContents, _payload)); + _scriptEngine = scriptEngineFactory(ScriptEngine::AGENT_SCRIPT, _scriptContents, _payload); _scriptEngine->setParent(this); // be the parent of the script engine so it gets moved when we do - DependencyManager::get()->setScriptEngine(_scriptEngine.get()); + DependencyManager::get()->setScriptEngine(_scriptEngine); // setup an Avatar for the script to use auto scriptedAvatar = DependencyManager::get(); - connect(_scriptEngine.get(), SIGNAL(update(float)), scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection); + connect(_scriptEngine.data(), SIGNAL(update(float)), + scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection); scriptedAvatar->setForceFaceTrackerConnected(true); // call model URL setters with empty URLs so our avatar, if user, will have the default models diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index b10f72db9a..168da185b6 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -88,7 +88,7 @@ private: void encodeFrameOfZeros(QByteArray& encodedZeros); void computeLoudness(const QByteArray* decodedBuffer, QSharedPointer); - std::unique_ptr _scriptEngine; + ScriptEnginePointer _scriptEngine; EntityEditPacketSender _entityEditSender; EntityTreeHeadlessViewer _entityViewer; diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index e7433e7c05..fd53ab2391 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -415,8 +415,7 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) { void EntityScriptServer::resetEntitiesScriptEngine() { auto engineName = QString("about:Entities %1").arg(++_entitiesScriptEngineCount); - auto newEngine = QSharedPointer(new ScriptEngine(ScriptEngine::ENTITY_SERVER_SCRIPT, NO_SCRIPT, engineName), - &ScriptEngine::deleteLater); + auto newEngine = scriptEngineFactory(ScriptEngine::ENTITY_SERVER_SCRIPT, NO_SCRIPT, engineName); auto webSocketServerConstructorValue = newEngine->newFunction(WebSocketServerClass::constructor); newEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue); @@ -437,11 +436,14 @@ void EntityScriptServer::resetEntitiesScriptEngine() { newEngine->runInThread(); - DependencyManager::get()->setEntitiesScriptEngine(newEngine.data()); + auto newEngineSP = qSharedPointerCast(newEngine); + DependencyManager::get()->setEntitiesScriptEngine(newEngineSP); - disconnect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, this, &EntityScriptServer::updateEntityPPS); + disconnect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, + this, &EntityScriptServer::updateEntityPPS); _entitiesScriptEngine.swap(newEngine); - connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, this, &EntityScriptServer::updateEntityPPS); + connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, + this, &EntityScriptServer::updateEntityPPS); } diff --git a/assignment-client/src/scripts/EntityScriptServer.h b/assignment-client/src/scripts/EntityScriptServer.h index 84454375e5..e6bd12460b 100644 --- a/assignment-client/src/scripts/EntityScriptServer.h +++ b/assignment-client/src/scripts/EntityScriptServer.h @@ -72,7 +72,7 @@ private: bool _shuttingDown { false }; static int _entitiesScriptEngineCount; - QSharedPointer _entitiesScriptEngine; + ScriptEnginePointer _entitiesScriptEngine; EntityEditPacketSender _entityEditSender; EntityTreeHeadlessViewer _entityViewer; diff --git a/interface/resources/qml/dialogs/FileDialog.qml b/interface/resources/qml/dialogs/FileDialog.qml index 106e067968..b9633104d5 100644 --- a/interface/resources/qml/dialogs/FileDialog.qml +++ b/interface/resources/qml/dialogs/FileDialog.qml @@ -486,9 +486,9 @@ ModalWindow { model: filesModel function updateSort() { - model.sortOrder = sortIndicatorOrder; - model.sortColumn = sortIndicatorColumn; - model.update(); + fileTableModel.sortOrder = sortIndicatorOrder; + fileTableModel.sortColumn = sortIndicatorColumn; + fileTableModel.update(); } onSortIndicatorColumnChanged: { updateSort(); } diff --git a/interface/resources/qml/dialogs/TabletFileDialog.qml b/interface/resources/qml/dialogs/TabletFileDialog.qml index 9e1d0a9f5a..d3b738469e 100644 --- a/interface/resources/qml/dialogs/TabletFileDialog.qml +++ b/interface/resources/qml/dialogs/TabletFileDialog.qml @@ -484,9 +484,9 @@ TabletModalWindow { model: filesModel function updateSort() { - model.sortOrder = sortIndicatorOrder; - model.sortColumn = sortIndicatorColumn; - model.update(); + fileTableModel.sortOrder = sortIndicatorOrder; + fileTableModel.sortColumn = sortIndicatorColumn; + fileTableModel.update(); } onSortIndicatorColumnChanged: { updateSort(); } diff --git a/interface/resources/qml/hifi/LetterboxMessage.qml b/interface/resources/qml/hifi/LetterboxMessage.qml index 6f41154d4d..7ce66adf11 100644 --- a/interface/resources/qml/hifi/LetterboxMessage.qml +++ b/interface/resources/qml/hifi/LetterboxMessage.qml @@ -137,48 +137,11 @@ Item { } } } - // Left gray MouseArea MouseArea { - anchors.left: parent.left; - anchors.right: textContainer.left; - anchors.top: textContainer.top; - anchors.bottom: textContainer.bottom; + anchors.fill: parent acceptedButtons: Qt.LeftButton onClicked: { - letterbox.visible = false - } - } - // Right gray MouseArea - MouseArea { - anchors.left: textContainer.left; - anchors.right: parent.left; - anchors.top: textContainer.top; - anchors.bottom: textContainer.bottom; - acceptedButtons: Qt.LeftButton - onClicked: { - letterbox.visible = false - } - } - // Top gray MouseArea - MouseArea { - anchors.left: parent.left; - anchors.right: parent.right; - anchors.top: parent.top; - anchors.bottom: textContainer.top; - acceptedButtons: Qt.LeftButton - onClicked: { - letterbox.visible = false - } - } - // Bottom gray MouseArea - MouseArea { - anchors.left: parent.left; - anchors.right: parent.right; - anchors.top: textContainer.bottom; - anchors.bottom: parent.bottom; - acceptedButtons: Qt.LeftButton - onClicked: { - letterbox.visible = false + letterbox.visible = false; } } } diff --git a/interface/resources/qml/hifi/dialogs/RunningScripts.qml b/interface/resources/qml/hifi/dialogs/RunningScripts.qml index 952cc03733..c949be319f 100644 --- a/interface/resources/qml/hifi/dialogs/RunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/RunningScripts.qml @@ -387,9 +387,9 @@ ScrollingWindow { readOnly: true Connections { - target: treeView + target: treeView.selection onCurrentIndexChanged: { - var path = scriptsModel.data(treeView.currentIndex, 0x100) + var path = scriptsModel.data(treeView.selection.currentIndex, 0x100) if (path) { selectedScript.text = path } else { diff --git a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml index 5677cc92a1..340d2e9ac7 100644 --- a/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/TabletRunningScripts.qml @@ -416,9 +416,9 @@ Rectangle { readOnly: true Connections { - target: treeView + target: treeView.selection onCurrentIndexChanged: { - var path = scriptsModel.data(treeView.currentIndex, 0x100) + var path = scriptsModel.data(treeView.selection.currentIndex, 0x100) if (path) { selectedScript.text = path } else { diff --git a/interface/resources/qml/hifi/tablet/WindowRoot.qml b/interface/resources/qml/hifi/tablet/WindowRoot.qml index 94847b2973..e3170f85ef 100644 --- a/interface/resources/qml/hifi/tablet/WindowRoot.qml +++ b/interface/resources/qml/hifi/tablet/WindowRoot.qml @@ -14,6 +14,8 @@ import "../../windows" as Windows import QtQuick 2.0 import Hifi 1.0 +import Qt.labs.settings 1.0 + Windows.ScrollingWindow { id: tabletRoot objectName: "tabletRoot" @@ -25,8 +27,32 @@ Windows.ScrollingWindow { shown: false resizable: false + Settings { + id: settings + category: "WindowRoot.Windows" + property real width: 480 + property real height: 706 + } + + onResizableChanged: { + if (!resizable) { + // restore default size + settings.width = tabletRoot.width + settings.height = tabletRoot.height + tabletRoot.width = 480 + tabletRoot.height = 706 + } else { + tabletRoot.width = settings.width + tabletRoot.height = settings.height + } + } + signal showDesktop(); + function setResizable(value) { + tabletRoot.resizable = value; + } + function setMenuProperties(rootMenu, subMenu) { tabletRoot.rootMenu = rootMenu; tabletRoot.subMenu = subMenu; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index de1269c3ae..9de0154f1c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -963,7 +963,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo DependencyManager::get().data(), &AddressManager::storeCurrentAddress); auto scriptEngines = DependencyManager::get().data(); - scriptEngines->registerScriptInitializer([this](ScriptEngine* engine){ + scriptEngines->registerScriptInitializer([this](ScriptEnginePointer engine){ registerScriptEngineWithApplicationServices(engine); }); @@ -5226,7 +5226,7 @@ void Application::update(float deltaTime) { } } - avatarManager->postUpdate(deltaTime); + avatarManager->postUpdate(deltaTime, getMain3DScene()); { PROFILE_RANGE_EX(app, "PreRenderLambdas", 0xffff0000, (uint64_t)0); @@ -5947,7 +5947,7 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer void Application::packetSent(quint64 length) { } -void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) { +void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) { scriptEngine->setEmitScriptUpdatesFunction([this]() { SharedNodePointer entityServerNode = DependencyManager::get()->soloNodeOfType(NodeType::EntityServer); @@ -5982,29 +5982,31 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri ClipboardScriptingInterface* clipboardScriptable = new ClipboardScriptingInterface(); scriptEngine->registerGlobalObject("Clipboard", clipboardScriptable); - connect(scriptEngine, &ScriptEngine::finished, clipboardScriptable, &ClipboardScriptingInterface::deleteLater); + connect(scriptEngine.data(), &ScriptEngine::finished, clipboardScriptable, &ClipboardScriptingInterface::deleteLater); scriptEngine->registerGlobalObject("Overlays", &_overlays); - qScriptRegisterMetaType(scriptEngine, OverlayPropertyResultToScriptValue, OverlayPropertyResultFromScriptValue); - qScriptRegisterMetaType(scriptEngine, RayToOverlayIntersectionResultToScriptValue, + qScriptRegisterMetaType(scriptEngine.data(), OverlayPropertyResultToScriptValue, OverlayPropertyResultFromScriptValue); + qScriptRegisterMetaType(scriptEngine.data(), RayToOverlayIntersectionResultToScriptValue, RayToOverlayIntersectionResultFromScriptValue); scriptEngine->registerGlobalObject("OffscreenFlags", DependencyManager::get()->getFlags()); scriptEngine->registerGlobalObject("Desktop", DependencyManager::get().data()); - qScriptRegisterMetaType(scriptEngine, wrapperToScriptValue, wrapperFromScriptValue); - qScriptRegisterMetaType(scriptEngine, wrapperToScriptValue, wrapperFromScriptValue); + qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue, wrapperFromScriptValue); + qScriptRegisterMetaType(scriptEngine.data(), + wrapperToScriptValue, wrapperFromScriptValue); scriptEngine->registerGlobalObject("Toolbars", DependencyManager::get().data()); - qScriptRegisterMetaType(scriptEngine, wrapperToScriptValue, wrapperFromScriptValue); - qScriptRegisterMetaType(scriptEngine, wrapperToScriptValue, wrapperFromScriptValue); + qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue, wrapperFromScriptValue); + qScriptRegisterMetaType(scriptEngine.data(), + wrapperToScriptValue, wrapperFromScriptValue); scriptEngine->registerGlobalObject("Tablet", DependencyManager::get().data()); - - DependencyManager::get().data()->setToolbarScriptingInterface(DependencyManager::get().data()); + auto toolbarScriptingInterface = DependencyManager::get().data(); + DependencyManager::get().data()->setToolbarScriptingInterface(toolbarScriptingInterface); scriptEngine->registerGlobalObject("Window", DependencyManager::get().data()); - qScriptRegisterMetaType(scriptEngine, CustomPromptResultToScriptValue, CustomPromptResultFromScriptValue); + qScriptRegisterMetaType(scriptEngine.data(), CustomPromptResultToScriptValue, CustomPromptResultFromScriptValue); scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, LocationScriptingInterface::locationSetter, "Window"); // register `location` on the global object. @@ -6036,7 +6038,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("DialogsManager", _dialogsManagerScriptingInterface); scriptEngine->registerGlobalObject("GlobalServices", GlobalServicesScriptingInterface::getInstance()); - qScriptRegisterMetaType(scriptEngine, DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue); + qScriptRegisterMetaType(scriptEngine.data(), DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue); scriptEngine->registerGlobalObject("FaceTracker", DependencyManager::get().data()); @@ -6064,11 +6066,11 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("LimitlessSpeechRecognition", DependencyManager::get().data()); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { - scriptEngine->registerGlobalObject("Steam", new SteamScriptingInterface(scriptEngine, steamClient.get())); + scriptEngine->registerGlobalObject("Steam", new SteamScriptingInterface(scriptEngine.data(), steamClient.get())); } auto scriptingInterface = DependencyManager::get(); scriptEngine->registerGlobalObject("Controller", scriptingInterface.data()); - UserInputMapper::registerControllerTypes(scriptEngine); + UserInputMapper::registerControllerTypes(scriptEngine.data()); auto recordingInterface = DependencyManager::get(); scriptEngine->registerGlobalObject("Recording", recordingInterface.data()); @@ -6079,14 +6081,19 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("Selection", DependencyManager::get().data()); scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get().data()); - qScriptRegisterMetaType(scriptEngine, OverlayIDtoScriptValue, OverlayIDfromScriptValue); + qScriptRegisterMetaType(scriptEngine.data(), OverlayIDtoScriptValue, OverlayIDfromScriptValue); // connect this script engines printedMessage signal to the global ScriptEngines these various messages - connect(scriptEngine, &ScriptEngine::printedMessage, DependencyManager::get().data(), &ScriptEngines::onPrintedMessage); - connect(scriptEngine, &ScriptEngine::errorMessage, DependencyManager::get().data(), &ScriptEngines::onErrorMessage); - connect(scriptEngine, &ScriptEngine::warningMessage, DependencyManager::get().data(), &ScriptEngines::onWarningMessage); - connect(scriptEngine, &ScriptEngine::infoMessage, DependencyManager::get().data(), &ScriptEngines::onInfoMessage); - connect(scriptEngine, &ScriptEngine::clearDebugWindow, DependencyManager::get().data(), &ScriptEngines::onClearDebugWindow); + connect(scriptEngine.data(), &ScriptEngine::printedMessage, + DependencyManager::get().data(), &ScriptEngines::onPrintedMessage); + connect(scriptEngine.data(), &ScriptEngine::errorMessage, + DependencyManager::get().data(), &ScriptEngines::onErrorMessage); + connect(scriptEngine.data(), &ScriptEngine::warningMessage, + DependencyManager::get().data(), &ScriptEngines::onWarningMessage); + connect(scriptEngine.data(), &ScriptEngine::infoMessage, + DependencyManager::get().data(), &ScriptEngines::onInfoMessage); + connect(scriptEngine.data(), &ScriptEngine::clearDebugWindow, + DependencyManager::get().data(), &ScriptEngines::onClearDebugWindow); } diff --git a/interface/src/Application.h b/interface/src/Application.h index c7f83ad28f..86e4f94917 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -218,7 +218,7 @@ public: NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } virtual controller::ScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; } - virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) override; + virtual void registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) override; virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const override { copyDisplayViewFrustum(viewOut); } virtual QThread* getMainThread() override { return thread(); } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index e7a83b5abc..a6d77c8d03 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -259,12 +259,12 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { simulateAvatarFades(deltaTime); } -void AvatarManager::postUpdate(float deltaTime) { +void AvatarManager::postUpdate(float deltaTime, const render::ScenePointer& scene) { auto hashCopy = getHashCopy(); AvatarHash::iterator avatarIterator = hashCopy.begin(); for (avatarIterator = hashCopy.begin(); avatarIterator != hashCopy.end(); avatarIterator++) { auto avatar = std::static_pointer_cast(avatarIterator.value()); - avatar->postUpdate(deltaTime); + avatar->postUpdate(deltaTime, scene); } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 810d419a55..cef6bd4c9c 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -55,7 +55,7 @@ public: void updateMyAvatar(float deltaTime); void updateOtherAvatars(float deltaTime); - void postUpdate(float deltaTime); + void postUpdate(float deltaTime, const render::ScenePointer& scene); void clearOtherAvatars(); void deleteAllAvatars(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index abbf667894..f7116a60db 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -234,7 +234,7 @@ void MyAvatar::setDominantHand(const QString& hand) { } } -void MyAvatar::registerMetaTypes(QScriptEngine* engine) { +void MyAvatar::registerMetaTypes(ScriptEnginePointer engine) { QScriptValue value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects); engine->globalObject().setProperty("MyAvatar", value); @@ -245,8 +245,8 @@ void MyAvatar::registerMetaTypes(QScriptEngine* engine) { } engine->globalObject().setProperty("DriveKeys", driveKeys); - qScriptRegisterMetaType(engine, audioListenModeToScriptValue, audioListenModeFromScriptValue); - qScriptRegisterMetaType(engine, driveKeysToScriptValue, driveKeysFromScriptValue); + qScriptRegisterMetaType(engine.data(), audioListenModeToScriptValue, audioListenModeFromScriptValue); + qScriptRegisterMetaType(engine.data(), driveKeysToScriptValue, driveKeysFromScriptValue); } void MyAvatar::setOrientationVar(const QVariant& newOrientationVar) { @@ -1791,11 +1791,11 @@ void MyAvatar::destroyAnimGraph() { _skeletonModel->getRig().destroyAnimGraph(); } -void MyAvatar::postUpdate(float deltaTime) { +void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) { - Avatar::postUpdate(deltaTime); + Avatar::postUpdate(deltaTime, scene); - if (DependencyManager::get()->shouldRenderAvatars() && _skeletonModel->initWhenReady(qApp->getMain3DScene())) { + if (_skeletonModel->isLoaded() && !_skeletonModel->getRig().getAnimNode()) { initHeadBones(); _skeletonModel->setCauterizeBoneSet(_headBoneSet); _fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index f8617bd309..c9d073cfd9 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -175,7 +176,7 @@ public: ~MyAvatar(); void instantiableAvatar() override {}; - void registerMetaTypes(QScriptEngine* engine); + void registerMetaTypes(ScriptEnginePointer engine); virtual void simulateAttachments(float deltaTime) override; @@ -202,7 +203,7 @@ public: Q_INVOKABLE void clearIKJointLimitHistory(); // thread-safe void update(float deltaTime); - virtual void postUpdate(float deltaTime) override; + virtual void postUpdate(float deltaTime, const render::ScenePointer& scene) override; void preDisplaySide(RenderArgs* renderArgs); const glm::mat4& getHMDSensorMatrix() const { return _hmdSensorMatrix; } diff --git a/interface/src/ui/JSConsole.cpp b/interface/src/ui/JSConsole.cpp index 8c1ff87d13..c5f8b54ebd 100644 --- a/interface/src/ui/JSConsole.cpp +++ b/interface/src/ui/JSConsole.cpp @@ -61,7 +61,7 @@ void _writeLines(const QString& filename, const QList& lines) { QTextStream(&file) << json; } -JSConsole::JSConsole(QWidget* parent, const QSharedPointer& scriptEngine) : +JSConsole::JSConsole(QWidget* parent, const ScriptEnginePointer& scriptEngine) : QWidget(parent), _ui(new Ui::Console), _currentCommandInHistory(NO_CURRENT_HISTORY_COMMAND), @@ -97,7 +97,7 @@ JSConsole::~JSConsole() { delete _ui; } -void JSConsole::setScriptEngine(const QSharedPointer& scriptEngine) { +void JSConsole::setScriptEngine(const ScriptEnginePointer& scriptEngine) { if (_scriptEngine == scriptEngine && scriptEngine != NULL) { return; } @@ -111,7 +111,7 @@ void JSConsole::setScriptEngine(const QSharedPointer& scriptEngin // if scriptEngine is NULL then create one and keep track of it using _ownScriptEngine if (scriptEngine.isNull()) { - _scriptEngine = QSharedPointer(DependencyManager::get()->loadScript(_consoleFileName, false), &QObject::deleteLater); + _scriptEngine = DependencyManager::get()->loadScript(_consoleFileName, false); } else { _scriptEngine = scriptEngine; } diff --git a/interface/src/ui/JSConsole.h b/interface/src/ui/JSConsole.h index 5010b5b9ca..4b6409a76f 100644 --- a/interface/src/ui/JSConsole.h +++ b/interface/src/ui/JSConsole.h @@ -30,10 +30,10 @@ const int CONSOLE_HEIGHT = 200; class JSConsole : public QWidget { Q_OBJECT public: - JSConsole(QWidget* parent, const QSharedPointer& scriptEngine = QSharedPointer()); + JSConsole(QWidget* parent, const ScriptEnginePointer& scriptEngine = ScriptEnginePointer()); ~JSConsole(); - void setScriptEngine(const QSharedPointer& scriptEngine = QSharedPointer()); + void setScriptEngine(const ScriptEnginePointer& scriptEngine = ScriptEnginePointer()); void clear(); public slots: @@ -66,7 +66,7 @@ private: QString _savedHistoryFilename; QList _commandHistory; QString _rootCommand; - QSharedPointer _scriptEngine; + ScriptEnginePointer _scriptEngine; static const QString _consoleFileName; }; diff --git a/interface/src/ui/TestingDialog.cpp b/interface/src/ui/TestingDialog.cpp index bba14cd5d7..6f499f2a8d 100644 --- a/interface/src/ui/TestingDialog.cpp +++ b/interface/src/ui/TestingDialog.cpp @@ -24,7 +24,7 @@ TestingDialog::TestingDialog(QWidget* parent) : _console->setFixedHeight(TESTING_CONSOLE_HEIGHT); auto _engines = DependencyManager::get(); - _engine.reset(_engines->loadScript(qApp->applicationDirPath() + testRunnerRelativePath)); + _engine = _engines->loadScript(qApp->applicationDirPath() + testRunnerRelativePath); _console->setScriptEngine(_engine); connect(_engine.data(), &ScriptEngine::finished, this, &TestingDialog::onTestingFinished); } diff --git a/interface/src/ui/TestingDialog.h b/interface/src/ui/TestingDialog.h index 055e43eaf7..a7e909ca0e 100644 --- a/interface/src/ui/TestingDialog.h +++ b/interface/src/ui/TestingDialog.h @@ -29,7 +29,7 @@ public: private: std::unique_ptr _console; - QSharedPointer _engine; + ScriptEnginePointer _engine; }; #endif diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index c0278a6496..6f55260133 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -256,15 +256,46 @@ bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3 void Base3DOverlay::locationChanged(bool tellPhysics) { SpatiallyNestable::locationChanged(tellPhysics); - auto itemID = getRenderItemID(); - if (render::Item::isValidID(itemID)) { - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; - transaction.updateItem(itemID); - scene->enqueueTransaction(transaction); - } + // Force the actual update of the render transform through the notify call + notifyRenderTransformChange(); } void Base3DOverlay::parentDeleted() { qApp->getOverlays().deleteOverlay(getOverlayID()); } + +void Base3DOverlay::update(float duration) { + + // In Base3DOverlay, if its location or bound changed, the renderTrasnformDirty flag is true. + // then the correct transform used for rendering is computed in the update transaction and assigned. + // TODO: Fix the value to be computed in main thread now and passed by value to the render item. + // This is the simplest fix for the web overlay of the tablet for now + if (_renderTransformDirty) { + _renderTransformDirty = false; + auto itemID = getRenderItemID(); + if (render::Item::isValidID(itemID)) { + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + transaction.updateItem(itemID, [](Overlay& data) { + auto overlay3D = dynamic_cast(&data); + if (overlay3D) { + auto latestTransform = overlay3D->evalRenderTransform(); + overlay3D->setRenderTransform(latestTransform); + } + }); + scene->enqueueTransaction(transaction); + } + } +} + +void Base3DOverlay::notifyRenderTransformChange() const { + _renderTransformDirty = true; +} + +Transform Base3DOverlay::evalRenderTransform() const { + return getTransform(); +} + +void Base3DOverlay::setRenderTransform(const Transform& transform) { + _renderTransform = transform; +} diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index cc46fecfa5..7f72c80d55 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -55,6 +55,10 @@ public: virtual AABox getBounds() const override = 0; + void update(float deltatime) override; + + void notifyRenderTransformChange() const; + void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -70,12 +74,18 @@ protected: virtual void locationChanged(bool tellPhysics = true) override; virtual void parentDeleted() override; + mutable Transform _renderTransform; + virtual Transform evalRenderTransform() const; + virtual void setRenderTransform(const Transform& transform); + const Transform& getRenderTransform() const { return _renderTransform; } + float _lineWidth; bool _isSolid; bool _isDashedLine; bool _ignoreRayIntersection; bool _drawInFront; bool _isGrabbable { false }; + mutable bool _renderTransformDirty{ true }; QString _name; }; diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 242021d698..57911c0786 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -85,6 +85,7 @@ void Circle3DOverlay::render(RenderArgs* args) { } // FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround + // FIXME Start using the _renderTransform instead of calling for Transform from here, do the custom things needed in evalRenderTransform() auto transform = getTransform(); transform.postScale(glm::vec3(getDimensions(), 1.0f)); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 5ab32d21fe..ca7355b86f 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -54,6 +54,7 @@ void Cube3DOverlay::render(RenderArgs* args) { glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); // TODO: handle registration point?? + // FIXME Start using the _renderTransform instead of calling for Transform from here, do the custom things needed in evalRenderTransform() glm::vec3 position = getPosition(); glm::vec3 dimensions = getDimensions(); glm::quat rotation = getRotation(); diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 1c2b4c162d..3172403731 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -79,6 +79,7 @@ void Grid3DOverlay::render(RenderArgs* args) { position += glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z); } + // FIXME Start using the _renderTransform instead of calling for Transform from here, do the custom things needed in evalRenderTransform() Transform transform; transform.setRotation(getRotation()); transform.setScale(glm::vec3(getDimensions(), 1.0f)); diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index 6949848208..c79d363811 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -117,6 +117,7 @@ void Image3DOverlay::render(RenderArgs* args) { xColor color = getColor(); float alpha = getAlpha(); + // FIXME Start using the _renderTransform instead of calling for Transform from here, do the custom things needed in evalRenderTransform() Transform transform = getTransform(); bool transformChanged = applyTransformTo(transform, true); // If the transform is not modified, setting the transform to diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index cc8ed8e1a8..534261c839 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -132,6 +132,7 @@ void Line3DOverlay::render(RenderArgs* args) { glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); auto batch = args->_batch; if (batch) { + // FIXME Start using the _renderTransform instead of calling for Transform and start and end from here, do the custom things needed in evalRenderTransform() batch->setModelTransform(Transform()); glm::vec3 start = getStart(); glm::vec3 end = getEnd(); diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 891623edbc..e2a7df7ae6 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -285,6 +285,7 @@ ModelOverlay* ModelOverlay::createClone() const { void ModelOverlay::locationChanged(bool tellPhysics) { Base3DOverlay::locationChanged(tellPhysics); + // FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform() if (_model && _model->isActive()) { _model->setRotation(getRotation()); _model->setTranslation(getPosition()); diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index 58d72b100b..e2877e1e07 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -66,3 +66,11 @@ bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve // FIXME - face and surfaceNormal not being returned return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), getDimensions(), distance); } + +Transform Planar3DOverlay::evalRenderTransform() const { + auto transform = getTransform(); + if (glm::length2(getDimensions()) != 1.0f) { + transform.postScale(vec3(getDimensions(), 1.0f)); + } + return transform; +} \ No newline at end of file diff --git a/interface/src/ui/overlays/Planar3DOverlay.h b/interface/src/ui/overlays/Planar3DOverlay.h index 8127d4ebb9..2ed90ab4ed 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.h +++ b/interface/src/ui/overlays/Planar3DOverlay.h @@ -32,7 +32,9 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) override; - + + Transform evalRenderTransform() const override; + protected: glm::vec2 _dimensions; }; diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 22124a0a97..dc8badbbd1 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -66,6 +66,7 @@ void Rectangle3DOverlay::render(RenderArgs* args) { auto batch = args->_batch; if (batch) { + // FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform() Transform transform; transform.setTranslation(position); transform.setRotation(rotation); diff --git a/interface/src/ui/overlays/Shape3DOverlay.cpp b/interface/src/ui/overlays/Shape3DOverlay.cpp index df0ecba307..fc54cc19ff 100644 --- a/interface/src/ui/overlays/Shape3DOverlay.cpp +++ b/interface/src/ui/overlays/Shape3DOverlay.cpp @@ -33,6 +33,7 @@ void Shape3DOverlay::render(RenderArgs* args) { const float MAX_COLOR = 255.0f; glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + // FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform() // TODO: handle registration point?? glm::vec3 position = getPosition(); glm::vec3 dimensions = getDimensions(); diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 94c92c029d..83dc4b0e2b 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -39,6 +39,7 @@ void Sphere3DOverlay::render(RenderArgs* args) { auto batch = args->_batch; if (batch) { + // FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform() Transform transform = getTransform(); #ifndef USE_SN_SCALE transform.setScale(1.0f); // ignore inherited scale from SpatiallyNestable diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index bb8c24aa11..43a2854206 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -96,6 +96,7 @@ void Text3DOverlay::render(RenderArgs* args) { Q_ASSERT(args->_batch); auto& batch = *args->_batch; + // FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform() Transform transform = getTransform(); applyTransformTo(transform, true); setTransform(transform); diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 32f97507bd..b8249d6c75 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -184,6 +184,16 @@ void Web3DOverlay::update(float deltatime) { // update globalPosition _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } + Parent::update(deltatime); +} + +Transform Web3DOverlay::evalRenderTransform() const { + Transform transform = getTransform(); + transform.setScale(1.0f); // ignore inherited scale factor from parents + if (glm::length2(getDimensions()) != 1.0f) { + transform.postScale(vec3(getDimensions(), 1.0f)); + } + return transform; } QString Web3DOverlay::pickURL() { @@ -304,14 +314,6 @@ void Web3DOverlay::render(RenderArgs* args) { vec2 halfSize = getSize() / 2.0f; vec4 color(toGlm(getColor()), getAlpha()); - Transform transform = getTransform(); -#ifndef USE_SN_SCALE - transform.setScale(1.0f); // ignore inherited scale factor from parents -#endif - if (glm::length2(getDimensions()) != 1.0f) { - transform.postScale(vec3(getDimensions(), 1.0f)); - } - if (!_texture) { _texture = gpu::Texture::createExternal(OffscreenQmlSurface::getDiscardLambda()); _texture->setSource(__FUNCTION__); @@ -325,7 +327,9 @@ void Web3DOverlay::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; batch.setResourceTexture(0, _texture); - batch.setModelTransform(transform); + auto renderTransform = getRenderTransform(); + batch.setModelTransform(getRenderTransform()); + auto geometryCache = DependencyManager::get(); if (color.a < OPAQUE_ALPHA_THRESHOLD) { geometryCache->bindWebBrowserProgram(batch, true); diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 2eae7f33da..7031a3f2c9 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -19,8 +19,10 @@ class OffscreenQmlSurface; class Web3DOverlay : public Billboard3DOverlay { Q_OBJECT + using Parent = Billboard3DOverlay; public: + static const QString QML; static QString const TYPE; virtual QString getType() const override { return TYPE; } @@ -36,6 +38,7 @@ public: virtual const render::ShapeKey getShapeKey() override; virtual void update(float deltatime) override; + virtual Transform Web3DOverlay::evalRenderTransform() const override; QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 444147aeba..87d4a2d343 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -554,7 +554,7 @@ void Avatar::updateRenderItem(render::Transaction& transaction) { } } -void Avatar::postUpdate(float deltaTime) { +void Avatar::postUpdate(float deltaTime, const render::ScenePointer& scene) { if (isMyAvatar() ? showMyLookAtVectors : showOtherLookAtVectors) { const float EYE_RAY_LENGTH = 10.0; @@ -578,6 +578,8 @@ void Avatar::postUpdate(float deltaTime) { DebugDraw::getInstance().drawRay(rightEyePosition, rightEyePosition + rightEyeRotation * Vectors::UNIT_Z * EYE_RAY_LENGTH, RED); } } + + fixupModelsInScene(scene); } void Avatar::render(RenderArgs* renderArgs) { @@ -649,10 +651,6 @@ void Avatar::render(RenderArgs* renderArgs) { return; } - if (!isMyAvatar()) { - fixupModelsInScene(renderArgs->_scene); - } - if (showCollisionShapes && shouldRenderHead(renderArgs) && _skeletonModel->isRenderable()) { PROFILE_RANGE_BATCH(batch, __FUNCTION__":skeletonBoundingCollisionShapes"); const float BOUNDING_SHAPE_ALPHA = 0.7f; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index c969de980f..a5ec307c50 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -98,7 +98,7 @@ public: void updateRenderItem(render::Transaction& transaction); - virtual void postUpdate(float deltaTime); + virtual void postUpdate(float deltaTime, const render::ScenePointer& scene); //setters void setIsLookAtTarget(const bool isLookAtTarget) { _isLookAtTarget = isLookAtTarget; } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index d754d59721..e8ad163964 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -70,45 +70,21 @@ EntityRendererPointer EntityTreeRenderer::renderableForEntityId(const EntityItem return itr->second; } -render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& id) const { - auto renderable = renderableForEntityId(id); - return renderable ? renderable->getRenderItemID() : render::Item::INVALID_ITEM_ID; +render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& id) const { + auto renderable = renderableForEntityId(id); + return renderable ? renderable->getRenderItemID() : render::Item::INVALID_ITEM_ID; } int EntityTreeRenderer::_entitiesScriptEngineCount = 0; -void entitiesScriptEngineDeleter(ScriptEngine* engine) { - class WaitRunnable : public QRunnable { - public: - WaitRunnable(ScriptEngine* engine) : _engine(engine) {} - virtual void run() override { - _engine->waitTillDoneRunning(); - _engine->deleteLater(); - } - - private: - ScriptEngine* _engine; - }; - - // Wait for the scripting thread from the thread pool to avoid hanging the main thread - auto threadPool = QThreadPool::globalInstance(); - if (threadPool) { - threadPool->start(new WaitRunnable(engine)); - } else { - delete engine; - } -} - void EntityTreeRenderer::resetEntitiesScriptEngine() { - // Keep a ref to oldEngine until newEngine is ready so EntityScriptingInterface has something to use auto oldEngine = _entitiesScriptEngine; - - auto newEngine = new ScriptEngine(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); - _entitiesScriptEngine = QSharedPointer(newEngine, entitiesScriptEngineDeleter); - - _scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine.data()); + _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, + QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); + _scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine); _entitiesScriptEngine->runInThread(); - DependencyManager::get()->setEntitiesScriptEngine(_entitiesScriptEngine.data()); + auto entitiesScriptEngineProvider = qSharedPointerCast(_entitiesScriptEngine); + DependencyManager::get()->setEntitiesScriptEngine(entitiesScriptEngineProvider); } void EntityTreeRenderer::clear() { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 0950974347..05ddaa6b0a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -181,7 +181,7 @@ private: QVector _currentEntitiesInside; bool _wantScripts; - QSharedPointer _entitiesScriptEngine; + ScriptEnginePointer _entitiesScriptEngine; void playEntityCollisionSound(const EntityItemPointer& entity, const Collision& collision); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c6bad008e4..2508b598af 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -36,6 +36,29 @@ static CollisionRenderMeshCache collisionMeshCache; +void ModelEntityWrapper::setModel(const ModelPointer& model) { + withWriteLock([&] { + if (_model != model) { + _model = model; + if (_model) { + _needsInitialSimulation = true; + } + } + }); +} + +ModelPointer ModelEntityWrapper::getModel() const { + return resultWithReadLock([&] { + return _model; + }); +} + +bool ModelEntityWrapper::isModelLoaded() const { + return resultWithReadLock([&] { + return _model.operator bool() && _model->isLoaded(); + }); +} + EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer entity{ new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()) }; entity->setProperties(properties); @@ -43,7 +66,7 @@ EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityI } RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized) : - ModelEntityItem(entityItemID), + ModelEntityWrapper(entityItemID), _dimensionsInitialized(dimensionsInitialized) { } @@ -83,41 +106,47 @@ QVariantMap parseTexturesToMap(QString textures, const QVariantMap& defaultTextu } void RenderableModelEntityItem::doInitialModelSimulation() { + ModelPointer model = getModel(); + if (!model) { + return; + } // The machinery for updateModelBounds will give existing models the opportunity to fix their // translation/rotation/scale/registration. The first two are straightforward, but the latter two have guards to // make sure they don't happen after they've already been set. Here we reset those guards. This doesn't cause the // entity values to change -- it just allows the model to match once it comes in. - _model->setScaleToFit(false, getDimensions()); - _model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); + model->setScaleToFit(false, getDimensions()); + model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); // now recalculate the bounds and registration - _model->setScaleToFit(true, getDimensions()); - _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); - _model->setRotation(getRotation()); - _model->setTranslation(getPosition()); + model->setScaleToFit(true, getDimensions()); + model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); + model->setRotation(getRotation()); + model->setTranslation(getPosition()); { - PerformanceTimer perfTimer("_model->simulate"); - _model->simulate(0.0f); + PerformanceTimer perfTimer("model->simulate"); + model->simulate(0.0f); } _needsInitialSimulation = false; } void RenderableModelEntityItem::autoResizeJointArrays() { - if (_model && _model->isLoaded() && !_needsInitialSimulation) { - resizeJointArrays(_model->getJointStateCount()); + ModelPointer model = getModel(); + if (model && model->isLoaded() && !_needsInitialSimulation) { + resizeJointArrays(model->getJointStateCount()); } } bool RenderableModelEntityItem::needsUpdateModelBounds() const { - if (!hasModel() || !_model) { + ModelPointer model = getModel(); + if (!hasModel() || !model) { return false; } - if (!_dimensionsInitialized || !_model->isActive()) { + if (!_dimensionsInitialized || !model->isActive()) { return false; } - if (_model->needsReload()) { + if (model->needsReload()) { return true; } @@ -129,21 +158,21 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const { return true; } - if (_model->getScaleToFitDimensions() != getDimensions()) { + if (model->getScaleToFitDimensions() != getDimensions()) { return true; } - if (_model->getRegistrationPoint() != getRegistrationPoint()) { + if (model->getRegistrationPoint() != getRegistrationPoint()) { return true; } bool success; auto transform = getTransform(success); if (success) { - if (_model->getTranslation() != transform.getTranslation()) { + if (model->getTranslation() != transform.getTranslation()) { return true; } - if (_model->getRotation() != transform.getRotation()) { + if (model->getRotation() != transform.getRotation()) { return true; } } @@ -158,16 +187,6 @@ void RenderableModelEntityItem::updateModelBounds() { } } -void RenderableModelEntityItem::setModel(const ModelPointer& model) { - withWriteLock([&] { - if (_model != model) { - _model = model; - if (_model) { - _needsInitialSimulation = true; - } - } - }); -} EntityItemProperties RenderableModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { EntityItemProperties properties = ModelEntityItem::getProperties(desiredProperties); // get the properties from our base class @@ -175,43 +194,44 @@ EntityItemProperties RenderableModelEntityItem::getProperties(EntityPropertyFlag properties.setTextureNames(_originalTextures); } - if (_model) { - properties.setRenderInfoVertexCount(_model->getRenderInfoVertexCount()); - properties.setRenderInfoTextureCount(_model->getRenderInfoTextureCount()); - properties.setRenderInfoTextureSize(_model->getRenderInfoTextureSize()); - properties.setRenderInfoDrawCalls(_model->getRenderInfoDrawCalls()); - properties.setRenderInfoHasTransparent(_model->getRenderInfoHasTransparent()); + ModelPointer model = getModel(); + if (model) { + properties.setRenderInfoVertexCount(model->getRenderInfoVertexCount()); + properties.setRenderInfoTextureCount(model->getRenderInfoTextureCount()); + properties.setRenderInfoTextureSize(model->getRenderInfoTextureSize()); + properties.setRenderInfoDrawCalls(model->getRenderInfoDrawCalls()); + properties.setRenderInfoHasTransparent(model->getRenderInfoHasTransparent()); + + if (model->isLoaded()) { + // TODO: improve naturalDimensions in the future, + // for now we've added this hack for setting natural dimensions of models + Extents meshExtents = model->getFBXGeometry().getUnscaledMeshExtents(); + properties.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum); + properties.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum); + } } - if (_model && _model->isLoaded()) { - // TODO: improve naturalDimensions in the future, - // for now we've added this hack for setting natural dimensions of models - Extents meshExtents = _model->getFBXGeometry().getUnscaledMeshExtents(); - properties.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum); - properties.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum); - } return properties; } bool RenderableModelEntityItem::supportsDetailedRayIntersection() const { - return resultWithReadLock([&] { - return _model && _model->isLoaded(); - }); + return isModelLoaded(); } bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject, bool precisionPicking) const { - if (!_model) { + auto model = getModel(); + if (!model) { return true; } // qCDebug(entitiesrenderer) << "RenderableModelEntityItem::findDetailedRayIntersection() precisionPicking:" // << precisionPicking; QString extraInfo; - return _model->findRayIntersectionAgainstSubMeshes(origin, direction, distance, + return model->findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, surfaceNormal, extraInfo, precisionPicking, false); } @@ -242,7 +262,7 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { // parse it twice. auto currentCompoundShapeURL = getCompoundShapeURL(); ModelEntityItem::setCompoundShapeURL(url); - if (getCompoundShapeURL() != currentCompoundShapeURL || !_model) { + if (getCompoundShapeURL() != currentCompoundShapeURL || !getModel()) { if (getShapeType() == SHAPE_TYPE_COMPOUND) { getCollisionGeometryResource(); } @@ -252,17 +272,18 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { bool RenderableModelEntityItem::isReadyToComputeShape() const { ShapeType type = getShapeType(); + auto model = getModel(); if (type == SHAPE_TYPE_COMPOUND) { - if (!_model || getCompoundShapeURL().isEmpty()) { + if (!model || getCompoundShapeURL().isEmpty()) { return false; } - if (_model->getURL().isEmpty()) { + if (model->getURL().isEmpty()) { // we need a render geometry with a scale to proceed, so give up. return false; } - if (_model->isLoaded()) { + if (model->isLoaded()) { if (!getCompoundShapeURL().isEmpty() && !_compoundShapeResource) { const_cast(this)->getCollisionGeometryResource(); } @@ -281,7 +302,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const { // the model is still being downloaded. return false; } else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) { - return (_model && _model->isLoaded()); + return isModelLoaded(); } return true; } @@ -292,6 +313,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { ShapeType type = getShapeType(); glm::vec3 dimensions = getDimensions(); + auto model = getModel(); if (type == SHAPE_TYPE_COMPOUND) { updateModelBounds(); @@ -373,14 +395,14 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { // to the visual model and apply them to the collision model (without regard for the // collision model's extents). - glm::vec3 scaleToFit = dimensions / _model->getFBXGeometry().getUnscaledMeshExtents().size(); + glm::vec3 scaleToFit = dimensions / model->getFBXGeometry().getUnscaledMeshExtents().size(); // multiply each point by scale before handing the point-set off to the physics engine. // also determine the extents of the collision model. glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()); for (int32_t i = 0; i < pointCollection.size(); i++) { for (int32_t j = 0; j < pointCollection[i].size(); j++) { // back compensate for registration so we can apply that offset to the shapeInfo later - pointCollection[i][j] = scaleToFit * (pointCollection[i][j] + _model->getOffset()) - registrationOffset; + pointCollection[i][j] = scaleToFit * (pointCollection[i][j] + model->getOffset()) - registrationOffset; } } shapeInfo.setParams(type, dimensions, getCompoundShapeURL()); @@ -389,11 +411,11 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { assert(_model && _model->isLoaded()); updateModelBounds(); - _model->updateGeometry(); + model->updateGeometry(); // compute meshPart local transforms QVector localTransforms; - const FBXGeometry& fbxGeometry = _model->getFBXGeometry(); + const FBXGeometry& fbxGeometry = model->getFBXGeometry(); int numFbxMeshes = fbxGeometry.meshes.size(); int totalNumVertices = 0; glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT)); @@ -401,7 +423,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { const FBXMesh& mesh = fbxGeometry.meshes.at(i); if (mesh.clusters.size() > 0) { const FBXCluster& cluster = mesh.clusters.at(0); - auto jointMatrix = _model->getRig().getJointTransform(cluster.jointIndex); + auto jointMatrix = model->getRig().getJointTransform(cluster.jointIndex); // we backtranslate by the registration offset so we can apply that offset to the shapeInfo later localTransforms.push_back(invRegistraionOffset * jointMatrix * cluster.inverseBindMatrix); } else { @@ -417,7 +439,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { return; } - auto& meshes = _model->getGeometry()->getMeshes(); + auto& meshes = model->getGeometry()->getMeshes(); int32_t numMeshes = (int32_t)(meshes.size()); const int MAX_ALLOWED_MESH_COUNT = 1000; @@ -631,7 +653,8 @@ void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape) } bool RenderableModelEntityItem::contains(const glm::vec3& point) const { - if (EntityItem::contains(point) && _model && _compoundShapeResource && _compoundShapeResource->isLoaded()) { + auto model = getModel(); + if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) { return _compoundShapeResource->getFBXGeometry().convexHullContains(worldToEntity(point)); } @@ -639,11 +662,12 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const { } bool RenderableModelEntityItem::shouldBePhysical() const { + auto model = getModel(); // If we have a model, make sure it hasn't failed to download. // If it has, we'll report back that we shouldn't be physical so that physics aren't held waiting for us to be ready. - if (_model && getShapeType() == SHAPE_TYPE_COMPOUND && _model->didCollisionGeometryRequestFail()) { + if (model && getShapeType() == SHAPE_TYPE_COMPOUND && model->didCollisionGeometryRequestFail()) { return false; - } else if (_model && getShapeType() != SHAPE_TYPE_NONE && _model->didVisualGeometryRequestFail()) { + } else if (model && getShapeType() != SHAPE_TYPE_NONE && model->didVisualGeometryRequestFail()) { return false; } else { return ModelEntityItem::shouldBePhysical(); @@ -651,9 +675,10 @@ bool RenderableModelEntityItem::shouldBePhysical() const { } glm::quat RenderableModelEntityItem::getAbsoluteJointRotationInObjectFrame(int index) const { - if (_model) { + auto model = getModel(); + if (model) { glm::quat result; - if (_model->getAbsoluteJointRotationInRigFrame(index, result)) { + if (model->getAbsoluteJointRotationInRigFrame(index, result)) { return result; } } @@ -661,9 +686,10 @@ glm::quat RenderableModelEntityItem::getAbsoluteJointRotationInObjectFrame(int i } glm::vec3 RenderableModelEntityItem::getAbsoluteJointTranslationInObjectFrame(int index) const { - if (_model) { + auto model = getModel(); + if (model) { glm::vec3 result; - if (_model->getAbsoluteJointTranslationInRigFrame(index, result)) { + if (model->getAbsoluteJointTranslationInRigFrame(index, result)) { return result; } } @@ -671,10 +697,11 @@ glm::vec3 RenderableModelEntityItem::getAbsoluteJointTranslationInObjectFrame(in } bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { - if (!_model) { + auto model = getModel(); + if (!model) { return false; } - const Rig& rig = _model->getRig(); + const Rig& rig = model->getRig(); int jointParentIndex = rig.getJointParentIndex(index); if (jointParentIndex == -1) { return setLocalJointRotation(index, rotation); @@ -700,10 +727,11 @@ bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index, } bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) { - if (!_model) { + auto model = getModel(); + if (!model) { return false; } - const Rig& rig = _model->getRig(); + const Rig& rig = model->getRig(); int jointParentIndex = rig.getJointParentIndex(index); if (jointParentIndex == -1) { @@ -730,9 +758,10 @@ bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int ind } glm::quat RenderableModelEntityItem::getLocalJointRotation(int index) const { - if (_model) { + auto model = getModel(); + if (model) { glm::quat result; - if (_model->getJointRotation(index, result)) { + if (model->getJointRotation(index, result)) { return result; } } @@ -740,9 +769,10 @@ glm::quat RenderableModelEntityItem::getLocalJointRotation(int index) const { } glm::vec3 RenderableModelEntityItem::getLocalJointTranslation(int index) const { - if (_model) { + auto model = getModel(); + if (model) { glm::vec3 result; - if (_model->getJointTranslation(index, result)) { + if (model->getJointTranslation(index, result)) { return result; } } @@ -810,19 +840,22 @@ void RenderableModelEntityItem::setJointTranslationsSet(const QVector& tra void RenderableModelEntityItem::locationChanged(bool tellPhysics) { PerformanceTimer pertTimer("locationChanged"); EntityItem::locationChanged(tellPhysics); - if (_model && _model->isLoaded()) { - _model->updateRenderItems(); + auto model = getModel(); + if (model && model->isLoaded()) { + model->updateRenderItems(); } } int RenderableModelEntityItem::getJointIndex(const QString& name) const { - return (_model && _model->isActive()) ? _model->getRig().indexOfJoint(name) : -1; + auto model = getModel(); + return (model && model->isActive()) ? model->getRig().indexOfJoint(name) : -1; } QStringList RenderableModelEntityItem::getJointNames() const { QStringList result; - if (_model && _model->isActive()) { - const Rig& rig = _model->getRig(); + auto model = getModel(); + if (model && model->isActive()) { + const Rig& rig = model->getRig(); int jointCount = rig.getJointStateCount(); for (int jointIndex = 0; jointIndex < jointCount; jointIndex++) { result << rig.nameOfJoint(jointIndex); @@ -832,19 +865,16 @@ QStringList RenderableModelEntityItem::getJointNames() const { } bool RenderableModelEntityItem::getMeshes(MeshProxyList& result) { - if (!_model || !_model->isLoaded()) { + auto model = getModel(); + if (!model || !model->isLoaded()) { return false; } - BLOCKING_INVOKE_METHOD(_model.get(), "getMeshes", Q_RETURN_ARG(MeshProxyList, result)); + BLOCKING_INVOKE_METHOD(model.get(), "getMeshes", Q_RETURN_ARG(MeshProxyList, result)); return !result.isEmpty(); } void RenderableModelEntityItem::copyAnimationJointDataToModel() { - ModelPointer model; - withReadLock([&] { - model = _model; - }); - + auto model = getModel(); if (!model || !model->isLoaded()) { return; } @@ -859,7 +889,7 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() { jointData.rotationDirty = false; } if (jointData.translationDirty) { - _model->setJointTranslation(index, true, jointData.joint.translation, 1.0f); + model->setJointTranslation(index, true, jointData.joint.translation, 1.0f); jointData.translationDirty = false; } } @@ -1192,7 +1222,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce // When the individual mesh parts of a model finish fading, they will mark their Model as needing updating // we will watch for that and ask the model to update it's render items if (model->getRenderItemsNeedUpdate()) { - qDebug() << "QQQ" << __FUNCTION__ << "Update model render items" << model->getURL(); model->updateRenderItems(); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index d8ecbeb282..b9c751761d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -34,10 +34,24 @@ class ModelEntityRenderer; } } //#define MODEL_ENTITY_USE_FADE_EFFECT - -class RenderableModelEntityItem : public ModelEntityItem { +class ModelEntityWrapper : public ModelEntityItem { + using Parent = ModelEntityItem; friend class render::entities::ModelEntityRenderer; +protected: + ModelEntityWrapper(const EntityItemID& entityItemID) : Parent(entityItemID) {} + void setModel(const ModelPointer& model); + ModelPointer getModel() const; + bool isModelLoaded() const; + + bool _needsInitialSimulation{ true }; +private: + ModelPointer _model; +}; + +class RenderableModelEntityItem : public ModelEntityWrapper { + friend class render::entities::ModelEntityRenderer; + using Parent = ModelEntityWrapper; public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); @@ -97,14 +111,11 @@ private: bool isAnimatingSomething() const; void autoResizeJointArrays(); void copyAnimationJointDataToModel(); - void setModel(const ModelPointer& model); void getCollisionGeometryResource(); GeometryResource::Pointer _compoundShapeResource; bool _originalTexturesRead { false }; QVariantMap _originalTextures; - ModelPointer _model; - bool _needsInitialSimulation { true }; bool _dimensionsInitialized { true }; bool _needsJointSimulation { false }; bool _showCollisionGeometry { false }; diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 3db7fb2c30..8c1a6318f9 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -121,14 +121,19 @@ bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP } void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { + static const QUrl DEFAULT_POLYLINE_TEXTURE = QUrl(PathUtils::resourcesPath() + "images/paintStroke.png"); + QUrl entityTextures = DEFAULT_POLYLINE_TEXTURE; if (entity->texturesChanged()) { entity->resetTexturesChanged(); auto textures = entity->getTextures(); - QString path = textures.isEmpty() ? PathUtils::resourcesPath() + "images/paintStroke.png" : textures; - if (!_texture || _lastTextures != path) { - _texture = DependencyManager::get()->getTexture(QUrl(path)); + if (!textures.isEmpty()) { + entityTextures = QUrl(textures); } } + + if (!_texture || _texture->getURL() != entityTextures) { + _texture = DependencyManager::get()->getTexture(entityTextures); + } } void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { @@ -140,6 +145,10 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo auto normalsChanged = entity->normalsChanged(); entity->resetPolyLineChanged(); + _polylineTransform = Transform(); + _polylineTransform.setTranslation(entity->getPosition()); + _polylineTransform.setRotation(entity->getRotation()); + if (pointsChanged) { _lastPoints = entity->getLinePoints(); } @@ -217,13 +226,13 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - batch.setModelTransform(Transform{ _modelTransform }.setScale(vec3(1))); + batch.setModelTransform(_polylineTransform); batch.setUniformBuffer(PAINTSTROKE_UNIFORM_SLOT, _uniformBuffer); - if (_texture->isLoaded()) { + if (_texture && _texture->isLoaded()) { batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, _texture->getGPUTexture()); } else { - batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, nullptr); + batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, DependencyManager::get()->getWhiteTexture()); } batch.setInputFormat(polylineFormat); diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h index 88b5ebdb9f..610ee53cf7 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h @@ -47,6 +47,7 @@ protected: void updateGeometry(const std::vector& vertices); static std::vector updateVertices(const QVector& points, const QVector& normals, const QVector& strokeWidths); + Transform _polylineTransform; QVector _lastPoints; QVector _lastNormals; QVector _lastStrokeWidths; @@ -54,7 +55,6 @@ protected: gpu::BufferView _uniformBuffer; uint32_t _numVertices { 0 }; bool _empty{ true }; - QString _lastTextures; NetworkTexturePointer _texture; }; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 127da47ae2..f91bc14fe4 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -539,7 +539,7 @@ void EntityScriptingInterface::deleteEntity(QUuid id) { } } -void EntityScriptingInterface::setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine) { +void EntityScriptingInterface::setEntitiesScriptEngine(QSharedPointer engine) { std::lock_guard lock(_entitiesScriptEngineLock); _entitiesScriptEngine = engine; } @@ -749,7 +749,7 @@ bool EntityPropertyMetadataRequest::script(EntityItemID entityID, QScriptValue h request->deleteLater(); }); auto entityScriptingInterface = DependencyManager::get(); - entityScriptingInterface->withEntitiesScriptEngine([&](EntitiesScriptEngineProvider* entitiesScriptEngine) { + entityScriptingInterface->withEntitiesScriptEngine([&](QSharedPointer entitiesScriptEngine) { if (entitiesScriptEngine) { request->setFuture(entitiesScriptEngine->getLocalEntityScriptDetails(entityID)); } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 1eb754ef1c..9b2b6360f3 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -99,7 +99,7 @@ public: void setEntityTree(EntityTreePointer modelTree); EntityTreePointer getEntityTree() { return _entityTree; } - void setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine); + void setEntitiesScriptEngine(QSharedPointer engine); float calculateCost(float mass, float oldVelocity, float newVelocity); void resetActivityTracking(); @@ -405,7 +405,7 @@ signals: void webEventReceived(const EntityItemID& entityItemID, const QVariant& message); protected: - void withEntitiesScriptEngine(std::function function) { + void withEntitiesScriptEngine(std::function)> function) { std::lock_guard lock(_entitiesScriptEngineLock); function(_entitiesScriptEngine); }; @@ -427,7 +427,7 @@ private: EntityTreePointer _entityTree; std::recursive_mutex _entitiesScriptEngineLock; - EntitiesScriptEngineProvider* _entitiesScriptEngine { nullptr }; + QSharedPointer _entitiesScriptEngine; bool _bidOnSimulationOwnership { false }; float _currentAvatarEnergy = { FLT_MAX }; diff --git a/libraries/script-engine/src/AbstractScriptingServicesInterface.h b/libraries/script-engine/src/AbstractScriptingServicesInterface.h index de18338fca..e7a8d11562 100644 --- a/libraries/script-engine/src/AbstractScriptingServicesInterface.h +++ b/libraries/script-engine/src/AbstractScriptingServicesInterface.h @@ -12,13 +12,13 @@ #ifndef hifi_AbstractScriptingServicesInterface_h #define hifi_AbstractScriptingServicesInterface_h -class ScriptEngine; +#include /// Interface provided by Application to other objects that need access to scripting services of the application class AbstractScriptingServicesInterface { public: /// Registers application specific services with a script engine. - virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) = 0; + virtual void registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) = 0; }; diff --git a/libraries/script-engine/src/RecordingScriptingInterface.h b/libraries/script-engine/src/RecordingScriptingInterface.h index c4220958a2..bc0b019251 100644 --- a/libraries/script-engine/src/RecordingScriptingInterface.h +++ b/libraries/script-engine/src/RecordingScriptingInterface.h @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -28,7 +29,7 @@ class RecordingScriptingInterface : public QObject, public Dependency { public: RecordingScriptingInterface(); - void setScriptEngine(QScriptEngine* scriptEngine) { _scriptEngine = scriptEngine; } + void setScriptEngine(QSharedPointer scriptEngine) { _scriptEngine = scriptEngine; } public slots: void loadRecording(const QString& url, QScriptValue callback = QScriptValue()); @@ -85,7 +86,7 @@ protected: Flag _useSkeletonModel { false }; recording::ClipPointer _lastClip; - QScriptEngine* _scriptEngine; + QSharedPointer _scriptEngine; QSet _clipLoaders; }; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 8b8eed02fd..2260cea616 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -153,6 +153,15 @@ QString ScriptEngine::logException(const QScriptValue& exception) { return message; } +ScriptEnginePointer scriptEngineFactory(ScriptEngine::Context context, + const QString& scriptContents, + const QString& fileNameString) { + ScriptEngine* engine = new ScriptEngine(context, scriptContents, fileNameString); + ScriptEnginePointer engineSP = ScriptEnginePointer(engine); + DependencyManager::get()->addScriptEngine(qSharedPointerCast(engineSP)); + return engineSP; +} + int ScriptEngine::processLevelMaxRetries { ScriptRequest::MAX_RETRIES }; ScriptEngine::ScriptEngine(Context context, const QString& scriptContents, const QString& fileNameString) : BaseScriptEngine(), @@ -160,10 +169,10 @@ ScriptEngine::ScriptEngine(Context context, const QString& scriptContents, const _scriptContents(scriptContents), _timerFunctionMap(), _fileNameString(fileNameString), - _arrayBufferClass(new ArrayBufferClass(this)) + _arrayBufferClass(new ArrayBufferClass(this)), + // don't delete `ScriptEngines` until all `ScriptEngine`s are gone + _scriptEngines(DependencyManager::get()) { - DependencyManager::get()->addScriptEngine(this); - connect(this, &QScriptEngine::signalHandlerException, this, [this](const QScriptValue& exception) { if (hasUncaughtException()) { // the engine's uncaughtException() seems to produce much better stack traces here @@ -208,22 +217,9 @@ QString ScriptEngine::getContext() const { } ScriptEngine::~ScriptEngine() { - // FIXME: are these scriptInfoMessage/scriptWarningMessage segfaulting anybody else at app shutdown? -#if !defined(Q_OS_LINUX) - scriptInfoMessage("Script Engine shutting down:" + getFilename()); -#else - qCDebug(scriptengine) << "~ScriptEngine()" << this; -#endif - auto scriptEngines = DependencyManager::get(); if (scriptEngines) { - scriptEngines->removeScriptEngine(this); - } else { -#if !defined(Q_OS_LINUX) - scriptWarningMessage("Script destroyed after ScriptEngines!"); -#else - qCWarning(scriptengine) << ("Script destroyed after ScriptEngines!"); -#endif + scriptEngines->removeScriptEngine(qSharedPointerCast(sharedFromThis())); } } @@ -294,7 +290,7 @@ void ScriptEngine::runDebuggable() { stopAllTimers(); // make sure all our timers are stopped if the script is ending emit scriptEnding(); - emit finished(_fileNameString, this); + emit finished(_fileNameString, qSharedPointerCast(sharedFromThis())); _isRunning = false; emit runningStateChanged(); @@ -503,7 +499,8 @@ static void animVarMapFromScriptValue(const QScriptValue& value, AnimVariantMap& parameters.animVariantMapFromScriptValue(value); } // ... while these two are not. But none of the four are ever used. -static QScriptValue resultHandlerToScriptValue(QScriptEngine* engine, const AnimVariantResultHandler& resultHandler) { +static QScriptValue resultHandlerToScriptValue(QScriptEngine* engine, + const AnimVariantResultHandler& resultHandler) { qCCritical(scriptengine) << "Attempt to marshall result handler to javascript"; assert(false); return QScriptValue(); @@ -516,7 +513,8 @@ static void resultHandlerFromScriptValue(const QScriptValue& value, AnimVariantR // Templated qScriptRegisterMetaType fails to compile with raw pointers using ScriptableResourceRawPtr = ScriptableResource*; -static QScriptValue scriptableResourceToScriptValue(QScriptEngine* engine, const ScriptableResourceRawPtr& resource) { +static QScriptValue scriptableResourceToScriptValue(QScriptEngine* engine, + const ScriptableResourceRawPtr& resource) { // The first script to encounter this resource will track its memory. // In this way, it will be more likely to GC. // This fails in the case that the resource is used across many scripts, but @@ -539,11 +537,11 @@ static void scriptableResourceFromScriptValue(const QScriptValue& value, Scripta resource = static_cast(value.toQObject()); } -static QScriptValue createScriptableResourcePrototype(QScriptEngine* engine) { +static QScriptValue createScriptableResourcePrototype(ScriptEnginePointer engine) { auto prototype = engine->newObject(); // Expose enum State to JS/QML via properties - QObject* state = new QObject(engine); + QObject* state = new QObject(engine.data()); state->setObjectName("ResourceState"); auto metaEnum = QMetaEnum::fromType(); for (int i = 0; i < metaEnum.keyCount(); ++i) { @@ -693,7 +691,7 @@ void ScriptEngine::init() { qScriptRegisterMetaType(this, resultHandlerToScriptValue, resultHandlerFromScriptValue); // Scriptable cache access - auto resourcePrototype = createScriptableResourcePrototype(this); + auto resourcePrototype = createScriptableResourcePrototype(qSharedPointerCast(sharedFromThis())); globalObject().setProperty("Resource", resourcePrototype); setDefaultPrototype(qMetaTypeId(), resourcePrototype); qScriptRegisterMetaType(this, scriptableResourceToScriptValue, scriptableResourceFromScriptValue); @@ -1178,7 +1176,7 @@ void ScriptEngine::run() { } } - emit finished(_fileNameString, this); + emit finished(_fileNameString, qSharedPointerCast(sharedFromThis())); _isRunning = false; emit runningStateChanged(); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 7c473a305b..7109e0f582 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -53,6 +53,8 @@ static const int SCRIPT_FPS = 60; static const int DEFAULT_MAX_ENTITY_PPS = 9000; static const int DEFAULT_ENTITY_PPS_PER_SCRIPT = 900; +class ScriptEngines; + class CallbackData { public: QScriptValue function; @@ -242,7 +244,7 @@ signals: void errorLoadingScript(const QString& scriptFilename); void update(float deltaTime); void scriptEnding(); - void finished(const QString& fileNameString, ScriptEngine* engine); + void finished(const QString& fileNameString, ScriptEnginePointer); void cleanupMenuItem(const QString& menuItemString); void printedMessage(const QString& message, const QString& scriptName); void errorMessage(const QString& message, const QString& scriptName); @@ -328,6 +330,12 @@ protected: static const QString _SETTINGS_ENABLE_EXTENDED_EXCEPTIONS; Setting::Handle _enableExtendedJSExceptions { _SETTINGS_ENABLE_EXTENDED_EXCEPTIONS, true }; + + QSharedPointer _scriptEngines; }; +ScriptEnginePointer scriptEngineFactory(ScriptEngine::Context context, + const QString& scriptContents, + const QString& fileNameString); + #endif // hifi_ScriptEngine_h diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 57b04eeb82..6cfa678652 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -137,16 +137,14 @@ void ScriptEngines::registerScriptInitializer(ScriptInitializer initializer) { _scriptInitializers.push_back(initializer); } -void ScriptEngines::addScriptEngine(ScriptEngine* engine) { - if (_isStopped) { - engine->deleteLater(); - } else { +void ScriptEngines::addScriptEngine(ScriptEnginePointer engine) { + if (!_isStopped) { QMutexLocker locker(&_allScriptsMutex); _allKnownScriptEngines.insert(engine); } } -void ScriptEngines::removeScriptEngine(ScriptEngine* engine) { +void ScriptEngines::removeScriptEngine(ScriptEnginePointer engine) { // If we're not already in the middle of stopping all scripts, then we should remove ourselves // from the list of running scripts. We don't do this if we're in the process of stopping all scripts // because that method removes scripts from its list as it iterates them @@ -161,9 +159,9 @@ void ScriptEngines::shutdownScripting() { QMutexLocker locker(&_allScriptsMutex); qCDebug(scriptengine) << "Stopping all scripts.... currently known scripts:" << _allKnownScriptEngines.size(); - QMutableSetIterator i(_allKnownScriptEngines); + QMutableSetIterator i(_allKnownScriptEngines); while (i.hasNext()) { - ScriptEngine* scriptEngine = i.next(); + ScriptEnginePointer scriptEngine = i.next(); QString scriptName = scriptEngine->getFilename(); // NOTE: typically all script engines are running. But there's at least one known exception to this, the @@ -187,12 +185,9 @@ void ScriptEngines::shutdownScripting() { qCDebug(scriptengine) << "waiting on script:" << scriptName; scriptEngine->waitTillDoneRunning(); qCDebug(scriptengine) << "done waiting on script:" << scriptName; - - scriptEngine->deleteLater(); - - // Once the script is stopped, we can remove it from our set - i.remove(); } + // Once the script is stopped, we can remove it from our set + i.remove(); } qCDebug(scriptengine) << "DONE Stopping all scripts...."; } @@ -369,9 +364,9 @@ void ScriptEngines::stopAllScripts(bool restart) { _isReloading = true; } - for (QHash::const_iterator it = _scriptEnginesHash.constBegin(); + for (QHash::const_iterator it = _scriptEnginesHash.constBegin(); it != _scriptEnginesHash.constEnd(); it++) { - ScriptEngine *scriptEngine = it.value(); + ScriptEnginePointer scriptEngine = it.value(); // skip already stopped scripts if (scriptEngine->isFinished() || scriptEngine->isStopping()) { continue; @@ -417,11 +412,12 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { QReadLocker lock(&_scriptEnginesHashLock); if (_scriptEnginesHash.contains(scriptURL)) { - ScriptEngine* scriptEngine = _scriptEnginesHash[scriptURL]; + ScriptEnginePointer scriptEngine = _scriptEnginesHash[scriptURL]; if (restart) { auto scriptCache = DependencyManager::get(); scriptCache->deleteScript(scriptURL); - connect(scriptEngine, &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) { + connect(scriptEngine.data(), &ScriptEngine::finished, + this, [this](QString scriptName, ScriptEnginePointer engine) { reloadScript(scriptName); }); } @@ -449,11 +445,11 @@ void ScriptEngines::reloadAllScripts() { stopAllScripts(true); } -ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor, +ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor, bool activateMainWindow, bool reload) { if (thread() != QThread::currentThread()) { - ScriptEngine* result { nullptr }; - BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(ScriptEngine*, result), + ScriptEnginePointer result { nullptr }; + BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(ScriptEnginePointer, result), Q_ARG(QUrl, scriptFilename), Q_ARG(bool, isUserLoaded), Q_ARG(bool, loadScriptFromEditor), @@ -479,19 +475,16 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL return scriptEngine; } - scriptEngine = new ScriptEngine(_context, NO_SCRIPT, "about:" + scriptFilename.fileName()); + scriptEngine = ScriptEnginePointer(new ScriptEngine(_context, NO_SCRIPT, "about:" + scriptFilename.fileName())); + addScriptEngine(scriptEngine); scriptEngine->setUserLoaded(isUserLoaded); - connect(scriptEngine, &ScriptEngine::doneRunning, this, [scriptEngine] { - scriptEngine->deleteLater(); - }, Qt::QueuedConnection); - if (scriptFilename.isEmpty() || !scriptUrl.isValid()) { launchScriptEngine(scriptEngine); } else { // connect to the appropriate signals of this script engine - connect(scriptEngine, &ScriptEngine::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded); - connect(scriptEngine, &ScriptEngine::errorLoadingScript, this, &ScriptEngines::onScriptEngineError); + connect(scriptEngine.data(), &ScriptEngine::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded); + connect(scriptEngine.data(), &ScriptEngine::errorLoadingScript, this, &ScriptEngines::onScriptEngineError); // get the script engine object to load the script at the designated script URL scriptEngine->loadURL(scriptUrl, reload); @@ -500,8 +493,8 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL return scriptEngine; } -ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { - ScriptEngine* result = nullptr; +ScriptEnginePointer ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { + ScriptEnginePointer result; { QReadLocker lock(&_scriptEnginesHashLock); const QUrl scriptURL = normalizeScriptURL(rawScriptURL); @@ -516,7 +509,8 @@ ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { // FIXME - change to new version of ScriptCache loading notification void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { UserActivityLogger::getInstance().loadedScript(rawScriptURL); - ScriptEngine* scriptEngine = qobject_cast(sender()); + QSharedPointer baseScriptEngine = qobject_cast(sender())->sharedFromThis(); + ScriptEnginePointer scriptEngine = qSharedPointerCast(baseScriptEngine); launchScriptEngine(scriptEngine); @@ -532,12 +526,12 @@ void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { emit scriptCountChanged(); } -void ScriptEngines::launchScriptEngine(ScriptEngine* scriptEngine) { - connect(scriptEngine, &ScriptEngine::finished, this, &ScriptEngines::onScriptFinished, Qt::DirectConnection); - connect(scriptEngine, &ScriptEngine::loadScript, [&](const QString& scriptName, bool userLoaded) { +void ScriptEngines::launchScriptEngine(ScriptEnginePointer scriptEngine) { + connect(scriptEngine.data(), &ScriptEngine::finished, this, &ScriptEngines::onScriptFinished, Qt::DirectConnection); + connect(scriptEngine.data(), &ScriptEngine::loadScript, [&](const QString& scriptName, bool userLoaded) { loadScript(scriptName, userLoaded); }); - connect(scriptEngine, &ScriptEngine::reloadScript, [&](const QString& scriptName, bool userLoaded) { + connect(scriptEngine.data(), &ScriptEngine::reloadScript, [&](const QString& scriptName, bool userLoaded) { loadScript(scriptName, userLoaded, false, false, true); }); @@ -558,7 +552,7 @@ void ScriptEngines::launchScriptEngine(ScriptEngine* scriptEngine) { } } -void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptEngine* engine) { +void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptEnginePointer engine) { bool removed = false; { QWriteLocker lock(&_scriptEnginesHashLock); diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index 70634345eb..f2b0105be1 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -33,7 +33,7 @@ class ScriptEngines : public QObject, public Dependency { Q_PROPERTY(ScriptsModelFilter* scriptsModelFilter READ scriptsModelFilter CONSTANT) public: - using ScriptInitializer = std::function; + using ScriptInitializer = std::function; ScriptEngines(ScriptEngine::Context context); void registerScriptInitializer(ScriptInitializer initializer); @@ -45,7 +45,7 @@ public: void loadDefaultScripts(); void setScriptsLocation(const QString& scriptsLocation); QStringList getRunningScripts(); - ScriptEngine* getScriptEngine(const QUrl& scriptHash); + ScriptEnginePointer getScriptEngine(const QUrl& scriptHash); ScriptsModel* scriptsModel() { return &_scriptsModel; }; ScriptsModelFilter* scriptsModelFilter() { return &_scriptsModelFilter; }; @@ -53,7 +53,7 @@ public: QString getDefaultScriptsLocation() const; Q_INVOKABLE void loadOneScript(const QString& scriptFilename); - Q_INVOKABLE ScriptEngine* loadScript(const QUrl& scriptFilename = QString(), + Q_INVOKABLE ScriptEnginePointer loadScript(const QUrl& scriptFilename = QString(), bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false); Q_INVOKABLE bool stopScript(const QString& scriptHash, bool restart = false); @@ -72,6 +72,8 @@ public: void shutdownScripting(); bool isStopped() const { return _isStopped; } + void addScriptEngine(ScriptEnginePointer); + signals: void scriptCountChanged(); void scriptsReloading(); @@ -92,22 +94,21 @@ public slots: void onClearDebugWindow(); protected slots: - void onScriptFinished(const QString& fileNameString, ScriptEngine* engine); + void onScriptFinished(const QString& fileNameString, ScriptEnginePointer engine); protected: friend class ScriptEngine; void reloadScript(const QString& scriptName) { loadScript(scriptName, true, false, false, true); } - void addScriptEngine(ScriptEngine* engine); - void removeScriptEngine(ScriptEngine* engine); + void removeScriptEngine(ScriptEnginePointer); void onScriptEngineLoaded(const QString& scriptFilename); void onScriptEngineError(const QString& scriptFilename); - void launchScriptEngine(ScriptEngine* engine); + void launchScriptEngine(ScriptEnginePointer); ScriptEngine::Context _context; QReadWriteLock _scriptEnginesHashLock; - QHash _scriptEnginesHash; - QSet _allKnownScriptEngines; + QHash _scriptEnginesHash; + QSet _allKnownScriptEngines; QMutex _allScriptsMutex; std::list _scriptInitializers; mutable Setting::Handle _scriptsLocationHandle; diff --git a/libraries/shared/src/BaseScriptEngine.h b/libraries/shared/src/BaseScriptEngine.h index 138e46fafa..8820a386bf 100644 --- a/libraries/shared/src/BaseScriptEngine.h +++ b/libraries/shared/src/BaseScriptEngine.h @@ -16,6 +16,9 @@ #include #include +class ScriptEngine; +using ScriptEnginePointer = QSharedPointer; + // common base class for extending QScriptEngine itself class BaseScriptEngine : public QScriptEngine, public QEnableSharedFromThis { Q_OBJECT diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index adff219e0f..8ab03b60d0 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -425,6 +425,9 @@ void TabletProxy::gotoMenuScreen(const QString& submenu) { emit screenChanged(QVariant("Menu"), QVariant(VRMENU_SOURCE_URL)); _currentPathLoaded = VRMENU_SOURCE_URL; QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); + if (_toolbarMode && _desktopWindow) { + QMetaObject::invokeMethod(root, "setResizable", Q_ARG(const QVariant&, QVariant(false))); + } } } @@ -444,6 +447,9 @@ void TabletProxy::loadQMLOnTop(const QVariant& path) { if (root) { QMetaObject::invokeMethod(root, "loadQMLOnTop", Q_ARG(const QVariant&, path)); QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); + if (_toolbarMode && _desktopWindow) { + QMetaObject::invokeMethod(root, "setResizable", Q_ARG(const QVariant&, QVariant(false))); + } } else { qCDebug(uiLogging) << "tablet cannot load QML because _qmlTabletRoot is null"; } @@ -470,9 +476,9 @@ void TabletProxy::returnToPreviousApp() { } } -void TabletProxy::loadQMLSource(const QVariant& path) { +void TabletProxy::loadQMLSource(const QVariant& path, bool resizable) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "loadQMLSource", Q_ARG(QVariant, path)); + QMetaObject::invokeMethod(this, "loadQMLSource", Q_ARG(QVariant, path), Q_ARG(bool, resizable)); return; } @@ -492,6 +498,10 @@ void TabletProxy::loadQMLSource(const QVariant& path) { } _currentPathLoaded = path; QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); + if (_toolbarMode && _desktopWindow) { + QMetaObject::invokeMethod(root, "setResizable", Q_ARG(const QVariant&, QVariant(resizable))); + } + } else { qCDebug(uiLogging) << "tablet cannot load QML because _qmlTabletRoot is null"; } @@ -523,6 +533,9 @@ bool TabletProxy::pushOntoStack(const QVariant& path) { } else { loadQMLSource(path); } + if (_toolbarMode && _desktopWindow) { + QMetaObject::invokeMethod(root, "setResizable", Q_ARG(const QVariant&, QVariant(false))); + } } else { qCDebug(uiLogging) << "tablet cannot push QML because _qmlTabletRoot or _desktopWindow is null"; } @@ -599,6 +612,9 @@ void TabletProxy::loadWebScreenOnTop(const QVariant& url, const QString& injectJ if (root) { QMetaObject::invokeMethod(root, "loadQMLOnTop", Q_ARG(const QVariant&, QVariant(WEB_VIEW_SOURCE_URL))); QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); + if (_toolbarMode && _desktopWindow) { + QMetaObject::invokeMethod(root, "setResizable", Q_ARG(const QVariant&, QVariant(false))); + } QMetaObject::invokeMethod(root, "loadWebOnTop", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectJavaScriptUrl))); } _state = State::Web; @@ -625,6 +641,9 @@ void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaS QMetaObject::invokeMethod(root, "loadWebBase"); } QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true))); + if (_toolbarMode && _desktopWindow) { + QMetaObject::invokeMethod(root, "setResizable", Q_ARG(const QVariant&, QVariant(false))); + } QMetaObject::invokeMethod(root, "loadWebUrl", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectedJavaScriptUrl))); } _state = State::Web; diff --git a/libraries/ui/src/ui/TabletScriptingInterface.h b/libraries/ui/src/ui/TabletScriptingInterface.h index 822bae839e..d3590ec62e 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.h +++ b/libraries/ui/src/ui/TabletScriptingInterface.h @@ -124,7 +124,7 @@ public: Q_INVOKABLE void gotoWebScreen(const QString& url); Q_INVOKABLE void gotoWebScreen(const QString& url, const QString& injectedJavaScriptUrl, bool loadOtherBase = false); - Q_INVOKABLE void loadQMLSource(const QVariant& path); + Q_INVOKABLE void loadQMLSource(const QVariant& path, bool resizable = false); // FIXME: This currently relies on a script initializing the tablet (hence the bool denoting success); // it should be initialized internally so it cannot fail Q_INVOKABLE bool pushOntoStack(const QVariant& path); diff --git a/scripts/developer/tests/avatarAttachmentTest.js b/scripts/developer/tests/avatarAttachmentTest.js index f287013979..c9f2e1615b 100644 --- a/scripts/developer/tests/avatarAttachmentTest.js +++ b/scripts/developer/tests/avatarAttachmentTest.js @@ -89,9 +89,9 @@ var coatButton = new ToggleButtonBuddy(buttonPositionX, buttonPositionY, BUTTON_ var HAT_ATTACHMENT = { modelURL: "https://s3.amazonaws.com/hifi-public/tony/cowboy-hat.fbx", jointName: "Head", - translation: {"x": 0, "y": 0.2, "z": 0}, + translation: {"x": 0, "y": 0.25, "z": 0.03}, rotation: {"x": 0, "y": 0, "z": 0, "w": 1}, - scale: 1, + scale: 0.052, isSoft: false }; diff --git a/scripts/system/controllers/controllerModules/disableOtherModule.js b/scripts/system/controllers/controllerModules/disableOtherModule.js index d6079ffafb..92784ec2ed 100644 --- a/scripts/system/controllers/controllerModules/disableOtherModule.js +++ b/scripts/system/controllers/controllerModules/disableOtherModule.js @@ -1,15 +1,13 @@ "use strict"; -// nearTrigger.js +// disableOtherModule.js // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, - enableDispatcherModule, disableDispatcherModule, getGrabbableData, Vec3, - TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS, - getEnabledModuleByName +/* global Script, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, + makeDispatcherModuleParameters, makeRunningValues, getEnabledModuleByName, Messages */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -20,7 +18,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.disableModules = false; this.parameters = makeDispatcherModuleParameters( 90, - this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip", "rightHandTrigger"] : ["leftHand", "leftHandEquip", "leftHandTrigger"], + this.hand === RIGHT_HAND ? + ["rightHand", "rightHandEquip", "rightHandTrigger"] : + ["leftHand", "leftHandEquip", "leftHandTrigger"], [], 100); @@ -37,11 +37,11 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); if (teleportModule) { var ready = teleportModule.isReady(controllerData); - if (ready) { + if (ready.active) { return makeRunningValues(false, [], []); } } - if (!this.disablemodules) { + if (!this.disableModules) { return makeRunningValues(false, [], []); } return makeRunningValues(true, [], []); @@ -61,7 +61,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } if (message === 'right') { rightDisableModules.disableModules = true; - } if (message === 'both' || message === 'none') { if (message === 'both') { @@ -75,7 +74,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } } }; - + Messages.subscribe('Hifi-Hand-Disabler'); this.cleanup = function() { disableDispatcherModule("LeftDisableModules"); diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index fa1321b168..fe868493f4 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -602,11 +602,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa }; this.isTargetIDValid = function() { - var entityProperties = Entities.getEntityProperties(this.targetEntityID); - for (var propertry in entityProperties) { - return true; - } - return false; + var entityProperties = Entities.getEntityProperties(this.targetEntityID, ["type"]); + return "type" in entityProperties; }; this.isReady = function (controllerData, deltaTime) { diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index b46203c338..eb73b0f908 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -13,7 +13,7 @@ makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, - getControllerWorldLocation, projectOntoEntityXYPlane + getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays */ @@ -236,10 +236,10 @@ Script.include("/~/system/libraries/controllers.js"); this.actionID = null; } - // XXX - // if (this.actionID !== null) { - // this.callEntityMethodOnGrabbed("startDistanceGrab"); - // } + if (this.actionID !== null) { + var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; + Entities.callEntityMethod(this.grabbedThingID, "startDistanceGrab", args); + } Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); this.previousRoomControllerPosition = roomControllerPosition; @@ -271,8 +271,8 @@ Script.include("/~/system/libraries/controllers.js"); var handMoved = Vec3.multiply(worldHandDelta, radius); this.currentObjectPosition = Vec3.sum(this.currentObjectPosition, handMoved); - // XXX - // this.callEntityMethodOnGrabbed("continueDistantGrab"); + var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; + Entities.callEntityMethod(this.grabbedThingID, "continueDistanceGrab", args); // Update radialVelocity var lastVelocity = Vec3.multiply(worldHandDelta, 1.0 / deltaObjectTime); @@ -335,6 +335,10 @@ Script.include("/~/system/libraries/controllers.js"); this.distanceHolding = false; this.distanceRotating = false; Entities.deleteAction(this.grabbedThingID, this.actionID); + + var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; + Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args); + this.actionID = null; this.grabbedThingID = null; }; @@ -343,7 +347,8 @@ Script.include("/~/system/libraries/controllers.js"); var intersection = controllerData.rayPicks[this.hand]; var entityProperty = Entities.getEntityProperties(intersection.objectID); var entityType = entityProperty.type; - if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || intersection.type === RayPick.INTERSECTED_OVERLAY) { + if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || + intersection.type === RayPick.INTERSECTED_OVERLAY) { return true; } return false; @@ -354,7 +359,8 @@ Script.include("/~/system/libraries/controllers.js"); this.distanceHolding = false; var worldControllerRotation = getControllerWorldLocation(this.handToController(), true).orientation; - var controllerRotationDelta = Quat.multiply(worldControllerRotation, Quat.inverse(this.previousWorldControllerRotation)); + var controllerRotationDelta = + Quat.multiply(worldControllerRotation, Quat.inverse(this.previousWorldControllerRotation)); // Rotate entity by twice the delta rotation. controllerRotationDelta = Quat.multiply(controllerRotationDelta, controllerRotationDelta); @@ -426,7 +432,8 @@ Script.include("/~/system/libraries/controllers.js"); }; this.run = function (controllerData) { - if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.notPointingAtEntity(controllerData) || this.isPointingAtUI(controllerData)) { + if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || + this.notPointingAtEntity(controllerData) || this.isPointingAtUI(controllerData)) { this.endNearGrabAction(); this.laserPointerOff(); return makeRunningValues(false, [], []); @@ -471,6 +478,7 @@ Script.include("/~/system/libraries/controllers.js"); for (var j = 0; j < nearGrabReadiness.length; j++) { if (nearGrabReadiness[j].active) { this.laserPointerOff(); + this.endNearGrabAction(); return makeRunningValues(false, [], []); } } diff --git a/scripts/system/controllers/controllerModules/farTrigger.js b/scripts/system/controllers/controllerModules/farTrigger.js index 76fc87e607..a683044e6e 100644 --- a/scripts/system/controllers/controllerModules/farTrigger.js +++ b/scripts/system/controllers/controllerModules/farTrigger.js @@ -6,14 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat, - getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID, - enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, - makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, +/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset, + makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, - getControllerWorldLocation, projectOntoEntityXYPlane, getGrabbableData - + AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index 4301ddcaa7..cbe64b1870 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -5,13 +5,12 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, - NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues, - Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC, - AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset, - COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, - isInEditMode +/* jslint bitwise: true */ + +/* global Script, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, makeRunningValues, + Messages, makeDispatcherModuleParameters, AVATAR_SELF_ID, HMD, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, + COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, + getEnabledModuleByName, PICK_MAX_DISTANCE, isInEditMode, LaserPointers, RayPick */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index 3cef3219a3..bd7a64572a 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -111,6 +111,9 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); grabbedEntity: this.targetEntityID, joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" })); + + var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; + Entities.callEntityMethod(this.targetEntityID, "startNearGrab", args); }; // this is for when the action is going to time-out @@ -150,7 +153,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); var sensorScaleFactor = MyAvatar.sensorToWorldScale; for (var i = 0; i < nearbyEntityProperties.length; i++) { var props = nearbyEntityProperties[i]; - var handPosition = controllerData.controllerLocations[this.hand].position; if (props.distance > NEAR_GRAB_RADIUS * sensorScaleFactor) { break; } @@ -174,7 +176,8 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.targetEntityID = null; var targetProps = this.getTargetProps(controllerData); - if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE && controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { + if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE && + controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { return makeRunningValues(false, [], []); } @@ -193,7 +196,8 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.run = function (controllerData) { if (this.actionID) { - if (controllerData.triggerClicks[this.hand] < TRIGGER_OFF_VALUE && controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { + if (controllerData.triggerClicks[this.hand] < TRIGGER_OFF_VALUE && + controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { this.endNearGrabAction(); this.hapticTargetID = null; return makeRunningValues(false, [], []); diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index 33f4936e48..e08b61dbd5 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -6,11 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, - getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, - propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE, - makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS, - findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE +/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID, + enableDispatcherModule, disableDispatcherModule, propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, + TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS, findGroupParent, + Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -177,7 +176,8 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.grabbing = false; var targetProps = this.getTargetProps(controllerData); - if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE && controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { + if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE && + controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { return makeRunningValues(false, [], []); } @@ -196,7 +196,8 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.run = function (controllerData, deltaTime) { if (this.grabbing) { - if (controllerData.triggerClicks[this.hand] < TRIGGER_OFF_VALUE && controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { + if (controllerData.triggerClicks[this.hand] < TRIGGER_OFF_VALUE && + controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) { this.endNearParentingGrabEntity(); this.hapticTargetID = null; return makeRunningValues(false, [], []); diff --git a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js index b3f982eb1e..4ad17e6de9 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js @@ -6,11 +6,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, - getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, - Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, NEAR_GRAB_RADIUS - makeDispatcherModuleParameters, Overlays, makeRunningValues, resizeTablet, - getTabletWidthFromSettings +/* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID, + enableDispatcherModule, disableDispatcherModule, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, + makeDispatcherModuleParameters, Overlays, makeRunningValues, Vec3, resizeTablet, getTabletWidthFromSettings, + NEAR_GRAB_RADIUS */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); diff --git a/scripts/system/controllers/controllerModules/nearTrigger.js b/scripts/system/controllers/controllerModules/nearTrigger.js index 9f34eb702f..edea1f993d 100644 --- a/scripts/system/controllers/controllerModules/nearTrigger.js +++ b/scripts/system/controllers/controllerModules/nearTrigger.js @@ -6,9 +6,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, - enableDispatcherModule, disableDispatcherModule, getGrabbableData, Vec3, - TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS +/* global Script, Entities, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, getGrabbableData, + Vec3, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -64,7 +63,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.endNearTrigger = function (controllerData) { var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; - Entities.callEntityMethod(this.targetEntityID, "endNearTrigger", args); + Entities.callEntityMethod(this.targetEntityID, "stopNearTrigger", args); }; this.isReady = function (controllerData) { diff --git a/scripts/system/controllers/controllerModules/overlayLaserInput.js b/scripts/system/controllers/controllerModules/overlayLaserInput.js index f955029cae..218122e876 100644 --- a/scripts/system/controllers/controllerModules/overlayLaserInput.js +++ b/scripts/system/controllers/controllerModules/overlayLaserInput.js @@ -5,13 +5,11 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, - NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues, - Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC, - AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset, - COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, - DISPATCHER_PROPERTIES +/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, NULL_UUID, enableDispatcherModule, disableDispatcherModule, + makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, AVATAR_SELF_ID, HMD, + INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, + COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, + TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, LaserPointers, RayPick, ContextOverlay */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); diff --git a/scripts/system/controllers/controllerModules/scaleAvatar.js b/scripts/system/controllers/controllerModules/scaleAvatar.js index b98e26b1da..05804c967b 100644 --- a/scripts/system/controllers/controllerModules/scaleAvatar.js +++ b/scripts/system/controllers/controllerModules/scaleAvatar.js @@ -7,9 +7,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global getEntityCustomData, flatten, Xform, Script, Quat, Vec3, MyAvatar, Entities, Overlays, Settings, - Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset, - setGrabCommunications, Menu, HMD, isInEditMode, AvatarList */ +/* global Script, Vec3, MyAvatar, RIGHT_HAND */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ (function () { @@ -37,7 +35,8 @@ }; this.triggersPressed = function(controllerData) { - if (controllerData.triggerClicks[this.hand] && controllerData.secondaryValues[this.hand] > dispatcherUtils.BUMPER_ON_VALUE) { + if (controllerData.triggerClicks[this.hand] && + controllerData.secondaryValues[this.hand] > dispatcherUtils.BUMPER_ON_VALUE) { return true; } return false; @@ -58,7 +57,8 @@ var otherModule = this.getOtherModule(); if (this.triggersPressed(controllerData) && otherModule.triggersPressed(controllerData)) { if (this.hand === dispatcherUtils.RIGHT_HAND) { - var scalingCurrentDistance = Vec3.length(Vec3.subtract(controllerData.controllerLocations[this.hand].position, + var scalingCurrentDistance = + Vec3.length(Vec3.subtract(controllerData.controllerLocations[this.hand].position, controllerData.controllerLocations[this.otherHand()].position)); var newAvatarScale = (scalingCurrentDistance / this.scalingStartDistance) * this.scalingStartAvatarScale; diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index 99c4a68b35..230038adb5 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -8,7 +8,8 @@ /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues, Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC, - AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset + AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset, + getEnabledModuleByName */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -653,7 +654,8 @@ Script.include("/~/system/libraries/controllers.js"); }; this.overlayLaserActive = function(controllerData) { - var overlayLaserModule = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightOverlayLaserInput" : "LeftOverlayLaserInput"); + var overlayLaserModule = + getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightOverlayLaserInput" : "LeftOverlayLaserInput"); if (overlayLaserModule) { return overlayLaserModule.isReady(controllerData).active; } diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index cd588de443..548179761c 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -8,11 +8,11 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/* jslint bitwise: true */ -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, - getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, - Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions, - Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic +/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID, + enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Vec3, + LaserPointers, RayPick, HMD, Uuid, AvatarList */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ @@ -111,7 +111,7 @@ var seatEnd = { url: SEAT_MODEL_URL, dimensions: TARGET_MODEL_DIMENSIONS, ignoreRayIntersection: true -} +}; var teleportRenderStates = [{name: "cancel", path: cancelPath, end: cancelEnd}, {name: "teleport", path: teleportPath, end: teleportEnd}, @@ -228,8 +228,8 @@ function Teleporter(hand) { this.buttonPress = function(value) { _this.buttonValue = value; - } - + }; + this.parameters = makeDispatcherModuleParameters( 80, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], @@ -277,7 +277,6 @@ function Teleporter(hand) { } }; - this.isReady = function(controllerData, deltaTime) { var otherModule = this.getOtherModule(); if (_this.buttonValue !== 0 && !otherModule.active) { @@ -287,7 +286,7 @@ function Teleporter(hand) { } return makeRunningValues(false, [], []); }; - + this.run = function(controllerData, deltaTime) { //_this.state = TELEPORTER_STATES.TARGETTING; @@ -329,7 +328,6 @@ function Teleporter(hand) { } else { result = LaserPointers.getPrevRayPickResult(_this.teleportRayHandVisible); } - teleportLocationType = getTeleportTargetType(result); } @@ -355,7 +353,7 @@ function Teleporter(hand) { if (_this.buttonValue !== 0) { return makeRunningValues(true, [], []); } - + if (target === TARGET.NONE || target === TARGET.INVALID || this.state === TELEPORTER_STATES.COOL_IN) { // Do nothing } else if (target === TARGET.SEAT) { @@ -390,7 +388,7 @@ function Teleporter(hand) { } }; } - + // related to repositioning the avatar after you teleport var FOOT_JOINT_NAMES = ["RightToe_End", "RightToeBase", "RightFoot"]; var DEFAULT_ROOT_TO_FOOT_OFFSET = 0.5; @@ -503,7 +501,7 @@ function Teleporter(hand) { disableDispatcherModule("RightTeleporter"); } Script.scriptEnding.connect(cleanup); - + var setIgnoreEntities = function() { LaserPointers.setIgnoreEntities(teleporter.teleportRayRightVisible, ignoredEntities); LaserPointers.setIgnoreEntities(teleporter.teleportRayRightInvisible, ignoredEntities); @@ -511,8 +509,8 @@ function Teleporter(hand) { LaserPointers.setIgnoreEntities(teleporter.teleportRayLeftInvisible, ignoredEntities); LaserPointers.setIgnoreEntities(teleporter.teleportRayHeadVisible, ignoredEntities); LaserPointers.setIgnoreEntities(teleporter.teleportRayHeadInvisible, ignoredEntities); - } - + }; + var isDisabled = false; var handleTeleportMessages = function(channel, message, sender) { if (sender === MyAvatar.sessionUUID) { @@ -529,7 +527,9 @@ function Teleporter(hand) { if (message === 'none') { isDisabled = false; } - } else if (channel === 'Hifi-Teleport-Ignore-Add' && !Uuid.isNull(message) && ignoredEntities.indexOf(message) === -1) { + } else if (channel === 'Hifi-Teleport-Ignore-Add' && + !Uuid.isNull(message) && + ignoredEntities.indexOf(message) === -1) { ignoredEntities.push(message); setIgnoreEntities(); } else if (channel === 'Hifi-Teleport-Ignore-Remove' && !Uuid.isNull(message)) { @@ -541,7 +541,7 @@ function Teleporter(hand) { } } }; - + Messages.subscribe('Hifi-Teleport-Disabler'); Messages.subscribe('Hifi-Teleport-Ignore-Add'); Messages.subscribe('Hifi-Teleport-Ignore-Remove'); diff --git a/scripts/system/controllers/controllerModules/webEntityLaserInput.js b/scripts/system/controllers/controllerModules/webEntityLaserInput.js index 75ad3a60cb..339f248547 100644 --- a/scripts/system/controllers/controllerModules/webEntityLaserInput.js +++ b/scripts/system/controllers/controllerModules/webEntityLaserInput.js @@ -7,13 +7,10 @@ /* jslint bitwise: true */ -/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat, - getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID, - enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, - makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, +/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Vec3, Quat, getGrabPointSphereOffset, + makeRunningValues, Entities, NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC - + AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, ZERO_VEC, Overlays */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 8b61226235..569d4812dc 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -655,7 +655,7 @@ var toolBar = (function () { selectionDisplay.triggerMapping.disable(); tablet.landscape = false; } else { - tablet.loadQMLSource("Edit.qml"); + tablet.loadQMLSource("Edit.qml", true); UserActivityLogger.enabledEdit(); entityListTool.setVisible(true); gridTool.setVisible(true); diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 42a938e78d..43cd281bbd 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -1,4 +1,4 @@ -