mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 08:14:48 +02:00
Merge remote-tracking branch 'upstream/master' into vive-ui
Conflicts: interface/resources/qml/hifi/dialogs/RunningScripts.qml
This commit is contained in:
commit
ca6e86e767
28 changed files with 288 additions and 165 deletions
|
@ -9,6 +9,8 @@
|
|||
"to": "Actions.StepYaw",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "deadZone", "min": 0.15 },
|
||||
"constrainToInteger",
|
||||
{ "type": "pulse", "interval": 0.5 },
|
||||
{ "type": "scale", "scale": 22.5 }
|
||||
]
|
||||
|
|
|
@ -23,9 +23,9 @@ Window {
|
|||
title: "Running Scripts"
|
||||
resizable: true
|
||||
destroyOnHidden: true
|
||||
implicitWidth: 400
|
||||
implicitWidth: 424
|
||||
implicitHeight: isHMD ? 695 : 728
|
||||
minSize: Qt.vector2d(200, 300)
|
||||
minSize: Qt.vector2d(424, 300)
|
||||
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
|
@ -86,6 +86,11 @@ Window {
|
|||
scripts.reloadAllScripts();
|
||||
}
|
||||
|
||||
function loadDefaults() {
|
||||
console.log("Load default scripts");
|
||||
scripts.loadOneScript(scripts.defaultScriptsPath + "/defaultScripts.js");
|
||||
}
|
||||
|
||||
function stopAll() {
|
||||
console.log("Stop all scripts");
|
||||
scripts.stopAllScripts();
|
||||
|
@ -104,13 +109,13 @@ Window {
|
|||
spacing: hifi.dimensions.contentSpacing.x
|
||||
|
||||
HifiControls.Button {
|
||||
text: "Reload all"
|
||||
text: "Reload All"
|
||||
color: hifi.buttons.black
|
||||
onClicked: reloadAll()
|
||||
}
|
||||
|
||||
HifiControls.Button {
|
||||
text: "Stop all"
|
||||
text: "Remove All"
|
||||
color: hifi.buttons.red
|
||||
onClicked: stopAll()
|
||||
}
|
||||
|
@ -218,7 +223,6 @@ Window {
|
|||
|
||||
Row {
|
||||
spacing: hifi.dimensions.contentSpacing.x
|
||||
anchors.right: parent.right
|
||||
|
||||
HifiControls.Button {
|
||||
text: "from URL"
|
||||
|
@ -256,6 +260,12 @@ Window {
|
|||
onTriggered: ApplicationInterface.loadDialog();
|
||||
}
|
||||
}
|
||||
|
||||
HifiControls.Button {
|
||||
text: "Load Defaults"
|
||||
color: hifi.buttons.black
|
||||
onClicked: loadDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
HifiControls.VerticalSpacer {}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <QtCore/QAbstractNativeEventFilter>
|
||||
#include <QtCore/QCommandLineParser>
|
||||
#include <QtCore/QMimeData>
|
||||
#include <QtCore/QThreadPool>
|
||||
|
||||
|
@ -197,7 +198,6 @@ static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check f
|
|||
|
||||
static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||
|
||||
static const QString INPUT_DEVICE_MENU_PREFIX = "Device: ";
|
||||
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
|
||||
|
||||
const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensions {
|
||||
|
@ -999,7 +999,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
RenderableWebEntityItem* webEntity = dynamic_cast<RenderableWebEntityItem*>(entity.get());
|
||||
if (webEntity) {
|
||||
webEntity->setProxyWindow(_window->windowHandle());
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||
}
|
||||
_keyboardFocusedItem = entityItemID;
|
||||
|
@ -1152,9 +1152,7 @@ void Application::aboutToQuit() {
|
|||
emit beforeAboutToQuit();
|
||||
|
||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||
if (action->isChecked()) {
|
||||
if (inputPlugin->isActive()) {
|
||||
inputPlugin->deactivate();
|
||||
}
|
||||
}
|
||||
|
@ -1476,7 +1474,6 @@ void Application::initializeUi() {
|
|||
}
|
||||
}
|
||||
_window->setMenuBar(new Menu());
|
||||
updateInputModes();
|
||||
|
||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||
connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, [=] {
|
||||
|
@ -2024,7 +2021,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
|
||||
if (hasFocus()) {
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->keyPressEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2359,7 +2356,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2391,9 +2388,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
void Application::focusOutEvent(QFocusEvent* event) {
|
||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||
foreach(auto inputPlugin, inputPlugins) {
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||
if (action && action->isChecked()) {
|
||||
if (inputPlugin->isActive()) {
|
||||
inputPlugin->pluginFocusOutEvent();
|
||||
}
|
||||
}
|
||||
|
@ -2478,7 +2473,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2515,7 +2510,7 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
|
||||
|
||||
if (hasFocus()) {
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->mousePressEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2560,7 +2555,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
if (hasFocus()) {
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2587,7 +2582,7 @@ void Application::touchUpdateEvent(QTouchEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->touchUpdateEvent(event);
|
||||
}
|
||||
}
|
||||
|
@ -2605,7 +2600,7 @@ void Application::touchBeginEvent(QTouchEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->touchBeginEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2622,7 +2617,7 @@ void Application::touchEndEvent(QTouchEvent* event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->touchEndEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2638,7 +2633,7 @@ void Application::wheelEvent(QWheelEvent* event) const {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->wheelEvent(event);
|
||||
}
|
||||
}
|
||||
|
@ -2771,9 +2766,7 @@ void Application::idle(float nsecsElapsed) {
|
|||
getActiveDisplayPlugin()->idle();
|
||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||
foreach(auto inputPlugin, inputPlugins) {
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||
if (action && action->isChecked()) {
|
||||
if (inputPlugin->isActive()) {
|
||||
inputPlugin->idle();
|
||||
}
|
||||
}
|
||||
|
@ -2957,6 +2950,27 @@ void Application::loadSettings() {
|
|||
//DependencyManager::get<LODManager>()->setAutomaticLODAdjust(false);
|
||||
|
||||
Menu::getInstance()->loadSettings();
|
||||
|
||||
// If there is a preferred plugin, we probably messed it up with the menu settings, so fix it.
|
||||
auto pluginManager = PluginManager::getInstance();
|
||||
auto plugins = pluginManager->getPreferredDisplayPlugins();
|
||||
for (auto plugin : plugins) {
|
||||
auto menu = Menu::getInstance();
|
||||
if (auto action = menu->getActionForOption(plugin->getName())) {
|
||||
action->setChecked(true);
|
||||
action->trigger();
|
||||
// Find and activated highest priority plugin, bail for the rest
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto inputs = pluginManager->getInputPlugins();
|
||||
for (auto plugin : inputs) {
|
||||
if (!plugin->isActive()) {
|
||||
plugin->activate();
|
||||
}
|
||||
}
|
||||
|
||||
getMyAvatar()->loadData();
|
||||
|
||||
_settingsLoaded = true;
|
||||
|
@ -4937,7 +4951,34 @@ void Application::postLambdaEvent(std::function<void()> f) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::initPlugins() {
|
||||
void Application::initPlugins(const QStringList& arguments) {
|
||||
QCommandLineOption display("display", "Preferred displays", "displays");
|
||||
QCommandLineOption disableDisplays("disable-displays", "Displays to disable", "displays");
|
||||
QCommandLineOption disableInputs("disable-inputs", "Inputs to disable", "inputs");
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addOption(display);
|
||||
parser.addOption(disableDisplays);
|
||||
parser.addOption(disableInputs);
|
||||
parser.parse(arguments);
|
||||
|
||||
if (parser.isSet(display)) {
|
||||
auto preferredDisplays = parser.value(display).split(',', QString::SkipEmptyParts);
|
||||
qInfo() << "Setting prefered display plugins:" << preferredDisplays;
|
||||
PluginManager::getInstance()->setPreferredDisplayPlugins(preferredDisplays);
|
||||
}
|
||||
|
||||
if (parser.isSet(disableDisplays)) {
|
||||
auto disabledDisplays = parser.value(disableDisplays).split(',', QString::SkipEmptyParts);
|
||||
qInfo() << "Disabling following display plugins:" << disabledDisplays;
|
||||
PluginManager::getInstance()->disableDisplays(disabledDisplays);
|
||||
}
|
||||
|
||||
if (parser.isSet(disableInputs)) {
|
||||
auto disabledInputs = parser.value(disableInputs).split(',', QString::SkipEmptyParts);
|
||||
qInfo() << "Disabling following input plugins:" << disabledInputs;
|
||||
PluginManager::getInstance()->disableInputs(disabledInputs);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::shutdownPlugins() {
|
||||
|
@ -5207,81 +5248,6 @@ void Application::updateDisplayMode() {
|
|||
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
||||
}
|
||||
|
||||
static void addInputPluginToMenu(InputPluginPointer inputPlugin) {
|
||||
auto menu = Menu::getInstance();
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
Q_ASSERT(!menu->menuItemExists(MenuOption::InputMenu, name));
|
||||
|
||||
static QActionGroup* inputPluginGroup = nullptr;
|
||||
if (!inputPluginGroup) {
|
||||
inputPluginGroup = new QActionGroup(menu);
|
||||
inputPluginGroup->setExclusive(false);
|
||||
}
|
||||
|
||||
auto parent = menu->getMenu(MenuOption::InputMenu);
|
||||
auto action = menu->addCheckableActionToQMenuAndActionHash(parent,
|
||||
name, 0, true, qApp,
|
||||
SLOT(updateInputModes()));
|
||||
|
||||
inputPluginGroup->addAction(action);
|
||||
Q_ASSERT(menu->menuItemExists(MenuOption::InputMenu, name));
|
||||
}
|
||||
|
||||
|
||||
void Application::updateInputModes() {
|
||||
auto menu = Menu::getInstance();
|
||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
foreach(auto inputPlugin, inputPlugins) {
|
||||
addInputPluginToMenu(inputPlugin);
|
||||
}
|
||||
});
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
||||
InputPluginList newInputPlugins;
|
||||
InputPluginList removedInputPlugins;
|
||||
foreach(auto inputPlugin, inputPlugins) {
|
||||
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
|
||||
auto it = std::find(std::begin(_activeInputPlugins), std::end(_activeInputPlugins), inputPlugin);
|
||||
if (action->isChecked() && it == std::end(_activeInputPlugins)) {
|
||||
_activeInputPlugins.push_back(inputPlugin);
|
||||
newInputPlugins.push_back(inputPlugin);
|
||||
} else if (!action->isChecked() && it != std::end(_activeInputPlugins)) {
|
||||
_activeInputPlugins.erase(it);
|
||||
removedInputPlugins.push_back(inputPlugin);
|
||||
}
|
||||
}
|
||||
|
||||
// A plugin was checked
|
||||
if (newInputPlugins.size() > 0) {
|
||||
foreach(auto newInputPlugin, newInputPlugins) {
|
||||
newInputPlugin->activate();
|
||||
//newInputPlugin->installEventFilter(qApp);
|
||||
//newInputPlugin->installEventFilter(offscreenUi.data());
|
||||
}
|
||||
}
|
||||
if (removedInputPlugins.size() > 0) { // A plugin was unchecked
|
||||
foreach(auto removedInputPlugin, removedInputPlugins) {
|
||||
removedInputPlugin->deactivate();
|
||||
//removedInputPlugin->removeEventFilter(qApp);
|
||||
//removedInputPlugin->removeEventFilter(offscreenUi.data());
|
||||
}
|
||||
}
|
||||
|
||||
//if (newInputPlugins.size() > 0 || removedInputPlugins.size() > 0) {
|
||||
// if (!_currentInputPluginActions.isEmpty()) {
|
||||
// auto menu = Menu::getInstance();
|
||||
// foreach(auto itemInfo, _currentInputPluginActions) {
|
||||
// menu->removeMenuItem(itemInfo.first, itemInfo.second);
|
||||
// }
|
||||
// _currentInputPluginActions.clear();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
mat4 Application::getEyeProjection(int eye) const {
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
if (isHMDMode()) {
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
};
|
||||
|
||||
// FIXME? Empty methods, do we still need them?
|
||||
static void initPlugins();
|
||||
static void initPlugins(const QStringList& arguments);
|
||||
static void shutdownPlugins();
|
||||
|
||||
Application(int& argc, char** argv, QElapsedTimer& startup_time);
|
||||
|
@ -327,7 +327,6 @@ private slots:
|
|||
void nodeKilled(SharedNodePointer node);
|
||||
static void packetSent(quint64 length);
|
||||
void updateDisplayMode();
|
||||
void updateInputModes();
|
||||
void domainConnectionRefused(const QString& reasonMessage, int reason);
|
||||
|
||||
private:
|
||||
|
|
|
@ -403,12 +403,6 @@ Menu::Menu() {
|
|||
// Developer > Avatar >>>
|
||||
MenuWrapper* avatarDebugMenu = developerMenu->addMenu("Avatar");
|
||||
|
||||
// Settings > Input Devices
|
||||
MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu, "Advanced");
|
||||
QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu);
|
||||
inputModeGroup->setExclusive(false);
|
||||
|
||||
|
||||
// Developer > Avatar > Face Tracking
|
||||
MenuWrapper* faceTrackingMenu = avatarDebugMenu->addMenu("Face Tracking");
|
||||
{
|
||||
|
|
|
@ -113,7 +113,6 @@ namespace MenuOption {
|
|||
const QString Help = "Help...";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IndependentMode = "Independent Mode";
|
||||
const QString InputMenu = "Developer>Avatar>Input Devices";
|
||||
const QString ActionMotorControl = "Enable Default Motor Control";
|
||||
const QString LeapMotionOnHMD = "Leap Motion on HMD";
|
||||
const QString LoadScript = "Open and Run Script File...";
|
||||
|
|
|
@ -1214,7 +1214,10 @@ void MyAvatar::updateMotors() {
|
|||
if (_characterController.getState() == CharacterController::State::Hover) {
|
||||
motorRotation = getHead()->getCameraOrientation();
|
||||
} else {
|
||||
motorRotation = getOrientation();
|
||||
// non-hovering = walking: follow camera twist about vertical but not lift
|
||||
// so we decompose camera's rotation and store the twist part in motorRotation
|
||||
glm::quat liftRotation;
|
||||
swingTwistDecomposition(getHead()->getCameraOrientation(), _worldUpDirection, liftRotation, motorRotation);
|
||||
}
|
||||
const float DEFAULT_MOTOR_TIMESCALE = 0.2f;
|
||||
const float INVALID_MOTOR_TIMESCALE = 1.0e6f;
|
||||
|
|
|
@ -46,6 +46,12 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
bool instanceMightBeRunning = true;
|
||||
|
||||
QStringList arguments;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
arguments << argv[i];
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Try to create a shared memory block - if it can't be created, there is an instance of
|
||||
// interface already running. We only do this on Windows for now because of the potential
|
||||
|
@ -64,12 +70,6 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
// Try to connect - if we can't connect, interface has probably just gone down
|
||||
if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {
|
||||
|
||||
QStringList arguments;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
arguments << argv[i];
|
||||
}
|
||||
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption urlOption("url", "", "value");
|
||||
parser.addOption(urlOption);
|
||||
|
@ -135,7 +135,7 @@ int main(int argc, const char* argv[]) {
|
|||
// Oculus initialization MUST PRECEDE OpenGL context creation.
|
||||
// The nature of the Application constructor means this has to be either here,
|
||||
// or in the main window ctor, before GL startup.
|
||||
Application::initPlugins();
|
||||
Application::initPlugins(arguments);
|
||||
|
||||
int exitCode;
|
||||
{
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
ClipboardScriptingInterface::ClipboardScriptingInterface() {
|
||||
}
|
||||
|
||||
glm::vec3 ClipboardScriptingInterface::getContentsDimensions() {
|
||||
return qApp->getEntityClipboard()->getContentsDimensions();
|
||||
}
|
||||
|
||||
float ClipboardScriptingInterface::getClipboardContentsLargestDimension() {
|
||||
return qApp->getEntityClipboard()->getContentsLargestDimension();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ signals:
|
|||
void readyToImport();
|
||||
|
||||
public slots:
|
||||
glm::vec3 getContentsDimensions(); /// returns the overall dimensions of everything on the blipboard
|
||||
float getClipboardContentsLargestDimension(); /// returns the largest dimension of everything on the clipboard
|
||||
bool importEntities(const QString& filename);
|
||||
bool exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs);
|
||||
|
|
|
@ -632,13 +632,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
|||
#endif
|
||||
|
||||
int numBytesRead = sourceBuffer - startPosition;
|
||||
|
||||
if (numBytesRead != buffer.size()) {
|
||||
if (shouldLogError(now)) {
|
||||
qCWarning(avatars) << "AvatarData packet size mismatch: expected " << numBytesRead << " received " << buffer.size();
|
||||
}
|
||||
}
|
||||
|
||||
_averageBytesReceived.updateAverage(numBytesRead);
|
||||
return numBytesRead;
|
||||
}
|
||||
|
@ -1270,6 +1263,10 @@ static const QString JSON_AVATAR_DISPLAY_NAME = QStringLiteral("displayName");
|
|||
static const QString JSON_AVATAR_ATTACHEMENTS = QStringLiteral("attachments");
|
||||
static const QString JSON_AVATAR_ENTITIES = QStringLiteral("attachedEntities");
|
||||
static const QString JSON_AVATAR_SCALE = QStringLiteral("scale");
|
||||
static const QString JSON_AVATAR_VERSION = QStringLiteral("version");
|
||||
|
||||
static const int JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION = 0;
|
||||
static const int JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION = 1;
|
||||
|
||||
QJsonValue toJsonValue(const JointData& joint) {
|
||||
QJsonArray result;
|
||||
|
@ -1293,6 +1290,8 @@ JointData jointDataFromJsonValue(const QJsonValue& json) {
|
|||
QJsonObject AvatarData::toJson() const {
|
||||
QJsonObject root;
|
||||
|
||||
root[JSON_AVATAR_VERSION] = JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION;
|
||||
|
||||
if (!getSkeletonModelURL().isEmpty()) {
|
||||
root[JSON_AVATAR_BODY_MODEL] = getSkeletonModelURL().toString();
|
||||
}
|
||||
|
@ -1359,6 +1358,15 @@ QJsonObject AvatarData::toJson() const {
|
|||
}
|
||||
|
||||
void AvatarData::fromJson(const QJsonObject& json) {
|
||||
|
||||
int version;
|
||||
if (json.contains(JSON_AVATAR_VERSION)) {
|
||||
version = json[JSON_AVATAR_VERSION].toInt();
|
||||
} else {
|
||||
// initial data did not have a version field.
|
||||
version = JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION;
|
||||
}
|
||||
|
||||
// The head setOrientation likes to overwrite the avatar orientation,
|
||||
// so lets do the head first
|
||||
// Most head data is relative to the avatar, and needs no basis correction,
|
||||
|
@ -1424,20 +1432,28 @@ void AvatarData::fromJson(const QJsonObject& json) {
|
|||
// }
|
||||
// }
|
||||
|
||||
// Joint rotations are relative to the avatar, so they require no basis correction
|
||||
if (json.contains(JSON_AVATAR_JOINT_ARRAY)) {
|
||||
QVector<JointData> jointArray;
|
||||
QJsonArray jointArrayJson = json[JSON_AVATAR_JOINT_ARRAY].toArray();
|
||||
jointArray.reserve(jointArrayJson.size());
|
||||
int i = 0;
|
||||
for (const auto& jointJson : jointArrayJson) {
|
||||
auto joint = jointDataFromJsonValue(jointJson);
|
||||
jointArray.push_back(joint);
|
||||
setJointData(i, joint.rotation, joint.translation);
|
||||
_jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose
|
||||
i++;
|
||||
if (version == JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION) {
|
||||
// because we don't have the full joint hierarchy skeleton of the model,
|
||||
// we can't properly convert from relative rotations into absolute rotations.
|
||||
quint64 now = usecTimestampNow();
|
||||
if (shouldLogError(now)) {
|
||||
qCWarning(avatars) << "Version 0 avatar recordings not supported. using default rotations";
|
||||
}
|
||||
} else {
|
||||
QVector<JointData> jointArray;
|
||||
QJsonArray jointArrayJson = json[JSON_AVATAR_JOINT_ARRAY].toArray();
|
||||
jointArray.reserve(jointArrayJson.size());
|
||||
int i = 0;
|
||||
for (const auto& jointJson : jointArrayJson) {
|
||||
auto joint = jointDataFromJsonValue(jointJson);
|
||||
jointArray.push_back(joint);
|
||||
setJointData(i, joint.rotation, joint.translation);
|
||||
_jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose
|
||||
i++;
|
||||
}
|
||||
setRawJointData(jointArray);
|
||||
}
|
||||
setRawJointData(jointArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1121,6 +1121,27 @@ QStringList EntityScriptingInterface::getJointNames(const QUuid& entityID) {
|
|||
return result;
|
||||
}
|
||||
|
||||
QVector<QUuid> EntityScriptingInterface::getChildrenIDs(const QUuid& parentID) {
|
||||
QVector<QUuid> result;
|
||||
if (!_entityTree) {
|
||||
return result;
|
||||
}
|
||||
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(parentID);
|
||||
if (!entity) {
|
||||
qDebug() << "EntityScriptingInterface::getChildrenIDs - no entity with ID" << parentID;
|
||||
return result;
|
||||
}
|
||||
|
||||
_entityTree->withReadLock([&] {
|
||||
entity->forEachChild([&](SpatiallyNestablePointer child) {
|
||||
result.push_back(child->getID());
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QVector<QUuid> EntityScriptingInterface::getChildrenIDsOfJoint(const QUuid& parentID, int jointIndex) {
|
||||
QVector<QUuid> result;
|
||||
if (!_entityTree) {
|
||||
|
|
|
@ -171,6 +171,7 @@ public slots:
|
|||
|
||||
Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name);
|
||||
Q_INVOKABLE QStringList getJointNames(const QUuid& entityID);
|
||||
Q_INVOKABLE QVector<QUuid> getChildrenIDs(const QUuid& parentID);
|
||||
Q_INVOKABLE QVector<QUuid> getChildrenIDsOfJoint(const QUuid& parentID, int jointIndex);
|
||||
|
||||
signals:
|
||||
|
|
|
@ -1284,6 +1284,7 @@ class ContentsDimensionOperator : public RecurseOctreeOperator {
|
|||
public:
|
||||
virtual bool preRecursion(OctreeElementPointer element);
|
||||
virtual bool postRecursion(OctreeElementPointer element) { return true; }
|
||||
glm::vec3 getDimensions() const { return _contentExtents.size(); }
|
||||
float getLargestDimension() const { return _contentExtents.largestDimension(); }
|
||||
private:
|
||||
Extents _contentExtents;
|
||||
|
@ -1295,6 +1296,12 @@ bool ContentsDimensionOperator::preRecursion(OctreeElementPointer element) {
|
|||
return true;
|
||||
}
|
||||
|
||||
glm::vec3 EntityTree::getContentsDimensions() {
|
||||
ContentsDimensionOperator theOperator;
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
return theOperator.getDimensions();
|
||||
}
|
||||
|
||||
float EntityTree::getContentsLargestDimension() {
|
||||
ContentsDimensionOperator theOperator;
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
|
|
|
@ -207,6 +207,7 @@ public:
|
|||
bool skipThoseWithBadParents) override;
|
||||
virtual bool readFromMap(QVariantMap& entityDescription) override;
|
||||
|
||||
glm::vec3 getContentsDimensions();
|
||||
float getContentsLargestDimension();
|
||||
|
||||
virtual void resetEditStats() override {
|
||||
|
|
|
@ -55,7 +55,7 @@ void EntityTreeElement::debugExtraEncodeData(EncodeBitstreamParams& params) cons
|
|||
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
qCDebug(entities) << " encode data:" << entityTreeElementExtraEncodeData;
|
||||
} else {
|
||||
qCDebug(entities) << " encode data: MISSING!!";
|
||||
|
@ -97,7 +97,7 @@ bool EntityTreeElement::shouldIncludeChildData(int childIndex, EncodeBitstreamPa
|
|||
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
bool childCompleted = entityTreeElementExtraEncodeData->childCompleted[childIndex];
|
||||
|
||||
|
@ -126,7 +126,7 @@ bool EntityTreeElement::alreadyFullyEncoded(EncodeBitstreamParams& params) const
|
|||
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
// If we know that ALL subtrees below us have already been recursed, then we don't
|
||||
// need to recurse this child.
|
||||
|
@ -140,7 +140,7 @@ void EntityTreeElement::updateEncodedData(int childIndex, AppendState childAppen
|
|||
assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
if (childAppendState == OctreeElement::COMPLETED) {
|
||||
entityTreeElementExtraEncodeData->childCompleted[childIndex] = true;
|
||||
|
@ -165,7 +165,7 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params) con
|
|||
assert(extraEncodeData->contains(this));
|
||||
|
||||
EntityTreeElementExtraEncodeData* thisExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
// Note: this will be called when OUR element has finished running through encodeTreeBitstreamRecursion()
|
||||
// which means, it's possible that our parent element hasn't finished encoding OUR data... so
|
||||
|
@ -241,7 +241,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
bool hadElementExtraData = false;
|
||||
if (extraEncodeData && extraEncodeData->contains(this)) {
|
||||
entityTreeElementExtraEncodeData =
|
||||
static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
hadElementExtraData = true;
|
||||
} else {
|
||||
// if there wasn't one already, then create one
|
||||
|
@ -268,7 +268,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
|
||||
//assert(extraEncodeData);
|
||||
//assert(extraEncodeData->contains(this));
|
||||
//entityTreeElementExtraEncodeData = static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
//entityTreeElementExtraEncodeData = static_cast<EntityTreeElementExtraEncodeData*>((*extraEncodeData)[this]);
|
||||
|
||||
LevelDetails elementLevel = packetData->startLevel();
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ InputPluginList getInputPlugins() {
|
|||
for (int i = 0; PLUGIN_POOL[i]; ++i) {
|
||||
InputPlugin* plugin = PLUGIN_POOL[i];
|
||||
if (plugin->isSupported()) {
|
||||
plugin->init();
|
||||
result.push_back(InputPluginPointer(plugin));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,50 @@ PluginManager* PluginManager::getInstance() {
|
|||
return &_manager;
|
||||
}
|
||||
|
||||
QString getPluginNameFromMetaData(QJsonObject object) {
|
||||
static const char* METADATA_KEY = "MetaData";
|
||||
static const char* NAME_KEY = "name";
|
||||
|
||||
if (!object.contains(METADATA_KEY) || !object[METADATA_KEY].isObject()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
auto metaDataObject = object[METADATA_KEY].toObject();
|
||||
|
||||
if (!metaDataObject.contains(NAME_KEY) || !metaDataObject[NAME_KEY].isString()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return metaDataObject[NAME_KEY].toString();
|
||||
}
|
||||
|
||||
QString getPluginIIDFromMetaData(QJsonObject object) {
|
||||
static const char* IID_KEY = "IID";
|
||||
|
||||
if (!object.contains(IID_KEY) || !object[IID_KEY].isString()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return object[IID_KEY].toString();
|
||||
}
|
||||
|
||||
QStringList preferredDisplayPlugins;
|
||||
QStringList disabledDisplays;
|
||||
QStringList disabledInputs;
|
||||
|
||||
bool isDisabled(QJsonObject metaData) {
|
||||
auto name = getPluginNameFromMetaData(metaData);
|
||||
auto iid = getPluginIIDFromMetaData(metaData);
|
||||
|
||||
if (iid == DisplayProvider_iid) {
|
||||
return disabledDisplays.contains(name);
|
||||
} else if (iid == InputProvider_iid) {
|
||||
return disabledInputs.contains(name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
using Loader = QSharedPointer<QPluginLoader>;
|
||||
using LoaderList = QList<Loader>;
|
||||
|
||||
|
@ -43,11 +87,21 @@ const LoaderList& getLoadedPlugins() {
|
|||
qDebug() << "Loading runtime plugins from " << pluginPath;
|
||||
auto candidates = pluginDir.entryList();
|
||||
for (auto plugin : candidates) {
|
||||
qDebug() << "Attempting plugins " << plugin;
|
||||
qDebug() << "Attempting plugin" << qPrintable(plugin);
|
||||
QSharedPointer<QPluginLoader> loader(new QPluginLoader(pluginPath + plugin));
|
||||
|
||||
if (isDisabled(loader->metaData())) {
|
||||
qWarning() << "Plugin" << qPrintable(plugin) << "is disabled";
|
||||
// Skip this one, it's disabled
|
||||
continue;
|
||||
}
|
||||
|
||||
if (loader->load()) {
|
||||
qDebug() << "Plugins " << plugin << " success";
|
||||
qDebug() << "Plugin" << qPrintable(plugin) << "loaded successfully";
|
||||
loadedPlugins.push_back(loader);
|
||||
} else {
|
||||
qDebug() << "Plugin" << qPrintable(plugin) << "failed to load:";
|
||||
qDebug() << " " << qPrintable(loader->errorString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +164,9 @@ const InputPluginList& PluginManager::getInputPlugins() {
|
|||
InputProvider* inputProvider = qobject_cast<InputProvider*>(loader->instance());
|
||||
if (inputProvider) {
|
||||
for (auto inputPlugin : inputProvider->getInputPlugins()) {
|
||||
inputPlugins.push_back(inputPlugin);
|
||||
if (inputPlugin->isSupported()) {
|
||||
inputPlugins.push_back(inputPlugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +180,40 @@ const InputPluginList& PluginManager::getInputPlugins() {
|
|||
return inputPlugins;
|
||||
}
|
||||
|
||||
void PluginManager::setPreferredDisplayPlugins(const QStringList& displays) {
|
||||
preferredDisplayPlugins = displays;
|
||||
}
|
||||
|
||||
DisplayPluginList PluginManager::getPreferredDisplayPlugins() {
|
||||
static DisplayPluginList displayPlugins;
|
||||
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
// Grab the built in plugins
|
||||
auto plugins = getDisplayPlugins();
|
||||
|
||||
for (auto pluginName : preferredDisplayPlugins) {
|
||||
auto it = std::find_if(plugins.begin(), plugins.end(), [&](DisplayPluginPointer plugin) {
|
||||
return plugin->getName() == pluginName;
|
||||
});
|
||||
if (it != plugins.end()) {
|
||||
displayPlugins.push_back(*it);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return displayPlugins;
|
||||
}
|
||||
|
||||
|
||||
void PluginManager::disableDisplays(const QStringList& displays) {
|
||||
disabledDisplays << displays;
|
||||
}
|
||||
|
||||
void PluginManager::disableInputs(const QStringList& inputs) {
|
||||
disabledInputs << inputs;
|
||||
}
|
||||
|
||||
void PluginManager::saveSettings() {
|
||||
saveInputPluginSettings(getInputPlugins());
|
||||
}
|
||||
|
|
|
@ -13,11 +13,17 @@
|
|||
|
||||
class PluginManager : public QObject {
|
||||
public:
|
||||
static PluginManager* getInstance();
|
||||
PluginManager();
|
||||
static PluginManager* getInstance();
|
||||
PluginManager();
|
||||
|
||||
const DisplayPluginList& getDisplayPlugins();
|
||||
void disableDisplayPlugin(const QString& name);
|
||||
const InputPluginList& getInputPlugins();
|
||||
void saveSettings();
|
||||
const DisplayPluginList& getDisplayPlugins();
|
||||
const InputPluginList& getInputPlugins();
|
||||
|
||||
DisplayPluginList getPreferredDisplayPlugins();
|
||||
void setPreferredDisplayPlugins(const QStringList& displays);
|
||||
|
||||
void disableDisplayPlugin(const QString& name);
|
||||
void disableDisplays(const QStringList& displays);
|
||||
void disableInputs(const QStringList& inputs);
|
||||
void saveSettings();
|
||||
};
|
||||
|
|
|
@ -28,7 +28,9 @@ Settings::~Settings() {
|
|||
}
|
||||
|
||||
void Settings::remove(const QString& key) {
|
||||
_manager->remove(key);
|
||||
if (key == "" || _manager->contains(key)) {
|
||||
_manager->remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList Settings::childGroups() const {
|
||||
|
@ -72,7 +74,9 @@ void Settings::endGroup() {
|
|||
}
|
||||
|
||||
void Settings::setValue(const QString& name, const QVariant& value) {
|
||||
_manager->setValue(name, value);
|
||||
if (_manager->value(name) != value) {
|
||||
_manager->setValue(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant Settings::value(const QString& name, const QVariant& defaultValue) const {
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"Neuron"}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"SDL2"}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"Sixense"}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"Spacemouse"}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"Oculus Rift"}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
using namespace oglplus;
|
||||
|
||||
const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift (0.5) (Legacy)");
|
||||
const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift");
|
||||
|
||||
OculusLegacyDisplayPlugin::OculusLegacyDisplayPlugin() {
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"Oculus Rift"}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{}
|
||||
{"name":"OpenVR (Vive)"}
|
||||
|
|
Loading…
Reference in a new issue