mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-07 08:23:17 +02:00
Merge pull request #14678 from hyperlogic/feature/hmd-avatar-alignment-type
Added HMD Avatar Alignment Type
This commit is contained in:
commit
f084021fdf
10 changed files with 156 additions and 21 deletions
|
@ -254,6 +254,7 @@ Rectangle {
|
|||
onSaveClicked: function() {
|
||||
var avatarSettings = {
|
||||
dominantHand : settings.dominantHandIsLeft ? 'left' : 'right',
|
||||
hmdAvatarAlignmentType : settings.hmdAvatarAlignmentTypeIsEyes ? 'eyes' : 'head',
|
||||
collisionsEnabled : settings.environmentCollisionsOn,
|
||||
otherAvatarsCollisionsEnabled : settings.otherAvatarsCollisionsOn,
|
||||
animGraphOverrideUrl : settings.avatarAnimationOverrideJSON,
|
||||
|
|
|
@ -37,6 +37,7 @@ Rectangle {
|
|||
property alias dominantHandIsLeft: leftHandRadioButton.checked
|
||||
property alias otherAvatarsCollisionsOn: otherAvatarsCollisionsEnabledRadiobutton.checked
|
||||
property alias environmentCollisionsOn: environmentCollisionsEnabledRadiobutton.checked
|
||||
property alias hmdAvatarAlignmentTypeIsEyes: eyesRadioButton.checked
|
||||
property alias avatarAnimationOverrideJSON: avatarAnimationUrlInputText.text
|
||||
property alias avatarAnimationJSON: avatarAnimationUrlInputText.placeholderText
|
||||
property alias avatarCollisionSoundUrl: avatarCollisionSoundUrlInputText.text
|
||||
|
@ -65,6 +66,11 @@ Rectangle {
|
|||
} else {
|
||||
environmentCollisionsDisabledRadiobutton.checked = true;
|
||||
}
|
||||
if (settings.hmdAvatarAlignmentType === 'eyes') {
|
||||
eyesRadioButton.checked = true;
|
||||
} else {
|
||||
headRadioButton.checked = true;
|
||||
}
|
||||
|
||||
avatarAnimationJSON = settings.animGraphUrl;
|
||||
avatarAnimationOverrideJSON = settings.animGraphOverrideUrl;
|
||||
|
@ -210,7 +216,7 @@ Rectangle {
|
|||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
rows: 2
|
||||
rows: 4
|
||||
rowSpacing: 25
|
||||
|
||||
columns: 3
|
||||
|
@ -233,7 +239,7 @@ Rectangle {
|
|||
|
||||
Layout.row: 0
|
||||
Layout.column: 1
|
||||
Layout.leftMargin: -20
|
||||
Layout.leftMargin: -15
|
||||
|
||||
ButtonGroup.group: leftRight
|
||||
checked: true
|
||||
|
@ -249,7 +255,7 @@ Rectangle {
|
|||
id: rightHandRadioButton
|
||||
|
||||
Layout.row: 0
|
||||
Layout.column: 3
|
||||
Layout.column: 2
|
||||
Layout.rightMargin: -15
|
||||
|
||||
ButtonGroup.group: leftRight
|
||||
|
@ -260,7 +266,7 @@ Rectangle {
|
|||
text: "Right"
|
||||
boxSize: 20
|
||||
}
|
||||
|
||||
|
||||
HifiConstants {
|
||||
id: hifi
|
||||
}
|
||||
|
@ -272,17 +278,17 @@ Rectangle {
|
|||
Layout.column: 0
|
||||
text: "Avatar to avatar collision"
|
||||
}
|
||||
|
||||
|
||||
ButtonGroup {
|
||||
id: otherAvatarsOnOff
|
||||
}
|
||||
|
||||
|
||||
HifiControlsUit.RadioButton {
|
||||
id: otherAvatarsCollisionsEnabledRadiobutton
|
||||
|
||||
Layout.row: 1
|
||||
Layout.column: 1
|
||||
Layout.leftMargin: -20
|
||||
Layout.leftMargin: -15
|
||||
|
||||
ButtonGroup.group: otherAvatarsOnOff
|
||||
|
||||
|
@ -297,7 +303,7 @@ Rectangle {
|
|||
id: otherAvatarsCollisionsDisabledRadiobutton
|
||||
|
||||
Layout.row: 1
|
||||
Layout.column: 3
|
||||
Layout.column: 2
|
||||
Layout.rightMargin: -15
|
||||
|
||||
ButtonGroup.group: otherAvatarsOnOff
|
||||
|
@ -320,13 +326,13 @@ Rectangle {
|
|||
ButtonGroup {
|
||||
id: worldOnOff
|
||||
}
|
||||
|
||||
|
||||
HifiControlsUit.RadioButton {
|
||||
id: environmentCollisionsEnabledRadiobutton
|
||||
|
||||
Layout.row: 2
|
||||
Layout.column: 1
|
||||
Layout.leftMargin: -20
|
||||
Layout.leftMargin: -15
|
||||
|
||||
ButtonGroup.group: worldOnOff
|
||||
|
||||
|
@ -341,7 +347,7 @@ Rectangle {
|
|||
id: environmentCollisionsDisabledRadiobutton
|
||||
|
||||
Layout.row: 2
|
||||
Layout.column: 3
|
||||
Layout.column: 2
|
||||
Layout.rightMargin: -15
|
||||
|
||||
ButtonGroup.group: worldOnOff
|
||||
|
@ -352,6 +358,52 @@ Rectangle {
|
|||
text: "Off"
|
||||
boxSize: 20
|
||||
}
|
||||
|
||||
// TextStyle9
|
||||
RalewaySemiBold {
|
||||
size: 17;
|
||||
Layout.row: 3
|
||||
Layout.column: 0
|
||||
text: "HMD Alignment"
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: headEyes
|
||||
}
|
||||
|
||||
HifiControlsUit.RadioButton {
|
||||
id: headRadioButton
|
||||
|
||||
Layout.row: 3
|
||||
Layout.column: 1
|
||||
Layout.leftMargin: -15
|
||||
|
||||
ButtonGroup.group: headEyes
|
||||
checked: true
|
||||
|
||||
colorScheme: hifi.colorSchemes.light
|
||||
fontSize: 17
|
||||
letterSpacing: 1.4
|
||||
text: "Head"
|
||||
boxSize: 20
|
||||
}
|
||||
|
||||
HifiControlsUit.RadioButton {
|
||||
id: eyesRadioButton
|
||||
|
||||
Layout.row: 3
|
||||
Layout.column: 2
|
||||
Layout.rightMargin: -15
|
||||
|
||||
ButtonGroup.group: headEyes
|
||||
|
||||
colorScheme: hifi.colorSchemes.light
|
||||
fontSize: 17
|
||||
letterSpacing: 1.4
|
||||
text: "Eyes"
|
||||
boxSize: 20
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
|
|
@ -6062,6 +6062,13 @@ void Application::update(float deltaTime) {
|
|||
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
|
||||
controller::HmdAvatarAlignmentType hmdAvatarAlignmentType;
|
||||
if (myAvatar->getHmdAvatarAlignmentType() == "eyes") {
|
||||
hmdAvatarAlignmentType = controller::HmdAvatarAlignmentType::Eyes;
|
||||
} else {
|
||||
hmdAvatarAlignmentType = controller::HmdAvatarAlignmentType::Head;
|
||||
}
|
||||
|
||||
controller::InputCalibrationData calibrationData = {
|
||||
myAvatar->getSensorToWorldMatrix(),
|
||||
createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()),
|
||||
|
@ -6075,7 +6082,8 @@ void Application::update(float deltaTime) {
|
|||
myAvatar->getRightArmCalibrationMat(),
|
||||
myAvatar->getLeftArmCalibrationMat(),
|
||||
myAvatar->getRightHandCalibrationMat(),
|
||||
myAvatar->getLeftHandCalibrationMat()
|
||||
myAvatar->getLeftHandCalibrationMat(),
|
||||
hmdAvatarAlignmentType
|
||||
};
|
||||
|
||||
InputPluginPointer keyboardMousePlugin;
|
||||
|
|
|
@ -125,6 +125,7 @@ MyAvatar::MyAvatar(QThread* thread) :
|
|||
_prevShouldDrawHead(true),
|
||||
_audioListenerMode(FROM_HEAD),
|
||||
_dominantHandSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "dominantHand", DOMINANT_RIGHT_HAND),
|
||||
_hmdAvatarAlignmentTypeSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "hmdAvatarAlignmentType", DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE),
|
||||
_headPitchSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "", 0.0f),
|
||||
_scaleSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "scale", _targetScale),
|
||||
_yawSpeedSetting(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "yawSpeed", _yawSpeed),
|
||||
|
@ -286,10 +287,25 @@ MyAvatar::~MyAvatar() {
|
|||
_myScriptEngine = nullptr;
|
||||
}
|
||||
|
||||
QString MyAvatar::getDominantHand() const {
|
||||
return _dominantHand.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setDominantHand(const QString& hand) {
|
||||
if (hand == DOMINANT_LEFT_HAND || hand == DOMINANT_RIGHT_HAND) {
|
||||
_dominantHand = hand;
|
||||
emit dominantHandChanged(_dominantHand);
|
||||
_dominantHand.set(hand);
|
||||
emit dominantHandChanged(hand);
|
||||
}
|
||||
}
|
||||
|
||||
QString MyAvatar::getHmdAvatarAlignmentType() const {
|
||||
return _hmdAvatarAlignmentType.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setHmdAvatarAlignmentType(const QString& type) {
|
||||
if (type != _hmdAvatarAlignmentType.get()) {
|
||||
_hmdAvatarAlignmentType.set(type);
|
||||
emit hmdAvatarAlignmentTypeChanged(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,6 +393,7 @@ void MyAvatar::resetSensorsAndBody() {
|
|||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "resetSensorsAndBody");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
qApp->getActiveDisplayPlugin()->resetSensors();
|
||||
|
@ -1277,7 +1294,8 @@ void MyAvatar::resizeAvatarEntitySettingHandles(uint32_t maxIndex) {
|
|||
}
|
||||
|
||||
void MyAvatar::saveData() {
|
||||
_dominantHandSetting.set(_dominantHand);
|
||||
_dominantHandSetting.set(getDominantHand());
|
||||
_hmdAvatarAlignmentTypeSetting.set(getHmdAvatarAlignmentType());
|
||||
_headPitchSetting.set(getHead()->getBasePitch());
|
||||
_scaleSetting.set(_targetScale);
|
||||
_yawSpeedSetting.set(_yawSpeed);
|
||||
|
@ -1882,6 +1900,7 @@ void MyAvatar::loadData() {
|
|||
setCollisionSoundURL(_collisionSoundURLSetting.get(QUrl(DEFAULT_AVATAR_COLLISION_SOUND_URL)).toString());
|
||||
setSnapTurn(_useSnapTurnSetting.get());
|
||||
setDominantHand(_dominantHandSetting.get(DOMINANT_RIGHT_HAND).toLower());
|
||||
setHmdAvatarAlignmentType(_hmdAvatarAlignmentTypeSetting.get(DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE).toLower());
|
||||
setUserHeight(_userHeightSetting.get(DEFAULT_AVATAR_HEIGHT));
|
||||
setTargetScale(_scaleSetting.get());
|
||||
|
||||
|
|
|
@ -252,6 +252,7 @@ class MyAvatar : public Avatar {
|
|||
|
||||
const QString DOMINANT_LEFT_HAND = "left";
|
||||
const QString DOMINANT_RIGHT_HAND = "right";
|
||||
const QString DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE = "head";
|
||||
|
||||
using Clock = std::chrono::system_clock;
|
||||
using TimePoint = Clock::time_point;
|
||||
|
@ -519,7 +520,18 @@ public:
|
|||
* @function MyAvatar.getDominantHand
|
||||
* @returns {string}
|
||||
*/
|
||||
Q_INVOKABLE QString getDominantHand() const { return _dominantHand; }
|
||||
Q_INVOKABLE QString getDominantHand() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.setHmdAvatarAlignmentType
|
||||
* @param {string} hand
|
||||
*/
|
||||
Q_INVOKABLE void setHmdAvatarAlignmentType(const QString& hand);
|
||||
/**jsdoc
|
||||
* @function MyAvatar.setHmdAvatarAlignmentType
|
||||
* @returns {string}
|
||||
*/
|
||||
Q_INVOKABLE QString getHmdAvatarAlignmentType() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.setCenterOfGravityModelEnabled
|
||||
|
@ -1585,6 +1597,13 @@ signals:
|
|||
*/
|
||||
void dominantHandChanged(const QString& hand);
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.hmdAvatarAlignmentTypeChanged
|
||||
* @param {string} type
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void hmdAvatarAlignmentTypeChanged(const QString& type);
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.sensorToWorldScaleChanged
|
||||
* @param {number} scale
|
||||
|
@ -1773,7 +1792,8 @@ private:
|
|||
ThreadSafeValueCache<QUrl> _prefOverrideAnimGraphUrl;
|
||||
QUrl _fstAnimGraphOverrideUrl;
|
||||
bool _useSnapTurn { true };
|
||||
QString _dominantHand { DOMINANT_RIGHT_HAND };
|
||||
ThreadSafeValueCache<QString> _dominantHand { DOMINANT_RIGHT_HAND };
|
||||
ThreadSafeValueCache<QString> _hmdAvatarAlignmentType { DEFAULT_HMD_AVATAR_ALIGNMENT_TYPE };
|
||||
|
||||
const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // degrees
|
||||
const float ROLL_CONTROL_RATE_DEFAULT = 114.0f; // degrees / sec
|
||||
|
@ -1946,6 +1966,7 @@ private:
|
|||
TimePoint _nextTraitsSendWindow;
|
||||
|
||||
Setting::Handle<QString> _dominantHandSetting;
|
||||
Setting::Handle<QString> _hmdAvatarAlignmentTypeSetting;
|
||||
Setting::Handle<float> _headPitchSetting;
|
||||
Setting::Handle<float> _scaleSetting;
|
||||
Setting::Handle<float> _yawSpeedSetting;
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
|
||||
namespace controller {
|
||||
|
||||
enum class HmdAvatarAlignmentType {
|
||||
Eyes = 0, // align the user's eyes with the avatars eyes
|
||||
Head // align the user's head with the avatars head
|
||||
};
|
||||
|
||||
struct InputCalibrationData {
|
||||
glm::mat4 sensorToWorldMat; // sensor to world
|
||||
glm::mat4 avatarMat; // avatar to world
|
||||
|
@ -29,6 +34,7 @@ struct InputCalibrationData {
|
|||
glm::mat4 defaultLeftArm; // default pose for leftArm joint in sensor space
|
||||
glm::mat4 defaultRightHand; // default pose for rightHand joint in sensor space
|
||||
glm::mat4 defaultLeftHand; // default pose for leftHand joint in sensor space
|
||||
HmdAvatarAlignmentType hmdAvatarAlignmentType;
|
||||
};
|
||||
|
||||
enum class ChannelType {
|
||||
|
|
|
@ -44,7 +44,7 @@ const float DEFAULT_AVATAR_RIGHTHAND_MASS = 2.0f;
|
|||
|
||||
// Used when avatar is missing joints... (avatar space)
|
||||
const glm::quat DEFAULT_AVATAR_MIDDLE_EYE_ROT { Quaternions::Y_180 };
|
||||
const glm::vec3 DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET = { 0.0f, 0.06f, -0.09f };
|
||||
const glm::vec3 DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET = { 0.0f, 0.064f, 0.084f };
|
||||
const glm::vec3 DEFAULT_AVATAR_HEAD_POS { 0.0f, 0.53f, 0.0f };
|
||||
const glm::quat DEFAULT_AVATAR_HEAD_ROT { Quaternions::Y_180 };
|
||||
const glm::vec3 DEFAULT_AVATAR_RIGHTARM_POS { -0.134824f, 0.396348f, -0.0515777f };
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <controllers/UserInputMapper.h>
|
||||
#include <controllers/StandardControls.h>
|
||||
|
||||
#include <AvatarConstants.h>
|
||||
#include <PerfStat.h>
|
||||
#include <PathUtils.h>
|
||||
#include <NumericalConstants.h>
|
||||
|
@ -327,8 +328,14 @@ void OculusControllerManager::TouchDevice::handleHeadPose(float deltaTime,
|
|||
ovr::toGlm(headPose.AngularVelocity));
|
||||
|
||||
glm::mat4 sensorToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat;
|
||||
glm::mat4 defaultHeadOffset = glm::inverse(inputCalibrationData.defaultCenterEyeMat) *
|
||||
inputCalibrationData.defaultHeadMat;
|
||||
glm::mat4 defaultHeadOffset;
|
||||
if (inputCalibrationData.hmdAvatarAlignmentType == controller::HmdAvatarAlignmentType::Eyes) {
|
||||
// align the eyes of the user with the eyes of the avatar
|
||||
defaultHeadOffset = glm::inverse(inputCalibrationData.defaultCenterEyeMat) * inputCalibrationData.defaultHeadMat;
|
||||
} else {
|
||||
// align the head of the user with the head of the avatar
|
||||
defaultHeadOffset = createMatFromQuatAndPos(Quaternions::IDENTITY, -DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET);
|
||||
}
|
||||
|
||||
pose.valid = true;
|
||||
_poseStateMap[controller::HEAD] = pose.postTransform(defaultHeadOffset).transform(sensorToAvatar);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <SettingHandle.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <AvatarConstants.h>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <ui-plugins/PluginContainer.h>
|
||||
|
@ -1024,7 +1025,16 @@ void ViveControllerManager::InputDevice::handleHeadPoseEvent(const controller::I
|
|||
//perform a 180 flip to make the HMD face the +z instead of -z, beacuse the head faces +z
|
||||
glm::mat4 matYFlip = mat * Matrices::Y_180;
|
||||
controller::Pose pose(extractTranslation(matYFlip), glmExtractRotation(matYFlip), linearVelocity, angularVelocity);
|
||||
glm::mat4 defaultHeadOffset = glm::inverse(inputCalibrationData.defaultCenterEyeMat) * inputCalibrationData.defaultHeadMat;
|
||||
|
||||
glm::mat4 defaultHeadOffset;
|
||||
if (inputCalibrationData.hmdAvatarAlignmentType == controller::HmdAvatarAlignmentType::Eyes) {
|
||||
// align the eyes of the user with the eyes of the avatar
|
||||
defaultHeadOffset = glm::inverse(inputCalibrationData.defaultCenterEyeMat) * inputCalibrationData.defaultHeadMat;
|
||||
} else {
|
||||
// align the head of the user with the head of the avatar
|
||||
defaultHeadOffset = createMatFromQuatAndPos(Quaternions::IDENTITY, -DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET);
|
||||
}
|
||||
|
||||
glm::mat4 sensorToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat;
|
||||
_poseStateMap[controller::HEAD] = pose.postTransform(defaultHeadOffset).transform(sensorToAvatar);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ function getMyAvatar() {
|
|||
function getMyAvatarSettings() {
|
||||
return {
|
||||
dominantHand: MyAvatar.getDominantHand(),
|
||||
hmdAvatarAlignmentType: MyAvatar.getHmdAvatarAlignmentType(),
|
||||
collisionsEnabled: MyAvatar.getCollisionsEnabled(),
|
||||
otherAvatarsCollisionsEnabled: MyAvatar.getOtherAvatarsCollisionsEnabled(),
|
||||
collisionSoundUrl : MyAvatar.collisionSoundURL,
|
||||
|
@ -129,6 +130,13 @@ function onDominantHandChanged(dominantHand) {
|
|||
}
|
||||
}
|
||||
|
||||
function onHmdAvatarAlignmentTypeChanged(type) {
|
||||
if (currentAvatarSettings.hmdAvatarAlignmentType !== type) {
|
||||
currentAvatarSettings.hmdAvatarAlignmentType = type;
|
||||
sendToQml({'method' : 'settingChanged', 'name' : 'hmdAvatarAlignmentType', 'value' : type});
|
||||
}
|
||||
}
|
||||
|
||||
function onCollisionsEnabledChanged(enabled) {
|
||||
if(currentAvatarSettings.collisionsEnabled !== enabled) {
|
||||
currentAvatarSettings.collisionsEnabled = enabled;
|
||||
|
@ -331,6 +339,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
|||
currentAvatar.avatarScale = message.avatarScale;
|
||||
|
||||
MyAvatar.setDominantHand(message.settings.dominantHand);
|
||||
MyAvatar.setHmdAvatarAlignmentType(message.settings.hmdAvatarAlignmentType);
|
||||
MyAvatar.setOtherAvatarsCollisionsEnabled(message.settings.otherAvatarsCollisionsEnabled);
|
||||
MyAvatar.setCollisionsEnabled(message.settings.collisionsEnabled);
|
||||
MyAvatar.collisionSoundURL = message.settings.collisionSoundUrl;
|
||||
|
@ -521,6 +530,7 @@ function off() {
|
|||
Entities.deletingWearable.disconnect(onDeletingWearable);
|
||||
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
|
||||
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
|
||||
MyAvatar.hmdAvatarAlignmentTypeChanged.disconnect(onHmdAvatarAlignmentTypeChanged);
|
||||
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
|
||||
MyAvatar.otherAvatarsCollisionsEnabledChanged.disconnect(onOtherAvatarsCollisionsEnabledChanged);
|
||||
MyAvatar.newCollisionSoundURL.disconnect(onNewCollisionSoundUrl);
|
||||
|
@ -542,6 +552,7 @@ function on() {
|
|||
Entities.deletingWearable.connect(onDeletingWearable);
|
||||
MyAvatar.skeletonModelURLChanged.connect(onSkeletonModelURLChanged);
|
||||
MyAvatar.dominantHandChanged.connect(onDominantHandChanged);
|
||||
MyAvatar.hmdAvatarAlignmentTypeChanged.connect(onHmdAvatarAlignmentTypeChanged);
|
||||
MyAvatar.collisionsEnabledChanged.connect(onCollisionsEnabledChanged);
|
||||
MyAvatar.otherAvatarsCollisionsEnabledChanged.connect(onOtherAvatarsCollisionsEnabledChanged);
|
||||
MyAvatar.newCollisionSoundURL.connect(onNewCollisionSoundUrl);
|
||||
|
|
Loading…
Reference in a new issue