From 52dacaab02468e6c806b7df05ac17a88ccc49c6c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Oct 2014 10:36:44 -0700 Subject: [PATCH 01/11] Update entity editing to force SPACE_LOCAL for single-selection --- examples/libraries/entitySelectionTool.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index b70c2187c2..7815946fd1 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -78,6 +78,8 @@ SelectionManager = (function() { that.worldDimensions = null; that.worldPosition = null; } else if (that.selections.length == 1) { + SelectionDisplay.setSpaceMode(SPACE_LOCAL); + var properties = Entities.getEntityProperties(that.selections[0]); that.localDimensions = properties.dimensions; that.localPosition = properties.position; From 078d14ae58d560f9d36f2157d7f8f39e6931cb87 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Oct 2014 10:36:58 -0700 Subject: [PATCH 02/11] Fix rotation overlay size with multi-selection --- examples/libraries/entitySelectionTool.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 7815946fd1..0153f7fc3d 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -624,8 +624,8 @@ SelectionDisplay = (function () { } - var diagonal = (Vec3.length(properties.dimensions) / 2) * 1.1; - var halfDimensions = Vec3.multiply(properties.dimensions, 0.5); + var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; + var halfDimensions = Vec3.multiply(selectionManager.worldDimensions, 0.5); innerRadius = diagonal; outerRadius = diagonal * 1.15; var innerActive = false; From 5b9806dc0dd9bb419421c4345f45c2d2e0902309 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Oct 2014 10:37:17 -0700 Subject: [PATCH 03/11] Fix deletion with multi-selection --- examples/libraries/entitySelectionTool.js | 2 +- examples/newEditEntities.js | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 0153f7fc3d..f4f068742f 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -927,7 +927,7 @@ SelectionDisplay = (function () { }; that.updateHandles = function(entityID) { - if (!entitySelected) { + if (SelectionManager.selections.length == 0) { that.setOverlaysVisible(false); return; } diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 9b46cdaf3f..402ad94417 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -608,9 +608,12 @@ function handeMenuEvent(menuItem) { } else if (menuItem == "Delete") { if (entitySelected) { print(" Delete Entity.... selectedEntityID="+ selectedEntityID); - Entities.deleteEntity(selectedEntityID); + for (var i = 0; i < selectionManager.selections.length; i++) { + Entities.deleteEntity(selectionManager.selections[i]); + } selectionDisplay.unselect(selectedEntityID); entitySelected = false; + selectionManager.clearSelections(); } else { print(" Delete Entity.... not holding..."); } @@ -653,7 +656,7 @@ Controller.keyReleaseEvent.connect(function (event) { if (event.text == "`") { handeMenuEvent("Edit Properties..."); } - if (event.text == "BACKSPACE") { + if (event.text == "BACKSPACE" || event.text == "DELETE") { handeMenuEvent("Delete"); } else if (event.text == "TAB") { selectionDisplay.toggleSpaceMode(); From 0bda7699a66d5c0dc53f15a4182715a3397d67e9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Oct 2014 10:38:24 -0700 Subject: [PATCH 04/11] Disable properties menu with multi-selection --- examples/newEditEntities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 402ad94417..ae0d018b14 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -621,7 +621,7 @@ function handeMenuEvent(menuItem) { // good place to put the properties dialog editModelID = -1; - if (entitySelected) { + if (selectionManager.selections.length == 1) { print(" Edit Properties.... selectedEntityID="+ selectedEntityID); editModelID = selectedEntityID; } else { From 14555c4534a2b96607c9ccdc7e40f011180bdc2f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Oct 2014 14:54:04 -0700 Subject: [PATCH 05/11] Add UndoStackScriptingInterface and support when editing entities --- examples/libraries/entitySelectionTool.js | 59 +++++++++++++++++-- examples/newEditEntities.js | 2 +- interface/src/Application.cpp | 4 ++ interface/src/Application.h | 4 ++ .../src/UndoStackScriptingInterface.cpp | 46 +++++++++++++++ .../src/UndoStackScriptingInterface.h | 47 +++++++++++++++ 6 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 libraries/script-engine/src/UndoStackScriptingInterface.cpp create mode 100644 libraries/script-engine/src/UndoStackScriptingInterface.h diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index f4f068742f..f1a94dbdd7 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -845,7 +845,7 @@ SelectionDisplay = (function () { Overlays.editOverlay(grabberMoveUp, { visible: translateHandlesVisible, position: { x: boundsCenter.x, y: top + grabberMoveUpOffset, z: boundsCenter.z } }); - that.updateHandles(entityID); + that.updateHandles(); Overlays.editOverlay(baseOfEntityProjectionOverlay, @@ -926,18 +926,17 @@ SelectionDisplay = (function () { entitySelected = false; }; - that.updateHandles = function(entityID) { + that.updateHandles = function() { + // print("Updating handles"); if (SelectionManager.selections.length == 0) { that.setOverlaysVisible(false); return; } - var properties = Entities.getEntityProperties(entityID); - var rotation, dimensions, position; if (spaceMode == SPACE_LOCAL) { - rotation = properties.rotation; + rotation = SelectionManager.localRotation; dimensions = SelectionManager.localDimensions; position = SelectionManager.localPosition; } else { @@ -1097,6 +1096,44 @@ SelectionDisplay = (function () { entitySelected = false; }; + function applyEntityProperties(data) { + for (var i = 0; i < data.length; i++) { + var entityID = data[i].entityID; + var properties = data[i].properties; + Entities.editEntity(entityID, properties); + } + selectionManager._update(); + }; + + // For currently selected entities, push a command to the UndoStack that uses the current entity properties for the + // redo command, and the saved properties for the undo command. + function pushCommandForSelections() { + var undoData = []; + var redoData = []; + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID.id]; + var currentProperties = Entities.getEntityProperties(entityID); + undoData.push({ + entityID: entityID, + properties: { + position: initialProperties.position, + rotation: initialProperties.rotation, + dimensions: initialProperties.dimensions, + }, + }); + redoData.push({ + entityID: entityID, + properties: { + position: currentProperties.position, + rotation: currentProperties.rotation, + dimensions: currentProperties.dimensions, + }, + }); + } + UndoStack.pushCommand(applyEntityProperties, undoData, applyEntityProperties, redoData); + } + var lastXZPick = null; var translateXZTool = { mode: 'TRANSLATE_XZ', @@ -1116,6 +1153,8 @@ SelectionDisplay = (function () { var initialProperties = SelectionManager.savedProperties[entityID.id]; Entities.editEntity(entityID, initialProperties); } + } else { + pushCommandForSelections(); } }, onMove: function(event) { @@ -1174,6 +1213,8 @@ SelectionDisplay = (function () { var initialProperties = SelectionManager.savedProperties[entityID.id]; Entities.editEntity(entityID, initialProperties); } + } else { + pushCommandForSelections(); } }, onMove: function(event) { @@ -1336,6 +1377,8 @@ SelectionDisplay = (function () { var initialProperties = SelectionManager.savedProperties[entityID.id]; Entities.editEntity(entityID, initialProperties); } + } else { + pushCommandForSelections(); } }; @@ -1498,6 +1541,8 @@ SelectionDisplay = (function () { var initialProperties = SelectionManager.savedProperties[entityID.id]; Entities.editEntity(entityID, initialProperties); } + } else { + pushCommandForSelections(); } }, onMove: function(event) { @@ -1604,6 +1649,8 @@ SelectionDisplay = (function () { var initialProperties = SelectionManager.savedProperties[entityID.id]; Entities.editEntity(entityID, initialProperties); } + } else { + pushCommandForSelections(); } }, onMove: function(event) { @@ -1708,6 +1755,8 @@ SelectionDisplay = (function () { var initialProperties = SelectionManager.savedProperties[entityID.id]; Entities.editEntity(entityID, initialProperties); } + } else { + pushCommandForSelections(); } }, onMove: function(event) { diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index ae0d018b14..4d5abaf254 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -35,7 +35,7 @@ var entityPropertyDialogBox = EntityPropertyDialogBox; Script.include("libraries/entityCameraTool.js"); var entityCameraTool = new EntityCameraTool(); -selectionManager.setEventListener(selectionDisplay.updateHandles()); +selectionManager.setEventListener(selectionDisplay.updateHandles); var windowDimensions = Controller.getViewportDimensions(); var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 145222cd3c..6cd9d00364 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -172,6 +172,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _nodeBoundsDisplay(this), _previousScriptLocation(), _applicationOverlay(), + _undoStack(), + _undoStackScriptingInterface(&_undoStack), _runningScriptsWidget(NULL), _runningScriptsWidgetWasVisible(false), _trayIcon(new QSystemTrayIcon(_window)), @@ -3810,6 +3812,8 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser scriptEngine->registerGlobalObject("Joysticks", &JoystickScriptingInterface::getInstance()); qScriptRegisterMetaType(scriptEngine, joystickToScriptValue, joystickFromScriptValue); + scriptEngine->registerGlobalObject("UndoStack", &_undoStackScriptingInterface); + #ifdef HAVE_RTMIDI scriptEngine->registerGlobalObject("MIDI", &MIDIManager::getInstance()); #endif diff --git a/interface/src/Application.h b/interface/src/Application.h index 64c7032403..4779f9c810 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -91,6 +91,9 @@ #include "voxels/VoxelSystem.h" +#include "UndoStackScriptingInterface.h" + + class QAction; class QActionGroup; class QGLWidget; @@ -450,6 +453,7 @@ private: int _numChangedSettings; QUndoStack _undoStack; + UndoStackScriptingInterface _undoStackScriptingInterface; glm::vec3 _gravity; diff --git a/libraries/script-engine/src/UndoStackScriptingInterface.cpp b/libraries/script-engine/src/UndoStackScriptingInterface.cpp new file mode 100644 index 0000000000..42efe99c92 --- /dev/null +++ b/libraries/script-engine/src/UndoStackScriptingInterface.cpp @@ -0,0 +1,46 @@ +// +// UndoStackScriptingInterface.cpp +// libraries/script-engine/src +// +// Created by Ryan Huffman on 10/22/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include + +#include "UndoStackScriptingInterface.h" + +UndoStackScriptingInterface::UndoStackScriptingInterface(QUndoStack* undoStack) : _undoStack(undoStack) { +} + +void UndoStackScriptingInterface::pushCommand(QScriptValue undoFunction, QScriptValue undoData, + QScriptValue redoFunction, QScriptValue redoData) { + ScriptUndoCommand* undoCommand = new ScriptUndoCommand(undoFunction, undoData, redoFunction, redoData); + qDebug() << "Pushing command"; + _undoStack->push(undoCommand); +} + +ScriptUndoCommand::ScriptUndoCommand(QScriptValue undoFunction, QScriptValue undoData, + QScriptValue redoFunction, QScriptValue redoData) : + _undoFunction(undoFunction), + _undoData(undoData), + _redoFunction(redoFunction), + _redoData(redoData) { +} + +void ScriptUndoCommand::undo() { + QScriptValueList args; + args << _undoData; + _undoFunction.call(QScriptValue(), args); +} + +void ScriptUndoCommand::redo() { + QScriptValueList args; + args << _redoData; + _redoFunction.call(QScriptValue(), args); +} diff --git a/libraries/script-engine/src/UndoStackScriptingInterface.h b/libraries/script-engine/src/UndoStackScriptingInterface.h new file mode 100644 index 0000000000..9ab822ff80 --- /dev/null +++ b/libraries/script-engine/src/UndoStackScriptingInterface.h @@ -0,0 +1,47 @@ +// +// UndoStackScriptingInterface.h +// libraries/script-engine/src +// +// Created by Ryan Huffman on 10/22/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_UndoStackScriptingInterface_h +#define hifi_UndoStackScriptingInterface_h + +#include +#include +#include + +class UndoStackScriptingInterface : public QObject { + Q_OBJECT +public: + UndoStackScriptingInterface(QUndoStack* undoStack); + +public slots: + void pushCommand(QScriptValue undoFunction, QScriptValue undoData, QScriptValue redoFunction, QScriptValue redoData); + +private: + QUndoStack* _undoStack; +}; + +class ScriptUndoCommand : public QUndoCommand { +public: + ScriptUndoCommand(QScriptValue undoFunction, QScriptValue undoData, QScriptValue redoFunction, QScriptValue redoData); + + virtual void undo(); + virtual void redo(); + virtual bool mergeWith(const QUndoCommand* command) { return false; } + virtual int id() const { return -1; } + +private: + QScriptValue _undoFunction; + QScriptValue _undoData; + QScriptValue _redoFunction; + QScriptValue _redoData; +}; + +#endif // hifi_UndoStackScriptingInterface_h From 70f72f94042a4a655046896cfdfe7ccc974dfbf6 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 22 Oct 2014 15:09:43 -0700 Subject: [PATCH 06/11] can warp at any yaw angle --- examples/headMove.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 236130e23d..831e77a723 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -64,7 +64,6 @@ function activateWarp() { var TRIGGER_PULLBACK_DISTANCE = 0.04; var WATCH_AVATAR_DISTANCE = 1.5; -var MAX_WARP_YAW = 40.0; var MAX_PULLBACK_YAW = 5.0; var sound = new Sound("http://public.highfidelity.io/sounds/Footsteps/FootstepW2Right-12db.wav"); @@ -72,7 +71,7 @@ function playSound() { var options = new AudioInjectionOptions(); var position = MyAvatar.position; options.position = position; - options.volume = 0.5; + options.volume = 1.0; Audio.playSound(sound, options); } @@ -89,7 +88,7 @@ function updateWarp() { var deltaPitch = MyAvatar.getHeadFinalPitch() - headStartFinalPitch; deltaYaw = MyAvatar.getHeadFinalYaw() - headStartYaw; - willMove = (!watchAvatar && (Math.abs(deltaYaw) < MAX_WARP_YAW) && (keyDownTime > WARP_START_TIME)); + willMove = (!watchAvatar && (keyDownTime > WARP_START_TIME)); if (willMove) { //var distance = Math.pow((deltaPitch - WARP_PITCH_DEAD_ZONE) * WARP_SENSITIVITY, 2.0); From ac8d947cb1d38db06b92b00cfc29517b75381c23 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 22 Oct 2014 15:18:49 -0700 Subject: [PATCH 07/11] Update ScriptUndoCommand to run on ScriptEngine thread --- .../src/UndoStackScriptingInterface.cpp | 20 +++++++++++++++---- .../src/UndoStackScriptingInterface.h | 7 ++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/libraries/script-engine/src/UndoStackScriptingInterface.cpp b/libraries/script-engine/src/UndoStackScriptingInterface.cpp index 42efe99c92..ed0f4d563d 100644 --- a/libraries/script-engine/src/UndoStackScriptingInterface.cpp +++ b/libraries/script-engine/src/UndoStackScriptingInterface.cpp @@ -10,6 +10,7 @@ // #include +#include #include #include @@ -20,9 +21,11 @@ UndoStackScriptingInterface::UndoStackScriptingInterface(QUndoStack* undoStack) void UndoStackScriptingInterface::pushCommand(QScriptValue undoFunction, QScriptValue undoData, QScriptValue redoFunction, QScriptValue redoData) { - ScriptUndoCommand* undoCommand = new ScriptUndoCommand(undoFunction, undoData, redoFunction, redoData); - qDebug() << "Pushing command"; - _undoStack->push(undoCommand); + if (undoFunction.engine()) { + ScriptUndoCommand* undoCommand = new ScriptUndoCommand(undoFunction, undoData, redoFunction, redoData); + undoCommand->moveToThread(undoFunction.engine()->thread()); + _undoStack->push(undoCommand); + } } ScriptUndoCommand::ScriptUndoCommand(QScriptValue undoFunction, QScriptValue undoData, @@ -34,12 +37,21 @@ ScriptUndoCommand::ScriptUndoCommand(QScriptValue undoFunction, QScriptValue und } void ScriptUndoCommand::undo() { + QMetaObject::invokeMethod(this, "doUndo"); +} + +void ScriptUndoCommand::redo() { + QMetaObject::invokeMethod(this, "doRedo"); +} + +void ScriptUndoCommand::doUndo() { QScriptValueList args; args << _undoData; _undoFunction.call(QScriptValue(), args); } -void ScriptUndoCommand::redo() { + +void ScriptUndoCommand::doRedo() { QScriptValueList args; args << _redoData; _redoFunction.call(QScriptValue(), args); diff --git a/libraries/script-engine/src/UndoStackScriptingInterface.h b/libraries/script-engine/src/UndoStackScriptingInterface.h index 9ab822ff80..835e5dfff4 100644 --- a/libraries/script-engine/src/UndoStackScriptingInterface.h +++ b/libraries/script-engine/src/UndoStackScriptingInterface.h @@ -28,7 +28,8 @@ private: QUndoStack* _undoStack; }; -class ScriptUndoCommand : public QUndoCommand { +class ScriptUndoCommand : public QObject, public QUndoCommand { + Q_OBJECT public: ScriptUndoCommand(QScriptValue undoFunction, QScriptValue undoData, QScriptValue redoFunction, QScriptValue redoData); @@ -37,6 +38,10 @@ public: virtual bool mergeWith(const QUndoCommand* command) { return false; } virtual int id() const { return -1; } +public slots: + void doUndo(); + void doRedo(); + private: QScriptValue _undoFunction; QScriptValue _undoData; From 7b0f1477a1a3d5b29f1eeab56f43612175a65baf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 22 Oct 2014 15:28:04 -0700 Subject: [PATCH 08/11] expose AvatarList to Interface SE, add avatarWithDisplayName method --- interface/src/Application.cpp | 3 ++- libraries/avatars/src/AvatarData.h | 2 ++ libraries/avatars/src/AvatarHashMap.cpp | 10 +++++++--- libraries/avatars/src/AvatarHashMap.h | 2 ++ libraries/script-engine/src/ScriptEngine.cpp | 12 ++++++++++-- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 145222cd3c..99c23f526b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3766,8 +3766,9 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser // AvatarManager has some custom types AvatarManager::registerMetaTypes(scriptEngine); - // hook our avatar object into this script engine + // hook our avatar and avatar hash map object into this script engine scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features + scriptEngine->setAvatarHashMap(&_avatarManager, "AvatarList"); CameraScriptableObject* cameraScriptable = new CameraScriptableObject(&_myCamera, &_viewFrustum); scriptEngine->registerGlobalObject("Camera", cameraScriptable); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 1fd4052974..29682da286 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -381,6 +381,8 @@ private: AvatarData& operator= (const AvatarData&); }; +Q_DECLARE_METATYPE(AvatarData*) + class JointData { public: bool valid; diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index f996fc2bad..b74205c6b6 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -21,6 +21,7 @@ AvatarHashMap::AvatarHashMap() : connect(NodeList::getInstance(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); } + AvatarHash::iterator AvatarHashMap::erase(const AvatarHash::iterator& iterator) { qDebug() << "Removing Avatar with UUID" << iterator.key() << "from AvatarHashMap."; return _avatarHash.erase(iterator); @@ -53,7 +54,10 @@ void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const } bool AvatarHashMap::containsAvatarWithDisplayName(const QString& displayName) { - + return avatarWithDisplayName(displayName) == NULL ? false : true; +} + +AvatarData* AvatarHashMap::avatarWithDisplayName(const QString& displayName) { AvatarHash::iterator avatarIterator = _avatarHash.begin(); while (avatarIterator != _avatarHash.end()) { AvatarSharedPointer sharedAvatar = avatarIterator.value(); @@ -62,7 +66,7 @@ bool AvatarHashMap::containsAvatarWithDisplayName(const QString& displayName) { // check if this avatar should still be around if (!shouldKillAvatar(sharedAvatar)) { // we have a match, return true - return true; + return sharedAvatar.data(); } else { // we should remove this avatar, do that now erase(avatarIterator); @@ -75,7 +79,7 @@ bool AvatarHashMap::containsAvatarWithDisplayName(const QString& displayName) { } // return false, no match - return false; + return NULL; } AvatarSharedPointer AvatarHashMap::newSharedAvatar() { diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index d52c656bc1..03b0bf887c 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -21,6 +21,7 @@ #include "AvatarData.h" typedef QSharedPointer AvatarSharedPointer; +typedef QWeakPointer AvatarWeakPointer; typedef QHash AvatarHash; class AvatarHashMap : public QObject { @@ -34,6 +35,7 @@ public: public slots: void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer); bool containsAvatarWithDisplayName(const QString& displayName); + AvatarData* avatarWithDisplayName(const QString& displayname); private slots: void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index eb5dd07ffb..93da900055 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -63,7 +63,15 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){ return QScriptValue(); } -QScriptValue injectorToScriptValue(QScriptEngine *engine, AudioInjector* const &in) { +QScriptValue avatarDataToScriptValue(QScriptEngine* engine, AvatarData* const &in) { + return engine->newQObject(in); +} + +void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) { + out = qobject_cast(object.toQObject()); +} + +QScriptValue injectorToScriptValue(QScriptEngine* engine, AudioInjector* const &in) { return engine->newQObject(in); } @@ -272,7 +280,7 @@ void ScriptEngine::init() { qScriptRegisterMetaType(this, injectorToScriptValue, injectorFromScriptValue); qScriptRegisterMetaType(this, inputControllerToScriptValue, inputControllerFromScriptValue); - + qScriptRegisterMetaType(this, avatarDataToScriptValue, avatarDataFromScriptValue); qScriptRegisterMetaType(this, animationDetailsToScriptValue, animationDetailsFromScriptValue); registerGlobalObject("Script", this); From 38d50a76ebae9dc7a15aecdb1632ab62491eb92c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 22 Oct 2014 16:47:40 -0700 Subject: [PATCH 09/11] Add IsFacingAvatar getter and setter to Text3DOverlay --- interface/src/ui/overlays/Text3DOverlay.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index 855890e493..c49116ee0c 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -32,6 +32,7 @@ public: float getTopMargin() const { return _topMargin; } float getRightMargin() const { return _rightMargin; } float getBottomMargin() const { return _bottomMargin; } + bool getIsFacingAvatar() const { return _isFacingAvatar; } xColor getBackgroundColor(); // setters @@ -41,6 +42,7 @@ public: void setTopMargin(float margin) { _topMargin = margin; } void setRightMargin(float margin) { _rightMargin = margin; } void setBottomMargin(float margin) { _bottomMargin = margin; } + void setIsFacingAvatar(bool isFacingAvatar) { _isFacingAvatar = isFacingAvatar; } virtual void setProperties(const QScriptValue& properties); From 0e3495986de948e588f98792683ea72349448e04 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 22 Oct 2014 16:58:10 -0700 Subject: [PATCH 10/11] Add countdown to HMD calibration billboard --- interface/src/devices/OculusManager.cpp | 19 +++++++++++-------- interface/src/devices/OculusManager.h | 6 ++---- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 62894510c2..709080e354 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -66,8 +66,6 @@ glm::vec3 OculusManager::_calibrationPosition; glm::quat OculusManager::_calibrationOrientation; quint64 OculusManager::_calibrationStartTime; int OculusManager::_calibrationMessage = NULL; -QString OculusManager::CALIBRATION_BILLBOARD_URL = "http://hifi-public.s3.amazonaws.com/images/hold-to-calibrate.svg"; -float OculusManager::CALIBRATION_BILLBOARD_SCALE = 2.f; #endif @@ -191,7 +189,7 @@ void OculusManager::disconnect() { } #ifdef HAVE_LIBOVR -void OculusManager::positionCalibrationBillboard(BillboardOverlay* billboard) { +void OculusManager::positionCalibrationBillboard(Text3DOverlay* billboard) { glm::quat headOrientation = Application::getInstance()->getAvatar()->getHeadOrientation(); headOrientation.x = 0; headOrientation.z = 0; @@ -204,8 +202,9 @@ void OculusManager::positionCalibrationBillboard(BillboardOverlay* billboard) { #ifdef HAVE_LIBOVR void OculusManager::calibrate(glm::vec3 position, glm::quat orientation) { + static QString instructionMessage = "Hold still to calibrate"; static QString progressMessage; - static BillboardOverlay* billboard; + static Text3DOverlay* billboard; switch (_calibrationState) { @@ -235,9 +234,13 @@ void OculusManager::calibrate(glm::vec3 position, glm::quat orientation) { if (!_calibrationMessage) { qDebug() << "Hold still to calibrate HMD"; - billboard = new BillboardOverlay(); - billboard->setURL(CALIBRATION_BILLBOARD_URL); - billboard->setScale(CALIBRATION_BILLBOARD_SCALE); + billboard = new Text3DOverlay(); + billboard->setDimensions(glm::vec2(2.0f, 1.25f)); + billboard->setTopMargin(0.35f); + billboard->setLeftMargin(0.28f); + billboard->setText(instructionMessage); + billboard->setAlpha(0.5f); + billboard->setLineHeight(0.1f); billboard->setIsFacingAvatar(false); positionCalibrationBillboard(billboard); @@ -275,7 +278,7 @@ void OculusManager::calibrate(glm::vec3 position, glm::quat orientation) { } else { progressMessage += "."; } - //qDebug() << progressMessage; // Progress message ready for 3D text overlays. + billboard->setText(instructionMessage + "\n\n" + progressMessage); } } } else { diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index dfe4a212b6..20e43d572c 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -18,7 +18,7 @@ #endif #include "renderer/ProgramObject.h" -#include "ui/overlays/BillboardOverlay.h" +#include "ui/overlays/Text3DOverlay.h" const float DEFAULT_OCULUS_UI_ANGULAR_SIZE = 72.0f; @@ -111,7 +111,7 @@ private: WAITING_FOR_ZERO_HELD, CALIBRATED }; - static void positionCalibrationBillboard(BillboardOverlay* billboard); + static void positionCalibrationBillboard(Text3DOverlay* message); static float CALIBRATION_DELTA_MINIMUM_LENGTH; static float CALIBRATION_DELTA_MINIMUM_ANGLE; static float CALIBRATION_ZERO_MAXIMUM_LENGTH; @@ -123,8 +123,6 @@ private: static glm::quat _calibrationOrientation; static quint64 _calibrationStartTime; static int _calibrationMessage; - static QString CALIBRATION_BILLBOARD_URL; - static float CALIBRATION_BILLBOARD_SCALE; #endif From 8e67c5f53485b016d66dc5d47f7f06d69cc26267 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 22 Oct 2014 17:35:28 -0700 Subject: [PATCH 11/11] don't erase from the AvatarHashMap on the wrong thread --- libraries/avatars/src/AvatarHashMap.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index b74205c6b6..4f69eb2e3d 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -58,27 +58,21 @@ bool AvatarHashMap::containsAvatarWithDisplayName(const QString& displayName) { } AvatarData* AvatarHashMap::avatarWithDisplayName(const QString& displayName) { - AvatarHash::iterator avatarIterator = _avatarHash.begin(); - while (avatarIterator != _avatarHash.end()) { - AvatarSharedPointer sharedAvatar = avatarIterator.value(); - if (avatarIterator.value()->getDisplayName() == displayName) { + foreach(const AvatarSharedPointer& sharedAvatar, _avatarHash) { + if (sharedAvatar->getDisplayName() == displayName) { // this is a match // check if this avatar should still be around if (!shouldKillAvatar(sharedAvatar)) { - // we have a match, return true + // we have a match, return the AvatarData return sharedAvatar.data(); } else { - // we should remove this avatar, do that now - erase(avatarIterator); + // we should remove this avatar, but we might not be on a thread that is allowed + // so we just return NULL to the caller + return NULL; } - - break; - } else { - ++avatarIterator; } } - - // return false, no match + return NULL; }