Tuned gyro look, added better preferences

This commit is contained in:
Philip Rosedale 2013-08-06 12:34:45 -07:00
parent 58cb852597
commit 120bbbd506
6 changed files with 37 additions and 37 deletions

View file

@ -1290,9 +1290,9 @@ void Application::editPreferences() {
horizontalFieldOfView->setValue(_horizontalFieldOfView); horizontalFieldOfView->setValue(_horizontalFieldOfView);
form->addRow("Horizontal field of view (degrees):", horizontalFieldOfView); form->addRow("Horizontal field of view (degrees):", horizontalFieldOfView);
QDoubleSpinBox* headCameraPitchYawScale = new QDoubleSpinBox(); QDoubleSpinBox* gyroCameraSensitivity = new QDoubleSpinBox();
headCameraPitchYawScale->setValue(_headCameraPitchYawScale); gyroCameraSensitivity->setValue(_gyroCameraSensitivity);
form->addRow("Head Camera Pitch/Yaw Scale:", headCameraPitchYawScale); form->addRow("Gyro Camera Sensitivity (0 - 1):", gyroCameraSensitivity);
QDoubleSpinBox* leanScale = new QDoubleSpinBox(); QDoubleSpinBox* leanScale = new QDoubleSpinBox();
leanScale->setValue(_myAvatar.getLeanScale()); leanScale->setValue(_myAvatar.getLeanScale());
@ -1342,7 +1342,7 @@ void Application::editPreferences() {
_myAvatar.getVoxels()->setVoxelURL(url); _myAvatar.getVoxels()->setVoxelURL(url);
sendAvatarVoxelURLMessage(url); sendAvatarVoxelURLMessage(url);
_headCameraPitchYawScale = headCameraPitchYawScale->value(); _gyroCameraSensitivity = gyroCameraSensitivity->value();
_myAvatar.setLeanScale(leanScale->value()); _myAvatar.setLeanScale(leanScale->value());
_audioJitterBufferSamples = audioJitterBufferSamples->value(); _audioJitterBufferSamples = audioJitterBufferSamples->value();
if (!shouldDynamicallySetJitterBuffer()) { if (!shouldDynamicallySetJitterBuffer()) {
@ -2500,7 +2500,7 @@ void Application::update(float deltaTime) {
if (!avatar->isInitialized()) { if (!avatar->isInitialized()) {
avatar->init(); avatar->init();
} }
avatar->simulate(deltaTime, NULL); avatar->simulate(deltaTime, NULL, 0.f);
avatar->setMouseRay(mouseRayOrigin, mouseRayDirection); avatar->setMouseRay(mouseRayOrigin, mouseRayDirection);
} }
node->unlock(); node->unlock();
@ -2515,9 +2515,9 @@ void Application::update(float deltaTime) {
} }
if (_transmitterDrives->isChecked() && _myTransmitter.isConnected()) { if (_transmitterDrives->isChecked() && _myTransmitter.isConnected()) {
_myAvatar.simulate(deltaTime, &_myTransmitter); _myAvatar.simulate(deltaTime, &_myTransmitter, _gyroCameraSensitivity);
} else { } else {
_myAvatar.simulate(deltaTime, NULL); _myAvatar.simulate(deltaTime, NULL, _gyroCameraSensitivity);
} }
if (!OculusManager::isConnected()) { if (!OculusManager::isConnected()) {
@ -2584,9 +2584,6 @@ void Application::updateAvatar(float deltaTime) {
// Update my avatar's state from gyros and/or webcam // Update my avatar's state from gyros and/or webcam
_myAvatar.updateFromGyrosAndOrWebcam(_gyroLook->isChecked(), _myAvatar.updateFromGyrosAndOrWebcam(_gyroLook->isChecked(),
glm::vec3(_headCameraPitchYawScale,
_headCameraPitchYawScale,
_headCameraPitchYawScale),
_pitchFromTouch); _pitchFromTouch);
if (_serialHeadSensor.isActive()) { if (_serialHeadSensor.isActive()) {
@ -3951,11 +3948,11 @@ void Application::saveAction(QSettings* set, QAction* action) {
} }
void Application::loadSettings(QSettings* settings) { void Application::loadSettings(QSettings* settings) {
if (!settings) { if (!settings) {
settings = getSettings(); settings = getSettings();
} }
_headCameraPitchYawScale = loadSetting(settings, "headCameraPitchYawScale", 0.0f); _gyroCameraSensitivity = loadSetting(settings, "gyroCameraSensitivity", 0.5f);
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0); _audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
_horizontalFieldOfView = loadSetting(settings, "horizontalFieldOfView", HORIZONTAL_FIELD_OF_VIEW_DEGREES); _horizontalFieldOfView = loadSetting(settings, "horizontalFieldOfView", HORIZONTAL_FIELD_OF_VIEW_DEGREES);
@ -3979,7 +3976,7 @@ void Application::saveSettings(QSettings* settings) {
settings = getSettings(); settings = getSettings();
} }
settings->setValue("headCameraPitchYawScale", _headCameraPitchYawScale); settings->setValue("gyroCameraSensitivity", _gyroCameraSensitivity);
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples); settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
settings->setValue("horizontalFieldOfView", _horizontalFieldOfView); settings->setValue("horizontalFieldOfView", _horizontalFieldOfView);
settings->beginGroup("View Frustum Offset Camera"); settings->beginGroup("View Frustum Offset Camera");

View file

@ -358,7 +358,7 @@ private:
Environment _environment; Environment _environment;
int _headMouseX, _headMouseY; int _headMouseX, _headMouseY;
float _headCameraPitchYawScale; float _gyroCameraSensitivity;
int _audioJitterBufferSamples; // Number of extra samples to wait before starting audio playback int _audioJitterBufferSamples; // Number of extra samples to wait before starting audio playback

View file

@ -294,7 +294,6 @@ void Avatar::reset() {
// Update avatar head rotation with sensor data // Update avatar head rotation with sensor data
void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook, void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
const glm::vec3& amplifyAngle,
float pitchFromTouch) { float pitchFromTouch) {
_head.setMousePitch(pitchFromTouch); _head.setMousePitch(pitchFromTouch);
SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor(); SerialInterface* gyros = Application::getInstance()->getSerialHeadSensor();
@ -333,9 +332,15 @@ void Avatar::updateFromGyrosAndOrWebcam(bool gyroLook,
} else { } else {
_head.getFace().clearFrame(); _head.getFace().clearFrame();
} }
_head.setPitch(estimatedRotation.x * amplifyAngle.x);
_head.setYaw(estimatedRotation.y * amplifyAngle.y); // Set the rotation of the avatar's head (as seen by others, not affecting view frustum)
_head.setRoll(estimatedRotation.z * amplifyAngle.z); // 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); _head.setCameraFollowsHead(gyroLook);
// Update torso lean distance based on accelerometer data // 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 // 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 front = orientation * IDENTITY_FRONT;
glm::vec3 right = orientation * IDENTITY_RIGHT; glm::vec3 right = orientation * IDENTITY_RIGHT;
glm::vec3 up = orientation * IDENTITY_UP; 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::quat orientation = getOrientation();
glm::vec3 front = orientation * IDENTITY_FRONT; 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.setPosition(_bodyBall[ BODY_BALL_HEAD_BASE ].position);
_head.setScale(_scale); _head.setScale(_scale);
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _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()); _hand.simulate(deltaTime, isMyAvatar());

View file

@ -119,11 +119,10 @@ public:
void init(); void init();
void reset(); void reset();
void simulate(float deltaTime, Transmitter* transmitter); void simulate(float deltaTime, Transmitter* transmitter, float gyroCameraSensitivity);
void updateThrust(float deltaTime, Transmitter * transmitter); void updateThrust(float deltaTime, Transmitter * transmitter);
void follow(Avatar* leadingAvatar); void follow(Avatar* leadingAvatar);
void updateFromGyrosAndOrWebcam(bool gyroLook, void updateFromGyrosAndOrWebcam(bool gyroLook,
const glm::vec3& amplifyAngle,
float pitchFromTouch); float pitchFromTouch);
void addBodyYaw(float bodyYaw) {_bodyYaw += bodyYaw;}; void addBodyYaw(float bodyYaw) {_bodyYaw += bodyYaw;};
void addBodyYawDelta(float bodyYawDelta) {_bodyYawDelta += bodyYawDelta;} void addBodyYawDelta(float bodyYawDelta) {_bodyYawDelta += bodyYawDelta;}

View file

@ -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 // Update eye saccades
const float AVERAGE_MICROSACCADE_INTERVAL = 0.50f; 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) // 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 // 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. // to create stable rendering view with small head movements.
const float CAMERA_FOLLOW_HEAD_RATE_START = 0.01f; const float CAMERA_FOLLOW_HEAD_RATE_START = 0.1f;
const float CAMERA_FOLLOW_HEAD_RATE_MAX = 0.5f; const float CAMERA_FOLLOW_HEAD_RATE_MAX = 1.0f;
const float CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE = 1.05f; const float CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE = 1.05f;
const float CAMERA_STOP_TOLERANCE_DEGREES = 0.5f; const float CAMERA_STOP_TOLERANCE_DEGREES = 0.5f;
const float CAMERA_PITCH_START_TOLERANCE_DEGREES = 20.0f; const float PITCH_START_RANGE = 20.f;
const float CAMERA_YAW_START_TOLERANCE_DEGREES = 10.0f; 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)); float cameraHeadAngleDifference = glm::length(glm::vec2(_pitch - _cameraPitch, _yaw - _cameraYaw));
if (_isCameraMoving) { if (_isCameraMoving) {
_cameraFollowHeadRate = glm::clamp(_cameraFollowHeadRate * CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE, _cameraFollowHeadRate = glm::clamp(_cameraFollowHeadRate * CAMERA_FOLLOW_HEAD_RATE_RAMP_RATE,
@ -249,17 +252,13 @@ void Head::simulate(float deltaTime, bool isMine) {
_isCameraMoving = false; _isCameraMoving = false;
} }
} else { } else {
if ((fabs(_pitch - _cameraPitch) > CAMERA_PITCH_START_TOLERANCE_DEGREES) || if ((fabs(_pitch - _cameraPitch) > pitchStartTolerance) ||
(fabs(_yaw - _cameraYaw) > CAMERA_YAW_START_TOLERANCE_DEGREES)) { (fabs(_yaw - _cameraYaw) > yawStartTolerance)) {
_isCameraMoving = true; _isCameraMoving = true;
_cameraFollowHeadRate = CAMERA_FOLLOW_HEAD_RATE_START; _cameraFollowHeadRate = CAMERA_FOLLOW_HEAD_RATE_START;
} }
} }
} else { }
// Camera always locked to head
_cameraPitch = _pitch;
_cameraYaw = _yaw;
}
} }
void Head::calculateGeometry() { void Head::calculateGeometry() {

View file

@ -41,7 +41,7 @@ public:
void init(); void init();
void reset(); void reset();
void simulate(float deltaTime, bool isMine); void simulate(float deltaTime, bool isMine, float gyroCameraSensitivity);
void render(float alpha); void render(float alpha);
void renderMohawk(); void renderMohawk();