mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 11:02:24 +02:00
Merge branch 'master' into feature/ant-man
This commit is contained in:
commit
0757f513af
75 changed files with 590 additions and 456 deletions
|
@ -354,15 +354,16 @@ void Agent::scriptRequestFinished() {
|
|||
|
||||
|
||||
void Agent::executeScript() {
|
||||
_scriptEngine = std::unique_ptr<ScriptEngine>(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<RecordingScriptingInterface>()->setScriptEngine(_scriptEngine.get());
|
||||
DependencyManager::get<RecordingScriptingInterface>()->setScriptEngine(_scriptEngine);
|
||||
|
||||
// setup an Avatar for the script to use
|
||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||
|
||||
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
|
||||
|
|
|
@ -88,7 +88,7 @@ private:
|
|||
void encodeFrameOfZeros(QByteArray& encodedZeros);
|
||||
void computeLoudness(const QByteArray* decodedBuffer, QSharedPointer<ScriptableAvatar>);
|
||||
|
||||
std::unique_ptr<ScriptEngine> _scriptEngine;
|
||||
ScriptEnginePointer _scriptEngine;
|
||||
EntityEditPacketSender _entityEditSender;
|
||||
EntityTreeHeadlessViewer _entityViewer;
|
||||
|
||||
|
|
|
@ -415,8 +415,7 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
|||
|
||||
void EntityScriptServer::resetEntitiesScriptEngine() {
|
||||
auto engineName = QString("about:Entities %1").arg(++_entitiesScriptEngineCount);
|
||||
auto newEngine = QSharedPointer<ScriptEngine>(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<EntityScriptingInterface>()->setEntitiesScriptEngine(newEngine.data());
|
||||
auto newEngineSP = qSharedPointerCast<EntitiesScriptEngineProvider>(newEngine);
|
||||
DependencyManager::get<EntityScriptingInterface>()->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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ private:
|
|||
bool _shuttingDown { false };
|
||||
|
||||
static int _entitiesScriptEngineCount;
|
||||
QSharedPointer<ScriptEngine> _entitiesScriptEngine;
|
||||
ScriptEnginePointer _entitiesScriptEngine;
|
||||
EntityEditPacketSender _entityEditSender;
|
||||
EntityTreeHeadlessViewer _entityViewer;
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -963,7 +963,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
|
||||
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>().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<NodeList>()->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<OffscreenUi>()->getFlags());
|
||||
scriptEngine->registerGlobalObject("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
|
||||
|
||||
qScriptRegisterMetaType(scriptEngine, wrapperToScriptValue<ToolbarProxy>, wrapperFromScriptValue<ToolbarProxy>);
|
||||
qScriptRegisterMetaType(scriptEngine, wrapperToScriptValue<ToolbarButtonProxy>, wrapperFromScriptValue<ToolbarButtonProxy>);
|
||||
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<ToolbarProxy>, wrapperFromScriptValue<ToolbarProxy>);
|
||||
qScriptRegisterMetaType(scriptEngine.data(),
|
||||
wrapperToScriptValue<ToolbarButtonProxy>, wrapperFromScriptValue<ToolbarButtonProxy>);
|
||||
scriptEngine->registerGlobalObject("Toolbars", DependencyManager::get<ToolbarScriptingInterface>().data());
|
||||
|
||||
qScriptRegisterMetaType(scriptEngine, wrapperToScriptValue<TabletProxy>, wrapperFromScriptValue<TabletProxy>);
|
||||
qScriptRegisterMetaType(scriptEngine, wrapperToScriptValue<TabletButtonProxy>, wrapperFromScriptValue<TabletButtonProxy>);
|
||||
qScriptRegisterMetaType(scriptEngine.data(), wrapperToScriptValue<TabletProxy>, wrapperFromScriptValue<TabletProxy>);
|
||||
qScriptRegisterMetaType(scriptEngine.data(),
|
||||
wrapperToScriptValue<TabletButtonProxy>, wrapperFromScriptValue<TabletButtonProxy>);
|
||||
scriptEngine->registerGlobalObject("Tablet", DependencyManager::get<TabletScriptingInterface>().data());
|
||||
|
||||
|
||||
DependencyManager::get<TabletScriptingInterface>().data()->setToolbarScriptingInterface(DependencyManager::get<ToolbarScriptingInterface>().data());
|
||||
auto toolbarScriptingInterface = DependencyManager::get<ToolbarScriptingInterface>().data();
|
||||
DependencyManager::get<TabletScriptingInterface>().data()->setToolbarScriptingInterface(toolbarScriptingInterface);
|
||||
|
||||
scriptEngine->registerGlobalObject("Window", DependencyManager::get<WindowScriptingInterface>().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<DdeFaceTracker>().data());
|
||||
|
||||
|
@ -6064,11 +6066,11 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
scriptEngine->registerGlobalObject("LimitlessSpeechRecognition", DependencyManager::get<LimitlessVoiceRecognitionScriptingInterface>().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<controller::ScriptingInterface>();
|
||||
scriptEngine->registerGlobalObject("Controller", scriptingInterface.data());
|
||||
UserInputMapper::registerControllerTypes(scriptEngine);
|
||||
UserInputMapper::registerControllerTypes(scriptEngine.data());
|
||||
|
||||
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
||||
scriptEngine->registerGlobalObject("Recording", recordingInterface.data());
|
||||
|
@ -6079,14 +6081,19 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
scriptEngine->registerGlobalObject("Selection", DependencyManager::get<SelectionScriptingInterface>().data());
|
||||
scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().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<ScriptEngines>().data(), &ScriptEngines::onPrintedMessage);
|
||||
connect(scriptEngine, &ScriptEngine::errorMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onErrorMessage);
|
||||
connect(scriptEngine, &ScriptEngine::warningMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onWarningMessage);
|
||||
connect(scriptEngine, &ScriptEngine::infoMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onInfoMessage);
|
||||
connect(scriptEngine, &ScriptEngine::clearDebugWindow, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onClearDebugWindow);
|
||||
connect(scriptEngine.data(), &ScriptEngine::printedMessage,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onPrintedMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::errorMessage,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onErrorMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::warningMessage,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onWarningMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::infoMessage,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onInfoMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::clearDebugWindow,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onClearDebugWindow);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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<Avatar>(avatarIterator.value());
|
||||
avatar->postUpdate(deltaTime);
|
||||
avatar->postUpdate(deltaTime, scene);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<SceneScriptingInterface>()->shouldRenderAvatars() && _skeletonModel->initWhenReady(qApp->getMain3DScene())) {
|
||||
if (_skeletonModel->isLoaded() && !_skeletonModel->getRig().getAnimNode()) {
|
||||
initHeadBones();
|
||||
_skeletonModel->setCauterizeBoneSet(_headBoneSet);
|
||||
_fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <SettingHandle.h>
|
||||
#include <Rig.h>
|
||||
#include <Sound.h>
|
||||
#include <ScriptEngine.h>
|
||||
|
||||
#include <controllers/Pose.h>
|
||||
#include <controllers/Actions.h>
|
||||
|
@ -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; }
|
||||
|
|
|
@ -61,7 +61,7 @@ void _writeLines(const QString& filename, const QList<QString>& lines) {
|
|||
QTextStream(&file) << json;
|
||||
}
|
||||
|
||||
JSConsole::JSConsole(QWidget* parent, const QSharedPointer<ScriptEngine>& 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>& scriptEngine) {
|
||||
void JSConsole::setScriptEngine(const ScriptEnginePointer& scriptEngine) {
|
||||
if (_scriptEngine == scriptEngine && scriptEngine != NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ void JSConsole::setScriptEngine(const QSharedPointer<ScriptEngine>& scriptEngin
|
|||
|
||||
// if scriptEngine is NULL then create one and keep track of it using _ownScriptEngine
|
||||
if (scriptEngine.isNull()) {
|
||||
_scriptEngine = QSharedPointer<ScriptEngine>(DependencyManager::get<ScriptEngines>()->loadScript(_consoleFileName, false), &QObject::deleteLater);
|
||||
_scriptEngine = DependencyManager::get<ScriptEngines>()->loadScript(_consoleFileName, false);
|
||||
} else {
|
||||
_scriptEngine = scriptEngine;
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ const int CONSOLE_HEIGHT = 200;
|
|||
class JSConsole : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
JSConsole(QWidget* parent, const QSharedPointer<ScriptEngine>& scriptEngine = QSharedPointer<ScriptEngine>());
|
||||
JSConsole(QWidget* parent, const ScriptEnginePointer& scriptEngine = ScriptEnginePointer());
|
||||
~JSConsole();
|
||||
|
||||
void setScriptEngine(const QSharedPointer<ScriptEngine>& scriptEngine = QSharedPointer<ScriptEngine>());
|
||||
void setScriptEngine(const ScriptEnginePointer& scriptEngine = ScriptEnginePointer());
|
||||
void clear();
|
||||
|
||||
public slots:
|
||||
|
@ -66,7 +66,7 @@ private:
|
|||
QString _savedHistoryFilename;
|
||||
QList<QString> _commandHistory;
|
||||
QString _rootCommand;
|
||||
QSharedPointer<ScriptEngine> _scriptEngine;
|
||||
ScriptEnginePointer _scriptEngine;
|
||||
static const QString _consoleFileName;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ TestingDialog::TestingDialog(QWidget* parent) :
|
|||
_console->setFixedHeight(TESTING_CONSOLE_HEIGHT);
|
||||
|
||||
auto _engines = DependencyManager::get<ScriptEngines>();
|
||||
_engine.reset(_engines->loadScript(qApp->applicationDirPath() + testRunnerRelativePath));
|
||||
_engine = _engines->loadScript(qApp->applicationDirPath() + testRunnerRelativePath);
|
||||
_console->setScriptEngine(_engine);
|
||||
connect(_engine.data(), &ScriptEngine::finished, this, &TestingDialog::onTestingFinished);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
|
||||
private:
|
||||
std::unique_ptr<JSConsole> _console;
|
||||
QSharedPointer<ScriptEngine> _engine;
|
||||
ScriptEnginePointer _engine;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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<Overlay>(itemID, [](Overlay& data) {
|
||||
auto overlay3D = dynamic_cast<Base3DOverlay*>(&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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<GeometryCache>();
|
||||
if (color.a < OPAQUE_ALPHA_THRESHOLD) {
|
||||
geometryCache->bindWebBrowserProgram(batch, true);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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<ScriptEngine>(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<EntityScriptingInterface>()->setEntitiesScriptEngine(_entitiesScriptEngine.data());
|
||||
auto entitiesScriptEngineProvider = qSharedPointerCast<EntitiesScriptEngineProvider>(_entitiesScriptEngine);
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(entitiesScriptEngineProvider);
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::clear() {
|
||||
|
|
|
@ -181,7 +181,7 @@ private:
|
|||
QVector<EntityItemID> _currentEntitiesInside;
|
||||
|
||||
bool _wantScripts;
|
||||
QSharedPointer<ScriptEngine> _entitiesScriptEngine;
|
||||
ScriptEnginePointer _entitiesScriptEngine;
|
||||
|
||||
void playEntityCollisionSound(const EntityItemPointer& entity, const Collision& collision);
|
||||
|
||||
|
|
|
@ -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<ModelPointer>([&] {
|
||||
return _model;
|
||||
});
|
||||
}
|
||||
|
||||
bool ModelEntityWrapper::isModelLoaded() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
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<bool>([&] {
|
||||
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<RenderableModelEntityItem*>(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<glm::mat4> 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<bool>& 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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<TextureCache>()->getTexture(QUrl(path));
|
||||
if (!textures.isEmpty()) {
|
||||
entityTextures = QUrl(textures);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_texture || _texture->getURL() != entityTextures) {
|
||||
_texture = DependencyManager::get<TextureCache>()->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<TextureCache>()->getWhiteTexture());
|
||||
}
|
||||
|
||||
batch.setInputFormat(polylineFormat);
|
||||
|
|
|
@ -47,6 +47,7 @@ protected:
|
|||
void updateGeometry(const std::vector<Vertex>& vertices);
|
||||
static std::vector<Vertex> updateVertices(const QVector<glm::vec3>& points, const QVector<glm::vec3>& normals, const QVector<float>& strokeWidths);
|
||||
|
||||
Transform _polylineTransform;
|
||||
QVector<glm::vec3> _lastPoints;
|
||||
QVector<glm::vec3> _lastNormals;
|
||||
QVector<float> _lastStrokeWidths;
|
||||
|
@ -54,7 +55,6 @@ protected:
|
|||
gpu::BufferView _uniformBuffer;
|
||||
uint32_t _numVertices { 0 };
|
||||
bool _empty{ true };
|
||||
QString _lastTextures;
|
||||
NetworkTexturePointer _texture;
|
||||
};
|
||||
|
||||
|
|
|
@ -539,7 +539,7 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine) {
|
||||
void EntityScriptingInterface::setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> engine) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||
_entitiesScriptEngine = engine;
|
||||
}
|
||||
|
@ -749,7 +749,7 @@ bool EntityPropertyMetadataRequest::script(EntityItemID entityID, QScriptValue h
|
|||
request->deleteLater();
|
||||
});
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
entityScriptingInterface->withEntitiesScriptEngine([&](EntitiesScriptEngineProvider* entitiesScriptEngine) {
|
||||
entityScriptingInterface->withEntitiesScriptEngine([&](QSharedPointer<EntitiesScriptEngineProvider> entitiesScriptEngine) {
|
||||
if (entitiesScriptEngine) {
|
||||
request->setFuture(entitiesScriptEngine->getLocalEntityScriptDetails(entityID));
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
|
||||
void setEntityTree(EntityTreePointer modelTree);
|
||||
EntityTreePointer getEntityTree() { return _entityTree; }
|
||||
void setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine);
|
||||
void setEntitiesScriptEngine(QSharedPointer<EntitiesScriptEngineProvider> 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<void(EntitiesScriptEngineProvider*)> function) {
|
||||
void withEntitiesScriptEngine(std::function<void(QSharedPointer<EntitiesScriptEngineProvider>)> function) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||
function(_entitiesScriptEngine);
|
||||
};
|
||||
|
@ -427,7 +427,7 @@ private:
|
|||
EntityTreePointer _entityTree;
|
||||
|
||||
std::recursive_mutex _entitiesScriptEngineLock;
|
||||
EntitiesScriptEngineProvider* _entitiesScriptEngine { nullptr };
|
||||
QSharedPointer<EntitiesScriptEngineProvider> _entitiesScriptEngine;
|
||||
|
||||
bool _bidOnSimulationOwnership { false };
|
||||
float _currentAvatarEnergy = { FLT_MAX };
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
#ifndef hifi_AbstractScriptingServicesInterface_h
|
||||
#define hifi_AbstractScriptingServicesInterface_h
|
||||
|
||||
class ScriptEngine;
|
||||
#include <BaseScriptEngine.h>
|
||||
|
||||
/// 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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <BaseScriptEngine.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <recording/ClipCache.h>
|
||||
#include <recording/Forward.h>
|
||||
|
@ -28,7 +29,7 @@ class RecordingScriptingInterface : public QObject, public Dependency {
|
|||
public:
|
||||
RecordingScriptingInterface();
|
||||
|
||||
void setScriptEngine(QScriptEngine* scriptEngine) { _scriptEngine = scriptEngine; }
|
||||
void setScriptEngine(QSharedPointer<BaseScriptEngine> 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<BaseScriptEngine> _scriptEngine;
|
||||
QSet<recording::NetworkClipLoaderPointer> _clipLoaders;
|
||||
};
|
||||
|
||||
|
|
|
@ -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<ScriptEngines>()->addScriptEngine(qSharedPointerCast<ScriptEngine>(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<ScriptEngines>())
|
||||
{
|
||||
DependencyManager::get<ScriptEngines>()->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<ScriptEngines>();
|
||||
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<ScriptEngine>(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<ScriptEngine>(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<ScriptableResourceRawPtr>(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<ScriptableResource::State>();
|
||||
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<ScriptEngine>(sharedFromThis()));
|
||||
globalObject().setProperty("Resource", resourcePrototype);
|
||||
setDefaultPrototype(qMetaTypeId<ScriptableResource*>(), resourcePrototype);
|
||||
qScriptRegisterMetaType(this, scriptableResourceToScriptValue, scriptableResourceFromScriptValue);
|
||||
|
@ -1178,7 +1176,7 @@ void ScriptEngine::run() {
|
|||
}
|
||||
}
|
||||
|
||||
emit finished(_fileNameString, this);
|
||||
emit finished(_fileNameString, qSharedPointerCast<ScriptEngine>(sharedFromThis()));
|
||||
|
||||
_isRunning = false;
|
||||
emit runningStateChanged();
|
||||
|
|
|
@ -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<bool> _enableExtendedJSExceptions { _SETTINGS_ENABLE_EXTENDED_EXCEPTIONS, true };
|
||||
|
||||
QSharedPointer<ScriptEngines> _scriptEngines;
|
||||
};
|
||||
|
||||
ScriptEnginePointer scriptEngineFactory(ScriptEngine::Context context,
|
||||
const QString& scriptContents,
|
||||
const QString& fileNameString);
|
||||
|
||||
#endif // hifi_ScriptEngine_h
|
||||
|
|
|
@ -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<ScriptEngine*> i(_allKnownScriptEngines);
|
||||
QMutableSetIterator<ScriptEnginePointer> 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<QUrl, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
|
||||
for (QHash<QUrl, ScriptEnginePointer>::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>();
|
||||
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<ScriptEngine*>(sender());
|
||||
QSharedPointer<BaseScriptEngine> baseScriptEngine = qobject_cast<ScriptEngine*>(sender())->sharedFromThis();
|
||||
ScriptEnginePointer scriptEngine = qSharedPointerCast<ScriptEngine>(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);
|
||||
|
|
|
@ -33,7 +33,7 @@ class ScriptEngines : public QObject, public Dependency {
|
|||
Q_PROPERTY(ScriptsModelFilter* scriptsModelFilter READ scriptsModelFilter CONSTANT)
|
||||
|
||||
public:
|
||||
using ScriptInitializer = std::function<void(ScriptEngine*)>;
|
||||
using ScriptInitializer = std::function<void(ScriptEnginePointer)>;
|
||||
|
||||
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<QUrl, ScriptEngine*> _scriptEnginesHash;
|
||||
QSet<ScriptEngine*> _allKnownScriptEngines;
|
||||
QHash<QUrl, ScriptEnginePointer> _scriptEnginesHash;
|
||||
QSet<ScriptEnginePointer> _allKnownScriptEngines;
|
||||
QMutex _allScriptsMutex;
|
||||
std::list<ScriptInitializer> _scriptInitializers;
|
||||
mutable Setting::Handle<QString> _scriptsLocationHandle;
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
#include <QtCore/QDebug>
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
class ScriptEngine;
|
||||
using ScriptEnginePointer = QSharedPointer<ScriptEngine>;
|
||||
|
||||
// common base class for extending QScriptEngine itself
|
||||
class BaseScriptEngine : public QScriptEngine, public QEnableSharedFromThis<BaseScriptEngine> {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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, [], []);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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, [], []);
|
||||
|
|
|
@ -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, [], []);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
// entityProperties.html
|
||||
//
|
||||
// Created by Ryan Huffman on 13 Nov 2014
|
||||
|
@ -136,17 +136,21 @@
|
|||
|
||||
<fieldset class="column" id="group-cloneable-group" style="display:none;">
|
||||
<legend class="sub-section-header">
|
||||
<span>Cloneable Settings</span>
|
||||
<span>Cloneable Settings</span>
|
||||
</legend>
|
||||
<fieldset class="minor">
|
||||
<div><label>Clone Lifetime</label><input type="number" data-user-data-type="cloneLifetime" id="property-cloneable-lifetime"></div>
|
||||
<div><label>Clone Lifetime</label><input type="number" data-user-data-type="cloneLifetime" id="property-cloneable-lifetime"></div>
|
||||
</fieldset>
|
||||
<fieldset class="minor">
|
||||
<div><label>Clone Limit </label><input type="number" data-user-data-type="cloneLimit" id="property-cloneable-limit"></div>
|
||||
<div><label>Clone Limit</label><input type="number" data-user-data-type="cloneLimit" id="property-cloneable-limit"></div>
|
||||
</fieldset>
|
||||
<div class="property checkbox">
|
||||
<input type="checkbox" id="property-cloneable-dynamic">
|
||||
<label for="property-cloneable-dynamic">Clone Dynamic</label>
|
||||
<input type="checkbox" id="property-cloneable-dynamic">
|
||||
<label for="property-cloneable-dynamic">Clone Dynamic</label>
|
||||
</div>
|
||||
<div class="property checkbox">
|
||||
<input type="checkbox" id="property-cloneable-avatarEntity">
|
||||
<label for="property-cloneable-avatarEntity">Clone Avatar Entity</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
|
|
@ -554,6 +554,7 @@ function loaded() {
|
|||
|
||||
var elCloneable = document.getElementById("property-cloneable");
|
||||
var elCloneableDynamic = document.getElementById("property-cloneable-dynamic");
|
||||
var elCloneableAvatarEntity = document.getElementById("property-cloneable-avatarEntity");
|
||||
var elCloneableGroup = document.getElementById("group-cloneable-group");
|
||||
var elCloneableLifetime = document.getElementById("property-cloneable-lifetime");
|
||||
var elCloneableLimit = document.getElementById("property-cloneable-limit");
|
||||
|
@ -844,25 +845,29 @@ function loaded() {
|
|||
parsedUserData = JSON.parse(properties.userData);
|
||||
|
||||
if ("grabbableKey" in parsedUserData) {
|
||||
if ("grabbable" in parsedUserData["grabbableKey"]) {
|
||||
elGrabbable.checked = parsedUserData["grabbableKey"].grabbable;
|
||||
var grabbableData = parsedUserData["grabbableKey"];
|
||||
if ("grabbable" in grabbableData) {
|
||||
elGrabbable.checked = grabbableData.grabbable;
|
||||
}
|
||||
if ("wantsTrigger" in parsedUserData["grabbableKey"]) {
|
||||
elWantsTrigger.checked = parsedUserData["grabbableKey"].wantsTrigger;
|
||||
if ("wantsTrigger" in grabbableData) {
|
||||
elWantsTrigger.checked = grabbableData.wantsTrigger;
|
||||
}
|
||||
if ("ignoreIK" in parsedUserData["grabbableKey"]) {
|
||||
elIgnoreIK.checked = parsedUserData["grabbableKey"].ignoreIK;
|
||||
if ("ignoreIK" in grabbableData) {
|
||||
elIgnoreIK.checked = grabbableData.ignoreIK;
|
||||
}
|
||||
if ("cloneable" in parsedUserData["grabbableKey"]) {
|
||||
elCloneable.checked = parsedUserData["grabbableKey"].cloneable;
|
||||
if ("cloneable" in grabbableData) {
|
||||
elCloneable.checked = grabbableData.cloneable;
|
||||
elCloneableGroup.style.display = elCloneable.checked ? "block": "none";
|
||||
elCloneableDynamic.checked = parsedUserData["grabbableKey"].cloneDynamic ? parsedUserData["grabbableKey"].cloneDynamic : properties.dynamic;
|
||||
elCloneableDynamic.checked = grabbableData.cloneDynamic ? grabbableData.cloneDynamic : properties.dynamic;
|
||||
if (elCloneable.checked) {
|
||||
if ("cloneLifetime" in parsedUserData["grabbableKey"]) {
|
||||
elCloneableLifetime.value = parsedUserData["grabbableKey"].cloneLifetime ? parsedUserData["grabbableKey"].cloneLifetime : 300;
|
||||
if ("cloneLifetime" in grabbableData) {
|
||||
elCloneableLifetime.value = grabbableData.cloneLifetime ? grabbableData.cloneLifetime : 300;
|
||||
}
|
||||
if ("cloneLimit" in parsedUserData["grabbableKey"]) {
|
||||
elCloneableLimit.value = parsedUserData["grabbableKey"].cloneLimit ? parsedUserData["grabbableKey"].cloneLimit : 0;
|
||||
if ("cloneLimit" in grabbableData) {
|
||||
elCloneableLimit.value = grabbableData.cloneLimit ? grabbableData.cloneLimit : 0;
|
||||
}
|
||||
if ("cloneAvatarEntity" in grabbableData) {
|
||||
elCloneableAvatarEntity.checked = grabbableData.cloneAvatarEntity ? grabbableData.cloneAvatarEntity : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1114,9 +1119,14 @@ function loaded() {
|
|||
}
|
||||
userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, properties.dynamic);
|
||||
});
|
||||
elCloneableDynamic.addEventListener('change', function (event){
|
||||
elCloneableDynamic.addEventListener('change', function(event) {
|
||||
userDataChanger("grabbableKey", "cloneDynamic", event.target, elUserData, -1);
|
||||
});
|
||||
|
||||
elCloneableAvatarEntity.addEventListener('change', function(event) {
|
||||
userDataChanger("grabbableKey", "cloneAvatarEntity", event.target, elUserData, -1);
|
||||
});
|
||||
|
||||
elCloneable.addEventListener('change', function (event) {
|
||||
var checked = event.target.checked;
|
||||
if (checked) {
|
||||
|
@ -1124,6 +1134,7 @@ function loaded() {
|
|||
cloneLifetime: elCloneableLifetime,
|
||||
cloneLimit: elCloneableLimit,
|
||||
cloneDynamic: elCloneableDynamic,
|
||||
cloneAvatarEntity: elCloneableAvatarEntity,
|
||||
cloneable: event.target,
|
||||
grabbable: null
|
||||
}, elUserData, {});
|
||||
|
@ -1134,6 +1145,7 @@ function loaded() {
|
|||
cloneLifetime: null,
|
||||
cloneLimit: null,
|
||||
cloneDynamic: null,
|
||||
cloneAvatarEntity: null,
|
||||
cloneable: false
|
||||
}, elUserData, {});
|
||||
elCloneableGroup.style.display = "none";
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global entityIsCloneable:true, getGrabbableData:true, cloneEntity:true propsAreCloneDynamic:true */
|
||||
/* global entityIsCloneable:true, getGrabbableData:true, cloneEntity:true, propsAreCloneDynamic:true, Script,
|
||||
propsAreCloneDynamic:true, Entities*/
|
||||
|
||||
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||
|
||||
|
@ -72,6 +73,7 @@ cloneEntity = function(props, worldEntityProps) {
|
|||
var lifetime = grabInfo.cloneLifetime ? grabInfo.cloneLifetime : 300;
|
||||
var dynamic = grabInfo.cloneDynamic ? grabInfo.cloneDynamic : false;
|
||||
var triggerable = grabInfo.triggerable ? grabInfo.triggerable : false;
|
||||
var avatarEntity = grabInfo.cloneAvatarEntity ? grabInfo.cloneAvatarEntity : false;
|
||||
var cUserData = Object.assign({}, JSON.parse(cloneableProps.userData));
|
||||
var cProperties = Object.assign({}, cloneableProps);
|
||||
|
||||
|
@ -80,6 +82,7 @@ cloneEntity = function(props, worldEntityProps) {
|
|||
delete cUserData.grabbableKey.cloneable;
|
||||
delete cUserData.grabbableKey.cloneDynamic;
|
||||
delete cUserData.grabbableKey.cloneLimit;
|
||||
delete cUserData.grabbableKey.cloneAvatarEntity;
|
||||
delete cProperties.id;
|
||||
|
||||
|
||||
|
@ -90,6 +93,6 @@ cloneEntity = function(props, worldEntityProps) {
|
|||
cProperties.lifetime = lifetime;
|
||||
cProperties.userData = JSON.stringify(cUserData);
|
||||
|
||||
var cloneID = Entities.addEntity(cProperties);
|
||||
var cloneID = Entities.addEntity(cProperties, avatarEntity);
|
||||
return cloneID;
|
||||
};
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
projectOntoOverlayXYPlane:true,
|
||||
entityHasActions:true,
|
||||
ensureDynamic:true,
|
||||
findGroupParent:true
|
||||
findGroupParent:true,
|
||||
BUMPER_ON_VALUE:true
|
||||
*/
|
||||
|
||||
MSECS_PER_SEC = 1000.0;
|
||||
|
|
Loading…
Reference in a new issue