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