mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 04:37:59 +02:00
Merge pull request #796 from PhilipRosedale/touchLook
Tune gyros, always fly in direction of sight, head always moves with gyros, adjustable view sensitivity
This commit is contained in:
commit
05452dc2aa
6 changed files with 37 additions and 37 deletions
|
@ -1299,9 +1299,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());
|
||||||
|
@ -1351,7 +1351,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()) {
|
||||||
|
@ -2564,7 +2564,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();
|
||||||
|
@ -2579,9 +2579,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()) {
|
||||||
|
@ -2648,9 +2648,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()) {
|
||||||
|
@ -4089,11 +4086,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);
|
||||||
|
|
||||||
|
@ -4117,7 +4114,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");
|
||||||
|
|
|
@ -366,7 +366,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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -502,7 +507,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;
|
||||||
|
@ -752,7 +757,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());
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue