Wiring step yaw to the avatar

This commit is contained in:
Brad Davis 2015-10-21 20:44:38 -07:00
parent 637654adea
commit 044a28212d
5 changed files with 78 additions and 96 deletions

View file

@ -27,7 +27,8 @@ HifiControls.VrDialog {
testMapping = Controller.newMapping(); testMapping = Controller.newMapping();
testMapping.from(standard.RY).invert().to(actions.Pitch); testMapping.from(standard.RY).invert().to(actions.Pitch);
testMapping.makeAxis(standard.LB, standard.RB).to(actions.Yaw); testMapping.makeAxis(standard.LB, standard.RB).to(actions.Yaw);
testMapping.from(standard.RX).to(actions.StepYaw); // Step yaw takes a number of degrees
testMapping.from(standard.RX).scale(15.0).to(actions.StepYaw);
} }
function toggleMapping() { function toggleMapping() {

View file

@ -2718,15 +2718,13 @@ void Application::update(float deltaTime) {
} }
// Transfer the user inputs to the driveKeys // Transfer the user inputs to the driveKeys
// FIXME can we drop drive keys and just have the avatar read the action states directly?
myAvatar->clearDriveKeys(); myAvatar->clearDriveKeys();
if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) { if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
if (!_controllerScriptingInterface->areActionsCaptured()) { if (!_controllerScriptingInterface->areActionsCaptured()) {
myAvatar->setDriveKeys(FWD, userInputMapper->getActionState(controller::Action::LONGITUDINAL_FORWARD)); myAvatar->setDriveKeys(TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z));
myAvatar->setDriveKeys(BACK, userInputMapper->getActionState(controller::Action::LONGITUDINAL_BACKWARD)); myAvatar->setDriveKeys(TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y));
myAvatar->setDriveKeys(UP, userInputMapper->getActionState(controller::Action::VERTICAL_UP)); myAvatar->setDriveKeys(TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X));
myAvatar->setDriveKeys(DOWN, userInputMapper->getActionState(controller::Action::VERTICAL_DOWN));
myAvatar->setDriveKeys(LEFT, userInputMapper->getActionState(controller::Action::LATERAL_LEFT));
myAvatar->setDriveKeys(RIGHT, userInputMapper->getActionState(controller::Action::LATERAL_RIGHT));
if (deltaTime > FLT_EPSILON) { if (deltaTime > FLT_EPSILON) {
// For rotations what we really want are meausures of "angles per second" (in order to prevent // For rotations what we really want are meausures of "angles per second" (in order to prevent
// fps-dependent spin rates) so we need to scale the units of the controller contribution. // fps-dependent spin rates) so we need to scale the units of the controller contribution.
@ -2734,14 +2732,12 @@ void Application::update(float deltaTime) {
// controllers to provide a delta_per_second value rather than a raw delta.) // controllers to provide a delta_per_second value rather than a raw delta.)
const float EXPECTED_FRAME_RATE = 60.0f; const float EXPECTED_FRAME_RATE = 60.0f;
float timeFactor = EXPECTED_FRAME_RATE * deltaTime; float timeFactor = EXPECTED_FRAME_RATE * deltaTime;
myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(controller::Action::PITCH_UP) / timeFactor); myAvatar->setDriveKeys(PITCH, userInputMapper->getActionState(controller::Action::PITCH) / timeFactor);
myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(controller::Action::PITCH_DOWN) / timeFactor); myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW) / timeFactor);
myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(controller::Action::YAW_LEFT) / timeFactor); myAvatar->setDriveKeys(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW) / timeFactor);
myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(controller::Action::YAW_RIGHT) / timeFactor);
} }
} }
myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(controller::Action::BOOM_IN)); myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z));
myAvatar->setDriveKeys(BOOM_OUT, userInputMapper->getActionState(controller::Action::BOOM_OUT));
} }
controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_HAND); controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_HAND);
controller::Pose rightHand = userInputMapper->getPoseState(controller::Action::RIGHT_HAND); controller::Pose rightHand = userInputMapper->getPoseState(controller::Action::RIGHT_HAND);

View file

@ -43,21 +43,6 @@ static const float BILLBOARD_DISTANCE = 5.56f; // meters
extern const float CHAT_MESSAGE_SCALE; extern const float CHAT_MESSAGE_SCALE;
extern const float CHAT_MESSAGE_HEIGHT; extern const float CHAT_MESSAGE_HEIGHT;
enum DriveKeys {
FWD = 0,
BACK,
LEFT,
RIGHT,
UP,
DOWN,
ROT_LEFT,
ROT_RIGHT,
ROT_UP,
ROT_DOWN,
BOOM_IN,
BOOM_OUT,
MAX_DRIVE_KEYS
};
enum ScreenTintLayer { enum ScreenTintLayer {
SCREEN_TINT_BEFORE_LANDSCAPE = 0, SCREEN_TINT_BEFORE_LANDSCAPE = 0,

View file

@ -242,6 +242,7 @@ void MyAvatar::simulate(float deltaTime) {
PerformanceTimer perfTimer("transform"); PerformanceTimer perfTimer("transform");
updateOrientation(deltaTime); updateOrientation(deltaTime);
updatePosition(deltaTime); updatePosition(deltaTime);
_lastStepPulse = _thisStepPulse;
} }
{ {
@ -1552,17 +1553,11 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
!cameraInsideHead()); !cameraInsideHead());
} }
static quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per half second
void MyAvatar::updateOrientation(float deltaTime) { void MyAvatar::updateOrientation(float deltaTime) {
// Smoothly rotate body with arrow keys // Smoothly rotate body with arrow keys
float targetSpeed = 0.0f; float targetSpeed = _driveKeys[YAW] * YAW_SPEED;
// FIXME - this comfort mode code is a total hack, remove it when we have new input mapping
bool isComfortMode = Menu::getInstance()->isOptionChecked(MenuOption::ComfortMode);
bool isHMDMode = qApp->getAvatarUpdater()->isHMDMode();
if (!isHMDMode || !isComfortMode) {
targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED;
if (targetSpeed != 0.0f) { if (targetSpeed != 0.0f) {
const float ROTATION_RAMP_TIMESCALE = 0.1f; const float ROTATION_RAMP_TIMESCALE = 0.1f;
float blend = deltaTime / ROTATION_RAMP_TIMESCALE; float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
@ -1585,38 +1580,22 @@ void MyAvatar::updateOrientation(float deltaTime) {
} }
} }
// update body orientation by movement inputs float totalBodyYaw = _bodyYawDelta * deltaTime;
setOrientation(getOrientation() *
glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f))));
} else {
// Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll // Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll
// get an instantaneous 15 degree turn. If you keep holding the key down you'll get another // get an instantaneous 15 degree turn. If you keep holding the key down you'll get another
// snap turn every half second. // snap turn every half second.
_bodyYawDelta = 0.0f;
static quint64 lastPulse = 0;
quint64 now = usecTimestampNow(); quint64 now = usecTimestampNow();
quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per half second if (_driveKeys[STEP_YAW] != 0.0f && now - _lastStepPulse > COMFORT_MODE_PULSE_TIMING) {
_thisStepPulse = now;
float driveLeft = _driveKeys[ROT_LEFT]; totalBodyYaw += _driveKeys[STEP_YAW];
float driveRight= _driveKeys[ROT_RIGHT]; }
if ((driveLeft != 0.0f || driveRight != 0.0f) && (now - lastPulse > COMFORT_MODE_PULSE_TIMING)) {
lastPulse = now;
const float SNAP_TURN_DELTA = 15.0f; // degrees
float direction = (driveLeft - driveRight) < 0.0f ? -1.0f : 1.0f;
float turnAmount = direction * SNAP_TURN_DELTA;
// update body orientation by movement inputs // update body orientation by movement inputs
setOrientation(getOrientation() * setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f))));
glm::quat(glm::radians(glm::vec3(0.0f, turnAmount, 0.0f))));
} getHead()->setBasePitch(getHead()->getBasePitch() + _driveKeys[PITCH] * PITCH_SPEED * deltaTime);
}
getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime);
if (qApp->getAvatarUpdater()->isHMDMode()) { if (qApp->getAvatarUpdater()->isHMDMode()) {
glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation(); glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation();
@ -1676,15 +1655,20 @@ glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVe
float motorEfficiency = glm::clamp(deltaTime / timescale, 0.0f, 1.0f); float motorEfficiency = glm::clamp(deltaTime / timescale, 0.0f, 1.0f);
glm::vec3 newLocalVelocity = localVelocity; glm::vec3 newLocalVelocity = localVelocity;
float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) + float stepControllerInput = fabsf(_driveKeys[STEP_TRANSLATE_Z]) + fabsf(_driveKeys[STEP_TRANSLATE_Z]) + fabsf(_driveKeys[STEP_TRANSLATE_Z]);
(fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT])) + quint64 now = usecTimestampNow();
fabsf(_driveKeys[UP] - _driveKeys[DOWN]); if (stepControllerInput && now - _lastStepPulse > COMFORT_MODE_PULSE_TIMING) {
if (keyboardInput) { _thisStepPulse = now;
// Compute keyboard input }
glm::vec3 front = (_driveKeys[FWD] - _driveKeys[BACK]) * IDENTITY_FRONT;
glm::vec3 right = (_driveKeys[RIGHT] - _driveKeys[LEFT]) * IDENTITY_RIGHT;
glm::vec3 up = (_driveKeys[UP] - _driveKeys[DOWN]) * IDENTITY_UP;
float keyboardInput = fabsf(_driveKeys[TRANSLATE_Z]) + fabsf(_driveKeys[TRANSLATE_X]) + fabsf(_driveKeys[TRANSLATE_Y]);
if (keyboardInput || (_thisStepPulse == now)) {
// Compute keyboard input
glm::vec3 front = (_driveKeys[TRANSLATE_Z]) * IDENTITY_FRONT;
glm::vec3 right = (_driveKeys[TRANSLATE_X]) * IDENTITY_RIGHT;
glm::vec3 up = (_driveKeys[TRANSLATE_Y]) * IDENTITY_UP;
// FIXME how do I implement step translation as well?
glm::vec3 direction = front + right + up; glm::vec3 direction = front + right + up;
float directionLength = glm::length(direction); float directionLength = glm::length(direction);
@ -1734,7 +1718,7 @@ glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVe
} }
} }
float boomChange = _driveKeys[BOOM_OUT] - _driveKeys[BOOM_IN]; float boomChange = _driveKeys[ZOOM];
_boomLength += 2.0f * _boomLength * boomChange + boomChange * boomChange; _boomLength += 2.0f * _boomLength * boomChange + boomChange * boomChange;
_boomLength = glm::clamp<float>(_boomLength, ZOOM_MIN, ZOOM_MAX); _boomLength = glm::clamp<float>(_boomLength, ZOOM_MIN, ZOOM_MAX);
@ -1983,7 +1967,7 @@ void MyAvatar::clearDriveKeys() {
} }
void MyAvatar::relayDriveKeysToCharacterController() { void MyAvatar::relayDriveKeysToCharacterController() {
if (_driveKeys[UP] > 0.0f) { if (_driveKeys[TRANSLATE_Y] > 0.0f) {
_characterController.jump(); _characterController.jump();
} }
} }

View file

@ -21,6 +21,20 @@
class ModelItemID; class ModelItemID;
enum DriveKeys {
TRANSLATE_X = 0,
TRANSLATE_Y,
TRANSLATE_Z,
YAW,
STEP_TRANSLATE_X,
STEP_TRANSLATE_Y,
STEP_TRANSLATE_Z,
STEP_YAW,
PITCH,
ZOOM,
MAX_DRIVE_KEYS
};
enum eyeContactTarget { enum eyeContactTarget {
LEFT_EYE, LEFT_EYE,
RIGHT_EYE, RIGHT_EYE,
@ -376,6 +390,8 @@ private:
AtRestDetector _hmdAtRestDetector; AtRestDetector _hmdAtRestDetector;
glm::vec3 _lastPosition; glm::vec3 _lastPosition;
bool _lastIsMoving = false; bool _lastIsMoving = false;
quint64 _lastStepPulse = 0;
quint64 _thisStepPulse = 0;
}; };
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);