From 120bbbd5067efed3724bf2fc37d9ce2ff5965cdf Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 6 Aug 2013 12:34:45 -0700 Subject: [PATCH] Tuned gyro look, added better preferences --- interface/src/Application.cpp | 23 ++++++++++------------- interface/src/Application.h | 2 +- interface/src/avatar/Avatar.cpp | 19 ++++++++++++------- interface/src/avatar/Avatar.h | 3 +-- interface/src/avatar/Head.cpp | 25 ++++++++++++------------- interface/src/avatar/Head.h | 2 +- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5efe365a49..88b92e1d45 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1290,9 +1290,9 @@ void Application::editPreferences() { horizontalFieldOfView->setValue(_horizontalFieldOfView); form->addRow("Horizontal field of view (degrees):", horizontalFieldOfView); - QDoubleSpinBox* headCameraPitchYawScale = new QDoubleSpinBox(); - headCameraPitchYawScale->setValue(_headCameraPitchYawScale); - form->addRow("Head Camera Pitch/Yaw Scale:", headCameraPitchYawScale); + QDoubleSpinBox* gyroCameraSensitivity = new QDoubleSpinBox(); + gyroCameraSensitivity->setValue(_gyroCameraSensitivity); + form->addRow("Gyro Camera Sensitivity (0 - 1):", gyroCameraSensitivity); QDoubleSpinBox* leanScale = new QDoubleSpinBox(); leanScale->setValue(_myAvatar.getLeanScale()); @@ -1342,7 +1342,7 @@ void Application::editPreferences() { _myAvatar.getVoxels()->setVoxelURL(url); sendAvatarVoxelURLMessage(url); - _headCameraPitchYawScale = headCameraPitchYawScale->value(); + _gyroCameraSensitivity = gyroCameraSensitivity->value(); _myAvatar.setLeanScale(leanScale->value()); _audioJitterBufferSamples = audioJitterBufferSamples->value(); if (!shouldDynamicallySetJitterBuffer()) { @@ -2500,7 +2500,7 @@ void Application::update(float deltaTime) { if (!avatar->isInitialized()) { avatar->init(); } - avatar->simulate(deltaTime, NULL); + avatar->simulate(deltaTime, NULL, 0.f); avatar->setMouseRay(mouseRayOrigin, mouseRayDirection); } node->unlock(); @@ -2515,9 +2515,9 @@ void Application::update(float deltaTime) { } if (_transmitterDrives->isChecked() && _myTransmitter.isConnected()) { - _myAvatar.simulate(deltaTime, &_myTransmitter); + _myAvatar.simulate(deltaTime, &_myTransmitter, _gyroCameraSensitivity); } else { - _myAvatar.simulate(deltaTime, NULL); + _myAvatar.simulate(deltaTime, NULL, _gyroCameraSensitivity); } if (!OculusManager::isConnected()) { @@ -2584,9 +2584,6 @@ void Application::updateAvatar(float deltaTime) { // Update my avatar's state from gyros and/or webcam _myAvatar.updateFromGyrosAndOrWebcam(_gyroLook->isChecked(), - glm::vec3(_headCameraPitchYawScale, - _headCameraPitchYawScale, - _headCameraPitchYawScale), _pitchFromTouch); if (_serialHeadSensor.isActive()) { @@ -3951,11 +3948,11 @@ void Application::saveAction(QSettings* set, QAction* action) { } void Application::loadSettings(QSettings* settings) { - if (!settings) { + if (!settings) { settings = getSettings(); } - _headCameraPitchYawScale = loadSetting(settings, "headCameraPitchYawScale", 0.0f); + _gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f); _audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0); _horizontalFieldOfView = loadSetting(settings, "horizontalFieldOfView", HORIZONTAL_FIELD_OF_VIEW_DEGREES); @@ -3979,7 +3976,7 @@ void Application::saveSettings(QSettings* settings) { settings = getSettings(); } - settings->setValue("headCameraPitchYawScale", _headCameraPitchYawScale); + settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity); settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples); settings->setValue("horizontalFieldOfView", _horizontalFieldOfView); settings->beginGroup("View Frustum Offset Camera"); diff --git a/interface/src/Application.h b/interface/src/Application.h index cb851c1dfc..dfb38d5dd5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -358,7 +358,7 @@ private: Environment _environment; int _headMouseX, _headMouseY; - float _headCameraPitchYawScale; + float _gyroCameraSensitivity; int _audioJitterBufferSamples; // Number of extra samples to wait before starting audio playback diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0b6484c8a7..b67a32887c 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -294,7 +294,6 @@ void Avatar::reset() { // Update avatar head rotation with sensor data void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook, - const glm::vec3& amplifyAngle, float pitchFromTouch) { _head.setMousePitch(pitchFromTouch); SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor(); @@ -333,9 +332,15 @@ void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook, } else { _head.getFace().clearFrame(); } - _head.setPitch(estimatedRotation.x * amplifyAngle.x); - _head.setYaw(estimatedRotation.y * amplifyAngle.y); - _head.setRoll(estimatedRotation.z * amplifyAngle.z); + + // Set the rotation of the avatar's head (as seen by others, not affecting view frustum) + // to be scaled. Pitch is greater to emphasize nodding behavior / synchrony. + const float AVATAR_HEAD_PITCH_MAGNIFY = 1.0f; + const float AVATAR_HEAD_YAW_MAGNIFY = 1.0f; + const float AVATAR_HEAD_ROLL_MAGNIFY = 1.0f; + _head.setPitch(estimatedRotation.x * AVATAR_HEAD_PITCH_MAGNIFY); + _head.setYaw(estimatedRotation.y * AVATAR_HEAD_YAW_MAGNIFY); + _head.setRoll(estimatedRotation.z * AVATAR_HEAD_ROLL_MAGNIFY); _head.setCameraFollowsHead(gyroLook); // Update torso lean distance based on accelerometer data @@ -390,7 +395,7 @@ void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) { // // Gather thrust information from keyboard and sensors to apply to avatar motion // - glm::quat orientation = getHead().getOrientation(); + glm::quat orientation = getHead().getCameraOrientation(); glm::vec3 front = orientation * IDENTITY_FRONT; glm::vec3 right = orientation * IDENTITY_RIGHT; glm::vec3 up = orientation * IDENTITY_UP; @@ -499,7 +504,7 @@ void Avatar::follow(Avatar* leadingAvatar) { } } -void Avatar::simulate(float deltaTime, Transmitter* transmitter) { +void Avatar::simulate(float deltaTime, Transmitter* transmitter, float gyroCameraSensitivity) { glm::quat orientation = getOrientation(); glm::vec3 front = orientation * IDENTITY_FRONT; @@ -746,7 +751,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _head.setPosition(_bodyBall[ BODY_BALL_HEAD_BASE ].position); _head.setScale(_scale); _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); - _head.simulate(deltaTime, isMyAvatar()); + _head.simulate(deltaTime, isMyAvatar(), gyroCameraSensitivity); _hand.simulate(deltaTime, isMyAvatar()); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index ca41bdcb32..fc475a5bd2 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -119,11 +119,10 @@ public: void init(); void reset(); - void simulate(float deltaTime, Transmitter* transmitter); + void simulate(float deltaTime, Transmitter* transmitter, float gyroCameraSensitivity); void updateThrust(float deltaTime, Transmitter * transmitter); void follow(Avatar* leadingAvatar); void updateFromGyrosAndOrWebcam(bool gyroLook, - const glm::vec3& amplifyAngle, float pitchFromTouch); void addBodyYaw(float bodyYaw) {_bodyYaw += bodyYaw;}; void addBodyYawDelta(float bodyYawDelta) {_bodyYawDelta += bodyYawDelta;} diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 40ed309097..08d9856634 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -146,7 +146,7 @@ void Head::resetHairPhysics() { } -void Head::simulate(float deltaTime, bool isMine) { +void Head::simulate(float deltaTime, bool isMine, float gyroCameraSensitivity) { // Update eye saccades const float AVERAGE_MICROSACCADE_INTERVAL = 0.50f; @@ -228,15 +228,18 @@ void Head::simulate(float deltaTime, bool isMine) { } // Update camera pitch and yaw independently from motion of head (for gyro-based interface) - if (isMine && _cameraFollowsHead) { + if (isMine && _cameraFollowsHead && (gyroCameraSensitivity > 0.f)) { // If we are using gyros and using gyroLook, have the camera follow head but with a null region // to create stable rendering view with small head movements. - const float CAMERA_FOLLOW_HEAD_RATE_START = 0.01f; - const float CAMERA_FOLLOW_HEAD_RATE_MAX = 0.5f; + const float CAMERA_FOLLOW_HEAD_RATE_START = 0.1f; + const float CAMERA_FOLLOW_HEAD_RATE_MAX = 1.0f; const float CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE = 1.05f; const float CAMERA_STOP_TOLERANCE_DEGREES = 0.5f; - const float CAMERA_PITCH_START_TOLERANCE_DEGREES = 20.0f; - const float CAMERA_YAW_START_TOLERANCE_DEGREES = 10.0f; + const float PITCH_START_RANGE = 20.f; + const float YAW_START_RANGE = 10.f; + float pitchStartTolerance = PITCH_START_RANGE * (1.f - gyroCameraSensitivity); + float yawStartTolerance = YAW_START_RANGE * (1.f - gyroCameraSensitivity); + float cameraHeadAngleDifference = glm::length(glm::vec2(_pitch - _cameraPitch, _yaw - _cameraYaw)); if (_isCameraMoving) { _cameraFollowHeadRate = glm::clamp(_cameraFollowHeadRate * CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE, @@ -249,17 +252,13 @@ void Head::simulate(float deltaTime, bool isMine) { _isCameraMoving = false; } } else { - if ((fabs(_pitch - _cameraPitch) > CAMERA_PITCH_START_TOLERANCE_DEGREES) || - (fabs(_yaw - _cameraYaw) > CAMERA_YAW_START_TOLERANCE_DEGREES)) { + if ((fabs(_pitch - _cameraPitch) > pitchStartTolerance) || + (fabs(_yaw - _cameraYaw) > yawStartTolerance)) { _isCameraMoving = true; _cameraFollowHeadRate = CAMERA_FOLLOW_HEAD_RATE_START; } } - } else { - // Camera always locked to head - _cameraPitch = _pitch; - _cameraYaw = _yaw; - } + } } void Head::calculateGeometry() { diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index f31bc53f2a..ea9e7fab0e 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -41,7 +41,7 @@ public: void init(); void reset(); - void simulate(float deltaTime, bool isMine); + void simulate(float deltaTime, bool isMine, float gyroCameraSensitivity); void render(float alpha); void renderMohawk();