mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 19:59:28 +02:00
Merge remote-tracking branch 'upstream/master' into bindless
This commit is contained in:
commit
14ea168ab3
9 changed files with 169 additions and 46 deletions
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <shared/QtHelpers.h>
|
#include <shared/QtHelpers.h>
|
||||||
#include <plugins/DisplayPlugin.h>
|
#include <plugins/DisplayPlugin.h>
|
||||||
|
@ -182,7 +183,6 @@ void AudioDeviceList::resetDevice(bool contextIsHMD) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD) {
|
void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD) {
|
||||||
auto oldDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
|
||||||
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
||||||
selectedDevice = device;
|
selectedDevice = device;
|
||||||
|
|
||||||
|
@ -200,32 +200,137 @@ void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD
|
||||||
emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0));
|
emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices, bool isHMD) {
|
// Function returns 'strings similarity' as a number. The lesser number - the more similar strings are. Absolutely equal strings should return 0.
|
||||||
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
// Optimized version kindly provided by Ken
|
||||||
|
int levenshteinDistance(const QString& s1, const QString& s2) {
|
||||||
|
const int m = s1.size();
|
||||||
|
const int n = s2.size();
|
||||||
|
|
||||||
const QString& savedDeviceName = isHMD ? _hmdSavedDeviceName : _desktopSavedDeviceName;
|
if (m == 0) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
if (n == 0) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cost = (int*)alloca((n + 1) * sizeof(int));
|
||||||
|
|
||||||
|
for (int j = 0; j <= n; j++) {
|
||||||
|
cost[j] = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
|
||||||
|
int prev = i;
|
||||||
|
cost[0] = i + 1;
|
||||||
|
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
|
||||||
|
int temp = cost[j + 1];
|
||||||
|
cost[j + 1] = (s1[i] == s2[j]) ? prev : std::min(cost[j], std::min(temp, prev)) + 1;
|
||||||
|
prev = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cost[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<scripting::AudioDevice> getSimilarDevice(const QString& deviceName, const QList<std::shared_ptr<scripting::AudioDevice>>& devices) {
|
||||||
|
|
||||||
|
int minDistance = INT_MAX;
|
||||||
|
int minDistanceIndex = 0;
|
||||||
|
|
||||||
|
for (auto i = 0; i < devices.length(); ++i) {
|
||||||
|
auto distance = levenshteinDistance(deviceName, devices[i]->info.deviceName());
|
||||||
|
if (distance < minDistance) {
|
||||||
|
minDistance = distance;
|
||||||
|
minDistanceIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices[minDistanceIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices) {
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
|
|
||||||
_devices.clear();
|
QList<std::shared_ptr<AudioDevice>> newDevices;
|
||||||
|
bool hmdIsSelected = false;
|
||||||
|
bool desktopIsSelected = false;
|
||||||
|
|
||||||
|
foreach(const QAudioDeviceInfo& deviceInfo, devices) {
|
||||||
|
for (bool isHMD : {false, true}) {
|
||||||
|
auto &backupSelectedDeviceName = isHMD ? _backupSelectedHMDDeviceName : _backupSelectedDesktopDeviceName;
|
||||||
|
if (deviceInfo.deviceName() == backupSelectedDeviceName) {
|
||||||
|
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
||||||
|
selectedDevice = deviceInfo;
|
||||||
|
backupSelectedDeviceName.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach(const QAudioDeviceInfo& deviceInfo, devices) {
|
foreach(const QAudioDeviceInfo& deviceInfo, devices) {
|
||||||
AudioDevice device;
|
AudioDevice device;
|
||||||
bool &isSelected = isHMD ? device.selectedHMD : device.selectedDesktop;
|
|
||||||
device.info = deviceInfo;
|
device.info = deviceInfo;
|
||||||
device.display = device.info.deviceName()
|
device.display = device.info.deviceName()
|
||||||
.replace("High Definition", "HD")
|
.replace("High Definition", "HD")
|
||||||
.remove("Device")
|
.remove("Device")
|
||||||
.replace(" )", ")");
|
.replace(" )", ")");
|
||||||
if (!selectedDevice.isNull()) {
|
|
||||||
isSelected = (device.info == selectedDevice);
|
for (bool isHMD : {false, true}) {
|
||||||
} else {
|
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
||||||
//no selected device for context. fallback to saved
|
bool &isSelected = isHMD ? device.selectedHMD : device.selectedDesktop;
|
||||||
isSelected = (device.info.deviceName() == savedDeviceName);
|
|
||||||
|
if (!selectedDevice.isNull()) {
|
||||||
|
isSelected = (device.info == selectedDevice);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//no selected device for context. fallback to saved
|
||||||
|
const QString& savedDeviceName = isHMD ? _hmdSavedDeviceName : _desktopSavedDeviceName;
|
||||||
|
isSelected = (device.info.deviceName() == savedDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSelected) {
|
||||||
|
if (isHMD) {
|
||||||
|
hmdIsSelected = isSelected;
|
||||||
|
} else {
|
||||||
|
desktopIsSelected = isSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if this device *is not* in old devices list - it means it was just re-plugged so needs to be selected explicitly
|
||||||
|
bool isNewDevice = true;
|
||||||
|
for (auto& oldDevice : _devices) {
|
||||||
|
if (oldDevice->info.deviceName() == device.info.deviceName()) {
|
||||||
|
isNewDevice = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNewDevice) {
|
||||||
|
emit selectedDevicePlugged(device.info, isHMD);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "adding audio device:" << device.display << device.selectedDesktop << device.selectedHMD << _mode;
|
qDebug() << "adding audio device:" << device.display << device.selectedDesktop << device.selectedHMD << _mode;
|
||||||
_devices.push_back(newDevice(device));
|
newDevices.push_back(newDevice(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!newDevices.isEmpty()) {
|
||||||
|
if (!hmdIsSelected) {
|
||||||
|
_backupSelectedHMDDeviceName = !_selectedHMDDevice.isNull() ? _selectedHMDDevice.deviceName() : _hmdSavedDeviceName;
|
||||||
|
auto device = getSimilarDevice(_backupSelectedHMDDeviceName, newDevices);
|
||||||
|
device->selectedHMD = true;
|
||||||
|
emit selectedDevicePlugged(device->info, true);
|
||||||
|
}
|
||||||
|
if (!desktopIsSelected) {
|
||||||
|
_backupSelectedDesktopDeviceName = !_selectedDesktopDevice.isNull() ? _selectedDesktopDevice.deviceName() : _desktopSavedDeviceName;
|
||||||
|
auto device = getSimilarDevice(_backupSelectedDesktopDeviceName, newDevices);
|
||||||
|
device->selectedDesktop = true;
|
||||||
|
emit selectedDevicePlugged(device->info, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_devices.swap(newDevices);
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,12 +376,10 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
|
||||||
// connections are made after client is initialized, so we must also fetch the devices
|
// connections are made after client is initialized, so we must also fetch the devices
|
||||||
const QList<QAudioDeviceInfo>& devicesInput = client->getAudioDevices(QAudio::AudioInput);
|
const QList<QAudioDeviceInfo>& devicesInput = client->getAudioDevices(QAudio::AudioInput);
|
||||||
const QList<QAudioDeviceInfo>& devicesOutput = client->getAudioDevices(QAudio::AudioOutput);
|
const QList<QAudioDeviceInfo>& devicesOutput = client->getAudioDevices(QAudio::AudioOutput);
|
||||||
//setup HMD devices
|
|
||||||
_inputs.onDevicesChanged(devicesInput, true);
|
//setup devices
|
||||||
_outputs.onDevicesChanged(devicesOutput, true);
|
_inputs.onDevicesChanged(devicesInput);
|
||||||
//setup Desktop devices
|
_outputs.onDevicesChanged(devicesOutput);
|
||||||
_inputs.onDevicesChanged(devicesInput, false);
|
|
||||||
_outputs.onDevicesChanged(devicesOutput, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDevices::~AudioDevices() {}
|
AudioDevices::~AudioDevices() {}
|
||||||
|
@ -375,11 +478,19 @@ void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceI
|
||||||
|
|
||||||
//set devices for both contexts
|
//set devices for both contexts
|
||||||
if (mode == QAudio::AudioInput) {
|
if (mode == QAudio::AudioInput) {
|
||||||
_inputs.onDevicesChanged(devices, _contextIsHMD);
|
_inputs.onDevicesChanged(devices);
|
||||||
_inputs.onDevicesChanged(devices, !_contextIsHMD);
|
|
||||||
|
static std::once_flag onceAfterInputDevicesChanged;
|
||||||
|
std::call_once(onceAfterInputDevicesChanged, [&] { // we only want 'selectedDevicePlugged' signal to be handled after initial list of input devices was populated
|
||||||
|
connect(&_inputs, &AudioDeviceList::selectedDevicePlugged, this, &AudioDevices::chooseInputDevice);
|
||||||
|
});
|
||||||
} else { // if (mode == QAudio::AudioOutput)
|
} else { // if (mode == QAudio::AudioOutput)
|
||||||
_outputs.onDevicesChanged(devices, _contextIsHMD);
|
_outputs.onDevicesChanged(devices);
|
||||||
_outputs.onDevicesChanged(devices, !_contextIsHMD);
|
|
||||||
|
static std::once_flag onceAfterOutputDevicesChanged;
|
||||||
|
std::call_once(onceAfterOutputDevicesChanged, [&] { // we only want 'selectedDevicePlugged' signal to be handled after initial list of output devices was populated
|
||||||
|
connect(&_outputs, &AudioDeviceList::selectedDevicePlugged, this, &AudioDevices::chooseOutputDevice);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,11 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void deviceChanged(const QAudioDeviceInfo& device);
|
void deviceChanged(const QAudioDeviceInfo& device);
|
||||||
|
void selectedDevicePlugged(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD);
|
void onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
void onDevicesChanged(const QList<QAudioDeviceInfo>& devices, bool isHMD);
|
void onDevicesChanged(const QList<QAudioDeviceInfo>& devices);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class AudioDevices;
|
friend class AudioDevices;
|
||||||
|
@ -64,6 +65,8 @@ protected:
|
||||||
const QAudio::Mode _mode;
|
const QAudio::Mode _mode;
|
||||||
QAudioDeviceInfo _selectedDesktopDevice;
|
QAudioDeviceInfo _selectedDesktopDevice;
|
||||||
QAudioDeviceInfo _selectedHMDDevice;
|
QAudioDeviceInfo _selectedHMDDevice;
|
||||||
|
QString _backupSelectedDesktopDeviceName;
|
||||||
|
QString _backupSelectedHMDDeviceName;
|
||||||
QList<std::shared_ptr<AudioDevice>> _devices;
|
QList<std::shared_ptr<AudioDevice>> _devices;
|
||||||
QString _hmdSavedDeviceName;
|
QString _hmdSavedDeviceName;
|
||||||
QString _desktopSavedDeviceName;
|
QString _desktopSavedDeviceName;
|
||||||
|
@ -117,13 +120,13 @@ public:
|
||||||
AudioDevices(bool& contextIsHMD);
|
AudioDevices(bool& contextIsHMD);
|
||||||
virtual ~AudioDevices();
|
virtual ~AudioDevices();
|
||||||
|
|
||||||
void chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
|
||||||
void chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nop();
|
void nop();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
|
void chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
|
|
||||||
void onContextChanged(const QString& context);
|
void onContextChanged(const QString& context);
|
||||||
void onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device,
|
void onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device,
|
||||||
const QAudioDeviceInfo& previousDevice, bool isHMD);
|
const QAudioDeviceInfo& previousDevice, bool isHMD);
|
||||||
|
|
|
@ -78,13 +78,17 @@ void WindowScriptingInterface::setFocus() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowScriptingInterface::raiseMainWindow() {
|
void WindowScriptingInterface::raise() {
|
||||||
// It's forbidden to call raise() from another thread.
|
// It's forbidden to call raise() from another thread.
|
||||||
qApp->postLambdaEvent([] {
|
qApp->postLambdaEvent([] {
|
||||||
qApp->raise();
|
qApp->raise();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowScriptingInterface::raiseMainWindow() {
|
||||||
|
raise();
|
||||||
|
}
|
||||||
|
|
||||||
/// Display an alert box
|
/// Display an alert box
|
||||||
/// \param const QString& message message to display
|
/// \param const QString& message message to display
|
||||||
/// \return QScriptValue::UndefinedValue
|
/// \return QScriptValue::UndefinedValue
|
||||||
|
|
|
@ -68,9 +68,16 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void setFocus();
|
void setFocus();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Raise the Interface window if it is minimized. If raised, the window gains focus.
|
||||||
|
* @function Window.raise
|
||||||
|
*/
|
||||||
|
void raise();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Raise the Interface window if it is minimized. If raised, the window gains focus.
|
* Raise the Interface window if it is minimized. If raised, the window gains focus.
|
||||||
* @function Window.raiseMainWindow
|
* @function Window.raiseMainWindow
|
||||||
|
* @deprecated Use {@link Window.raise|raise} instead.
|
||||||
*/
|
*/
|
||||||
void raiseMainWindow();
|
void raiseMainWindow();
|
||||||
|
|
||||||
|
|
|
@ -1246,6 +1246,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
||||||
const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo,
|
const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo,
|
||||||
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) {
|
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) {
|
||||||
|
|
||||||
|
const bool ENABLE_POLE_VECTORS = false;
|
||||||
const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.95f;
|
const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.95f;
|
||||||
|
|
||||||
int hipsIndex = indexOfJoint("Hips");
|
int hipsIndex = indexOfJoint("Hips");
|
||||||
|
@ -1268,7 +1269,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
||||||
int handJointIndex = _animSkeleton->nameToJointIndex("LeftHand");
|
int handJointIndex = _animSkeleton->nameToJointIndex("LeftHand");
|
||||||
int armJointIndex = _animSkeleton->nameToJointIndex("LeftArm");
|
int armJointIndex = _animSkeleton->nameToJointIndex("LeftArm");
|
||||||
int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm");
|
int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm");
|
||||||
if (!leftArmEnabled && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) {
|
if (ENABLE_POLE_VECTORS && !leftArmEnabled && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) {
|
||||||
glm::vec3 poleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, hipsIndex, true);
|
glm::vec3 poleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, hipsIndex, true);
|
||||||
|
|
||||||
// smooth toward desired pole vector from previous pole vector... to reduce jitter
|
// smooth toward desired pole vector from previous pole vector... to reduce jitter
|
||||||
|
@ -1315,7 +1316,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab
|
||||||
int handJointIndex = _animSkeleton->nameToJointIndex("RightHand");
|
int handJointIndex = _animSkeleton->nameToJointIndex("RightHand");
|
||||||
int armJointIndex = _animSkeleton->nameToJointIndex("RightArm");
|
int armJointIndex = _animSkeleton->nameToJointIndex("RightArm");
|
||||||
int elbowJointIndex = _animSkeleton->nameToJointIndex("RightForeArm");
|
int elbowJointIndex = _animSkeleton->nameToJointIndex("RightForeArm");
|
||||||
if (!rightArmEnabled && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) {
|
if (ENABLE_POLE_VECTORS && !rightArmEnabled && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) {
|
||||||
glm::vec3 poleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, hipsIndex, false);
|
glm::vec3 poleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, hipsIndex, false);
|
||||||
|
|
||||||
// smooth toward desired pole vector from previous pole vector... to reduce jitter
|
// smooth toward desired pole vector from previous pole vector... to reduce jitter
|
||||||
|
@ -1555,18 +1556,21 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
|
||||||
updateFeet(leftFootEnabled, rightFootEnabled,
|
updateFeet(leftFootEnabled, rightFootEnabled,
|
||||||
params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot]);
|
params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot]);
|
||||||
|
|
||||||
|
|
||||||
|
if (headEnabled) {
|
||||||
|
// Blend IK chains toward the joint limit centers, this should stablize head and hand ik.
|
||||||
|
_animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses);
|
||||||
|
} else {
|
||||||
|
// Blend IK chains toward the UnderPoses, so some of the animaton motion is present in the IK solution.
|
||||||
|
_animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToUnderPoses);
|
||||||
|
}
|
||||||
|
|
||||||
// if the hips or the feet are being controlled.
|
// if the hips or the feet are being controlled.
|
||||||
if (hipsEnabled || rightFootEnabled || leftFootEnabled) {
|
if (hipsEnabled || rightFootEnabled || leftFootEnabled) {
|
||||||
// for more predictable IK solve from the center of the joint limits, not from the underpose
|
|
||||||
_animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses);
|
|
||||||
|
|
||||||
// replace the feet animation with the default pose, this is to prevent unexpected toe wiggling.
|
// replace the feet animation with the default pose, this is to prevent unexpected toe wiggling.
|
||||||
_animVars.set("defaultPoseOverlayAlpha", 1.0f);
|
_animVars.set("defaultPoseOverlayAlpha", 1.0f);
|
||||||
_animVars.set("defaultPoseOverlayBoneSet", (int)AnimOverlay::BothFeetBoneSet);
|
_animVars.set("defaultPoseOverlayBoneSet", (int)AnimOverlay::BothFeetBoneSet);
|
||||||
} else {
|
} else {
|
||||||
// augment the IK with the underPose.
|
|
||||||
_animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToUnderPoses);
|
|
||||||
|
|
||||||
// feet should follow source animation
|
// feet should follow source animation
|
||||||
_animVars.unset("defaultPoseOverlayAlpha");
|
_animVars.unset("defaultPoseOverlayAlpha");
|
||||||
_animVars.unset("defaultPoseOverlayBoneSet");
|
_animVars.unset("defaultPoseOverlayBoneSet");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
var qml = Script.resourcesPath() + '/qml/AudioScope.qml';
|
var qml = Script.resourcesPath() + '/qml/AudioScopeUI.qml';
|
||||||
var window = new OverlayWindow({
|
var window = new OverlayWindow({
|
||||||
title: 'Audio Scope',
|
title: 'Audio Scope',
|
||||||
source: qml,
|
source: qml,
|
||||||
|
@ -14,4 +14,4 @@ window.closed.connect(function () {
|
||||||
AudioScope.setServerEcho(false);
|
AudioScope.setServerEcho(false);
|
||||||
AudioScope.selectAudioScopeFiveFrames();
|
AudioScope.selectAudioScopeFiveFrames();
|
||||||
Script.stop();
|
Script.stop();
|
||||||
});
|
});
|
||||||
|
|
|
@ -89,14 +89,8 @@
|
||||||
bubbleOverlayTimestamp = nowTimestamp;
|
bubbleOverlayTimestamp = nowTimestamp;
|
||||||
Script.update.connect(update);
|
Script.update.connect(update);
|
||||||
updateConnected = true;
|
updateConnected = true;
|
||||||
|
writeButtonProperties(bubbleButtonFlashState);
|
||||||
// Flash button
|
bubbleButtonFlashState = !bubbleButtonFlashState;
|
||||||
if (!bubbleFlashTimer) {
|
|
||||||
bubbleFlashTimer = Script.setInterval(function () {
|
|
||||||
writeButtonProperties(bubbleButtonFlashState);
|
|
||||||
bubbleButtonFlashState = !bubbleButtonFlashState;
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from the C++ scripting interface to show the bubble overlay
|
// Called from the C++ scripting interface to show the bubble overlay
|
||||||
|
|
|
@ -475,7 +475,7 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
entityID = targetEntity.id;
|
entityID = targetEntity.id;
|
||||||
targetProps = targetEntity.props;
|
targetProps = targetEntity.props;
|
||||||
|
|
||||||
if (entityIsGrabbable(targetProps)) {
|
if (entityIsGrabbable(targetProps) || entityIsGrabbable(this.targetObject.entityProps)) {
|
||||||
if (!entityIsDistanceGrabbable(targetProps)) {
|
if (!entityIsDistanceGrabbable(targetProps)) {
|
||||||
this.targetObject.makeDynamic();
|
this.targetObject.makeDynamic();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue