Merge branch 'master' of github.com:highfidelity/hifi into script-getmeshes-for-models

This commit is contained in:
Seth Alves 2017-07-24 19:23:30 -07:00
commit d1037a49ae
10 changed files with 120 additions and 97 deletions

View file

@ -81,7 +81,11 @@
{ "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] },
"when": "Keyboard.RightMouseButton",
"to": "Actions.Yaw"
"to": "Actions.Yaw",
"filters":
[
{ "type": "scale", "scale": 0.6 }
]
},
{ "from": "Keyboard.W", "to": "Actions.LONGITUDINAL_FORWARD" },
@ -102,8 +106,19 @@
{ "from": "Keyboard.PgDown", "to": "Actions.VERTICAL_DOWN" },
{ "from": "Keyboard.PgUp", "to": "Actions.VERTICAL_UP" },
{ "from": "Keyboard.MouseMoveUp", "when": "Keyboard.RightMouseButton", "to": "Actions.PITCH_UP" },
{ "from": "Keyboard.MouseMoveDown", "when": "Keyboard.RightMouseButton", "to": "Actions.PITCH_DOWN" },
{ "from": "Keyboard.MouseMoveUp", "when": "Keyboard.RightMouseButton", "to": "Actions.PITCH_UP",
"filters":
[
{ "type": "scale", "scale": 0.6 }
]
},
{ "from": "Keyboard.MouseMoveDown", "when": "Keyboard.RightMouseButton", "to": "Actions.PITCH_DOWN",
"filters":
[
{ "type": "scale", "scale": 0.6 }
]
},
{ "from": "Keyboard.TouchpadDown", "to": "Actions.PITCH_DOWN" },
{ "from": "Keyboard.TouchpadUp", "to": "Actions.PITCH_UP" },

View file

@ -21,7 +21,7 @@ TabView {
enabled: true
property string originalUrl: ""
Rectangle {
Rectangle {
color: "#404040"
Text {
@ -180,7 +180,7 @@ TabView {
WebView {
id: entityListToolWebView
url: "../../../../../scripts/system/html/entityList.html"
url: Paths.defaultScripts + "/system/html/entityList.html"
anchors.fill: parent
enabled: true
}
@ -194,7 +194,7 @@ TabView {
WebView {
id: entityPropertiesWebView
url: "../../../../../scripts/system/html/entityProperties.html"
url: Paths.defaultScripts + "/system/html/entityProperties.html"
anchors.fill: parent
enabled: true
}
@ -208,7 +208,7 @@ TabView {
WebView {
id: gridControlsWebView
url: "../../../../../scripts/system/html/gridControls.html"
url: Paths.defaultScripts + "/system/html/gridControls.html"
anchors.fill: parent
enabled: true
}
@ -222,7 +222,7 @@ TabView {
WebView {
id: particleExplorerWebView
url: "../../../../../scripts/system/particle_explorer/particleExplorer.html"
url: Paths.defaultScripts + "/system/particle_explorer/particleExplorer.html"
anchors.fill: parent
enabled: true
}
@ -293,16 +293,16 @@ TabView {
break;
case 'list':
editTabView.currentIndex = 1;
break;
break;
case 'properties':
editTabView.currentIndex = 2;
break;
break;
case 'grid':
editTabView.currentIndex = 3;
break;
break;
case 'particle':
editTabView.currentIndex = 4;
break;
break;
default:
console.warn('Attempt to switch to invalid tab:', id);
}
@ -310,4 +310,4 @@ TabView {
console.warn('Attempt to switch tabs with invalid input:', JSON.stringify(id));
}
}
}
}

View file

@ -69,8 +69,8 @@ const float MAX_BOOST_SPEED = 0.5f * MAX_WALKING_SPEED; // action motor gets add
const float MIN_AVATAR_SPEED = 0.05f;
const float MIN_AVATAR_SPEED_SQUARED = MIN_AVATAR_SPEED * MIN_AVATAR_SPEED; // speed is set to zero below this
const float YAW_SPEED_DEFAULT = 120.0f; // degrees/sec
const float PITCH_SPEED_DEFAULT = 90.0f; // degrees/sec
const float YAW_SPEED_DEFAULT = 100.0f; // degrees/sec
const float PITCH_SPEED_DEFAULT = 75.0f; // degrees/sec
// TODO: normalize avatar speed for standard avatar size, then scale all motion logic
// to properly follow avatar size.

View file

@ -36,6 +36,21 @@ Setting::Handle<QString>& getSetting(bool contextIsHMD, QAudio::Mode mode) {
}
}
static QString getTargetDevice(bool hmd, QAudio::Mode mode) {
QString deviceName;
auto& setting = getSetting(hmd, mode);
if (setting.isSet()) {
deviceName = setting.get();
} else if (hmd) {
if (mode == QAudio::AudioInput) {
deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioInDevice();
} else { // if (_mode == QAudio::AudioOutput)
deviceName = qApp->getActiveDisplayPlugin()->getPreferredAudioOutDevice();
}
}
return deviceName;
}
QHash<int, QByteArray> AudioDeviceList::_roles {
{ Qt::DisplayRole, "display" },
{ Qt::CheckStateRole, "selected" },
@ -59,10 +74,15 @@ QVariant AudioDeviceList::data(const QModelIndex& index, int role) const {
}
}
void AudioDeviceList::resetDevice(bool contextIsHMD, const QString& device) {
void AudioDeviceList::resetDevice(bool contextIsHMD) {
auto client = DependencyManager::get<AudioClient>().data();
auto deviceName = getSetting(contextIsHMD, _mode).get();
QString deviceName = getTargetDevice(contextIsHMD, _mode);
// FIXME can't use blocking connections here, so we can't determine whether the switch succeeded or not
// We need to have the AudioClient emit signals on switch success / failure
QMetaObject::invokeMethod(client, "switchAudioDevice",
Q_ARG(QAudio::Mode, _mode), Q_ARG(QString, deviceName));
#if 0
bool switchResult = false;
QMetaObject::invokeMethod(client, "switchAudioDevice", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, switchResult),
@ -85,6 +105,7 @@ void AudioDeviceList::resetDevice(bool contextIsHMD, const QString& device) {
QMetaObject::invokeMethod(client, "switchAudioDevice", Q_ARG(QAudio::Mode, _mode));
}
}
#endif
}
void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device) {
@ -137,11 +158,8 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
}
void AudioDevices::onContextChanged(const QString& context) {
auto input = getSetting(_contextIsHMD, QAudio::AudioInput).get();
auto output = getSetting(_contextIsHMD, QAudio::AudioOutput).get();
_inputs.resetDevice(_contextIsHMD, input);
_outputs.resetDevice(_contextIsHMD, output);
_inputs.resetDevice(_contextIsHMD);
_outputs.resetDevice(_contextIsHMD);
}
void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, const QAudioDeviceInfo& previousDevice) {
@ -182,8 +200,16 @@ void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& d
void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device) {
if (mode == QAudio::AudioInput) {
if (_requestedInputDevice == device) {
onDeviceSelected(QAudio::AudioInput, device, _inputs._selectedDevice);
_requestedInputDevice = QAudioDeviceInfo();
}
_inputs.onDeviceChanged(device);
} else { // if (mode == QAudio::AudioOutput)
if (_requestedOutputDevice == device) {
onDeviceSelected(QAudio::AudioOutput, device, _outputs._selectedDevice);
_requestedOutputDevice = QAudioDeviceInfo();
}
_outputs.onDeviceChanged(device);
}
}
@ -201,28 +227,16 @@ void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceI
void AudioDevices::chooseInputDevice(const QAudioDeviceInfo& device) {
auto client = DependencyManager::get<AudioClient>();
bool success = false;
_requestedInputDevice = device;
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, success),
Q_ARG(QAudio::Mode, QAudio::AudioInput),
Q_ARG(const QAudioDeviceInfo&, device));
if (success) {
onDeviceSelected(QAudio::AudioInput, device, _inputs._selectedDevice);
}
}
void AudioDevices::chooseOutputDevice(const QAudioDeviceInfo& device) {
auto client = DependencyManager::get<AudioClient>();
bool success = false;
_requestedOutputDevice = device;
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, success),
Q_ARG(QAudio::Mode, QAudio::AudioOutput),
Q_ARG(const QAudioDeviceInfo&, device));
if (success) {
onDeviceSelected(QAudio::AudioOutput, device, _outputs._selectedDevice);
}
}

View file

@ -39,7 +39,7 @@ public:
QVariant data(const QModelIndex& index, int role) const override;
// reset device to the last selected device in this context, or the default
void resetDevice(bool contextIsHMD, const QString& device);
void resetDevice(bool contextIsHMD);
signals:
void deviceChanged(const QAudioDeviceInfo& device);
@ -87,8 +87,10 @@ private:
AudioDeviceList _inputs { QAudio::AudioInput };
AudioDeviceList _outputs { QAudio::AudioOutput };
QAudioDeviceInfo _requestedOutputDevice;
QAudioDeviceInfo _requestedInputDevice;
bool& _contextIsHMD;
const bool& _contextIsHMD;
};
};

View file

@ -24,13 +24,14 @@
#include "ScriptHighlighting.h"
const int NO_CURRENT_HISTORY_COMMAND = -1;
const int MAX_HISTORY_SIZE = 64;
const int MAX_HISTORY_SIZE = 256;
const QString HISTORY_FILENAME = "JSConsole.history.json";
const QString COMMAND_STYLE = "color: #266a9b;";
const QString RESULT_SUCCESS_STYLE = "color: #677373;";
const QString RESULT_INFO_STYLE = "color: #223bd1;";
const QString RESULT_WARNING_STYLE = "color: #d13b22;";
const QString RESULT_WARNING_STYLE = "color: #999922;";
const QString RESULT_ERROR_STYLE = "color: #d13b22;";
const QString GUTTER_PREVIOUS_COMMAND = "<span style=\"color: #57b8bb;\">&lt;</span>";
@ -38,14 +39,35 @@ const QString GUTTER_ERROR = "<span style=\"color: #d13b22;\">X</span>";
const QString JSConsole::_consoleFileName { "about:console" };
const QString JSON_KEY = "entries";
QList<QString> _readLines(const QString& filename) {
QFile file(filename);
file.open(QFile::ReadOnly);
auto json = QTextStream(&file).readAll().toUtf8();
auto root = QJsonDocument::fromJson(json).object();
// TODO: check root["version"]
return root[JSON_KEY].toVariant().toStringList();
}
void _writeLines(const QString& filename, const QList<QString>& lines) {
QFile file(filename);
file.open(QFile::WriteOnly);
auto root = QJsonObject();
root["version"] = 1.0;
root["last-modified"] = QDateTime::currentDateTime().toTimeSpec(Qt::OffsetFromUTC).toString(Qt::ISODate);
root[JSON_KEY] = QJsonArray::fromStringList(lines);
auto json = QJsonDocument(root).toJson();
QTextStream(&file) << json;
}
JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) :
QWidget(parent),
_ui(new Ui::Console),
_currentCommandInHistory(NO_CURRENT_HISTORY_COMMAND),
_commandHistory(),
_savedHistoryFilename(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + HISTORY_FILENAME),
_commandHistory(_readLines(_savedHistoryFilename)),
_ownScriptEngine(scriptEngine == NULL),
_scriptEngine(NULL) {
_ui->setupUi(this);
_ui->promptTextEdit->setLineWrapMode(QTextEdit::NoWrap);
_ui->promptTextEdit->setWordWrapMode(QTextOption::NoWrap);
@ -101,9 +123,12 @@ void JSConsole::setScriptEngine(ScriptEngine* scriptEngine) {
}
void JSConsole::executeCommand(const QString& command) {
_commandHistory.prepend(command);
if (_commandHistory.length() > MAX_HISTORY_SIZE) {
_commandHistory.removeLast();
if (_commandHistory.isEmpty() || _commandHistory.constFirst() != command) {
_commandHistory.prepend(command);
if (_commandHistory.length() > MAX_HISTORY_SIZE) {
_commandHistory.removeLast();
}
_writeLines(_savedHistoryFilename, _commandHistory);
}
_ui->promptTextEdit->setDisabled(true);
@ -182,7 +207,7 @@ bool JSConsole::eventFilter(QObject* sender, QEvent* event) {
// a new QTextBlock isn't created.
keyEvent->setModifiers(keyEvent->modifiers() & ~Qt::ShiftModifier);
} else {
QString command = _ui->promptTextEdit->toPlainText().trimmed();
QString command = _ui->promptTextEdit->toPlainText().replace("\r\n","\n").trimmed();
if (!command.isEmpty()) {
QTextCursor cursor = _ui->promptTextEdit->textCursor();

View file

@ -63,6 +63,7 @@ private:
QFutureWatcher<QScriptValue> _executeWatcher;
Ui::Console* _ui;
int _currentCommandInHistory;
QString _savedHistoryFilename;
QList<QString> _commandHistory;
// Keeps track if the script engine is created inside the JSConsole
bool _ownScriptEngine;

View file

@ -13,6 +13,8 @@
#define hifi_PathUtils_h
#include <QtCore/QObject>
#include <QtCore/QUrl>
#include "DependencyManager.h"
/**jsdoc
@ -24,6 +26,7 @@ class PathUtils : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
Q_PROPERTY(QString resources READ resourcesPath)
Q_PROPERTY(QUrl defaultScripts READ defaultScriptsLocation)
public:
static const QString& resourcesPath();

View file

@ -1074,7 +1074,7 @@ function loaded() {
elDimensionsZ.addEventListener('change', dimensionsChangeFunction);
elParentID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentID'));
elParentJointIndex.addEventListener('change', createEmitNumberPropertyUpdateFunction('parentJointIndex'));
elParentJointIndex.addEventListener('change', createEmitNumberPropertyUpdateFunction('parentJointIndex', 0));
var registrationChangeFunction = createEmitVec3PropertyUpdateFunction(
'registrationPoint', elRegistrationX, elRegistrationY, elRegistrationZ);

View file

@ -1560,7 +1560,6 @@ SelectionDisplay = (function() {
visible: rotationOverlaysVisible
});
// TODO: we have not implemented the rotating handle/controls yet... so for now, these handles are hidden
Overlays.editOverlay(yawHandle, {
visible: rotateHandlesVisible,
position: yawCorner,
@ -3615,24 +3614,21 @@ SelectionDisplay = (function() {
onMove: function(event) {
var pickRay = generalComputePickRay(event.x, event.y);
Overlays.editOverlay(selectionBox, {
ignoreRayIntersection: true,
visible: false
});
Overlays.editOverlay(baseOfEntityProjectionOverlay, {
ignoreRayIntersection: true,
visible: false
});
Overlays.editOverlay(rotateOverlayTarget, {
ignoreRayIntersection: false
});
var result = Overlays.findRayIntersection(pickRay);
var result = Overlays.findRayIntersection(pickRay, true, [rotateOverlayTarget]);
if (result.intersects) {
var center = yawCenter;
var zero = yawZero;
// TODO: these vectors are backwards to their names, doesn't matter for this use case (inverted vectors still give same angle)
var centerToZero = Vec3.subtract(center, zero);
var centerToIntersect = Vec3.subtract(center, result.intersection);
// TODO: orientedAngle wants normalized centerToZero and centerToIntersect
var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal);
var distanceFromCenter = Vec3.distance(center, result.intersection);
var snapToInner = distanceFromCenter < innerRadius;
@ -3785,17 +3781,12 @@ SelectionDisplay = (function() {
onMove: function(event) {
var pickRay = generalComputePickRay(event.x, event.y);
Overlays.editOverlay(selectionBox, {
ignoreRayIntersection: true,
visible: false
});
Overlays.editOverlay(baseOfEntityProjectionOverlay, {
ignoreRayIntersection: true,
visible: false
});
Overlays.editOverlay(rotateOverlayTarget, {
ignoreRayIntersection: false
});
var result = Overlays.findRayIntersection(pickRay);
var result = Overlays.findRayIntersection(pickRay, true, [rotateOverlayTarget]);
if (result.intersects) {
var properties = Entities.getEntityProperties(selectionManager.selections[0]);
@ -3947,17 +3938,12 @@ SelectionDisplay = (function() {
onMove: function(event) {
var pickRay = generalComputePickRay(event.x, event.y);
Overlays.editOverlay(selectionBox, {
ignoreRayIntersection: true,
visible: false
});
Overlays.editOverlay(baseOfEntityProjectionOverlay, {
ignoreRayIntersection: true,
visible: false
});
Overlays.editOverlay(rotateOverlayTarget, {
ignoreRayIntersection: false
});
var result = Overlays.findRayIntersection(pickRay);
var result = Overlays.findRayIntersection(pickRay, true, [rotateOverlayTarget]);
if (result.intersects) {
var properties = Entities.getEntityProperties(selectionManager.selections[0]);
@ -4074,21 +4060,8 @@ SelectionDisplay = (function() {
return false;
}
// before we do a ray test for grabbers, disable the ray intersection for our selection box
Overlays.editOverlay(selectionBox, {
ignoreRayIntersection: true
});
Overlays.editOverlay(yawHandle, {
ignoreRayIntersection: true
});
Overlays.editOverlay(pitchHandle, {
ignoreRayIntersection: true
});
Overlays.editOverlay(rollHandle, {
ignoreRayIntersection: true
});
result = Overlays.findRayIntersection(pickRay);
// ignore ray intersection for our selection box and yaw/pitch/roll
result = Overlays.findRayIntersection(pickRay, true, null, [ yawHandle, pitchHandle, rollHandle, selectionBox ] );
if (result.intersects) {
if (wantDebug) {
print("something intersects... ");
@ -4191,17 +4164,8 @@ SelectionDisplay = (function() {
}
// After testing our stretch handles, then check out rotate handles
Overlays.editOverlay(yawHandle, {
ignoreRayIntersection: false
});
Overlays.editOverlay(pitchHandle, {
ignoreRayIntersection: false
});
Overlays.editOverlay(rollHandle, {
ignoreRayIntersection: false
});
var result = Overlays.findRayIntersection(pickRay);
// Only intersect versus yaw/pitch/roll.
var result = Overlays.findRayIntersection(pickRay, true, [ yawHandle, pitchHandle, rollHandle ] );
var overlayOrientation;
var overlayCenter;
@ -4306,6 +4270,7 @@ SelectionDisplay = (function() {
});
// TODO: these three duplicate prior three, remove them.
Overlays.editOverlay(yawHandle, {
visible: false
});
@ -4402,10 +4367,8 @@ SelectionDisplay = (function() {
}
if (!somethingClicked) {
Overlays.editOverlay(selectionBox, {
ignoreRayIntersection: false
});
var result = Overlays.findRayIntersection(pickRay);
// Only intersect versus selectionBox.
var result = Overlays.findRayIntersection(pickRay, true, [selectionBox]);
if (result.intersects) {
switch (result.overlayID) {
case selectionBox: