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.from(standard.RY).invert().to(actions.Pitch);
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() {

View file

@ -2718,15 +2718,13 @@ void Application::update(float deltaTime) {
}
// 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();
if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
if (!_controllerScriptingInterface->areActionsCaptured()) {
myAvatar->setDriveKeys(FWD, userInputMapper->getActionState(controller::Action::LONGITUDINAL_FORWARD));
myAvatar->setDriveKeys(BACK, userInputMapper->getActionState(controller::Action::LONGITUDINAL_BACKWARD));
myAvatar->setDriveKeys(UP, userInputMapper->getActionState(controller::Action::VERTICAL_UP));
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));
myAvatar->setDriveKeys(TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z));
myAvatar->setDriveKeys(TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y));
myAvatar->setDriveKeys(TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X));
if (deltaTime > FLT_EPSILON) {
// 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.
@ -2734,14 +2732,12 @@ void Application::update(float deltaTime) {
// controllers to provide a delta_per_second value rather than a raw delta.)
const float EXPECTED_FRAME_RATE = 60.0f;
float timeFactor = EXPECTED_FRAME_RATE * deltaTime;
myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(controller::Action::PITCH_UP) / timeFactor);
myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(controller::Action::PITCH_DOWN) / timeFactor);
myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(controller::Action::YAW_LEFT) / timeFactor);
myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(controller::Action::YAW_RIGHT) / timeFactor);
myAvatar->setDriveKeys(PITCH, userInputMapper->getActionState(controller::Action::PITCH) / timeFactor);
myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW) / timeFactor);
myAvatar->setDriveKeys(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW) / timeFactor);
}
}
myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(controller::Action::BOOM_IN));
myAvatar->setDriveKeys(BOOM_OUT, userInputMapper->getActionState(controller::Action::BOOM_OUT));
myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z));
}
controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_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_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 {
SCREEN_TINT_BEFORE_LANDSCAPE = 0,

View file

@ -242,6 +242,7 @@ void MyAvatar::simulate(float deltaTime) {
PerformanceTimer perfTimer("transform");
updateOrientation(deltaTime);
updatePosition(deltaTime);
_lastStepPulse = _thisStepPulse;
}
{
@ -1552,71 +1553,49 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
!cameraInsideHead());
}
static quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per half second
void MyAvatar::updateOrientation(float deltaTime) {
// Smoothly rotate body with arrow keys
float targetSpeed = 0.0f;
// 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) {
const float ROTATION_RAMP_TIMESCALE = 0.1f;
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
if (blend > 1.0f) {
blend = 1.0f;
}
_bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed;
} else if (_bodyYawDelta != 0.0f) {
// attenuate body rotation speed
const float ROTATION_DECAY_TIMESCALE = 0.05f;
float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE;
if (attenuation < 0.0f) {
attenuation = 0.0f;
}
_bodyYawDelta *= attenuation;
float MINIMUM_ROTATION_RATE = 2.0f;
if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) {
_bodyYawDelta = 0.0f;
}
float targetSpeed = _driveKeys[YAW] * YAW_SPEED;
if (targetSpeed != 0.0f) {
const float ROTATION_RAMP_TIMESCALE = 0.1f;
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
if (blend > 1.0f) {
blend = 1.0f;
}
_bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed;
} else if (_bodyYawDelta != 0.0f) {
// attenuate body rotation speed
const float ROTATION_DECAY_TIMESCALE = 0.05f;
float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE;
if (attenuation < 0.0f) {
attenuation = 0.0f;
}
_bodyYawDelta *= attenuation;
// update body orientation by movement inputs
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
// get an instantaneous 15 degree turn. If you keep holding the key down you'll get another
// snap turn every half second.
_bodyYawDelta = 0.0f;
static quint64 lastPulse = 0;
quint64 now = usecTimestampNow();
quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per half second
float driveLeft = _driveKeys[ROT_LEFT];
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
setOrientation(getOrientation() *
glm::quat(glm::radians(glm::vec3(0.0f, turnAmount, 0.0f))));
float MINIMUM_ROTATION_RATE = 2.0f;
if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) {
_bodyYawDelta = 0.0f;
}
}
getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime);
float totalBodyYaw = _bodyYawDelta * deltaTime;
// 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
// snap turn every half second.
quint64 now = usecTimestampNow();
if (_driveKeys[STEP_YAW] != 0.0f && now - _lastStepPulse > COMFORT_MODE_PULSE_TIMING) {
_thisStepPulse = now;
totalBodyYaw += _driveKeys[STEP_YAW];
}
// update body orientation by movement inputs
setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f))));
getHead()->setBasePitch(getHead()->getBasePitch() + _driveKeys[PITCH] * PITCH_SPEED * deltaTime);
if (qApp->getAvatarUpdater()->isHMDMode()) {
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);
glm::vec3 newLocalVelocity = localVelocity;
float keyboardInput = fabsf(_driveKeys[FWD] - _driveKeys[BACK]) +
(fabsf(_driveKeys[RIGHT] - _driveKeys[LEFT])) +
fabsf(_driveKeys[UP] - _driveKeys[DOWN]);
if (keyboardInput) {
// 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 stepControllerInput = fabsf(_driveKeys[STEP_TRANSLATE_Z]) + fabsf(_driveKeys[STEP_TRANSLATE_Z]) + fabsf(_driveKeys[STEP_TRANSLATE_Z]);
quint64 now = usecTimestampNow();
if (stepControllerInput && now - _lastStepPulse > COMFORT_MODE_PULSE_TIMING) {
_thisStepPulse = now;
}
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;
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 = glm::clamp<float>(_boomLength, ZOOM_MIN, ZOOM_MAX);
@ -1983,7 +1967,7 @@ void MyAvatar::clearDriveKeys() {
}
void MyAvatar::relayDriveKeysToCharacterController() {
if (_driveKeys[UP] > 0.0f) {
if (_driveKeys[TRANSLATE_Y] > 0.0f) {
_characterController.jump();
}
}

View file

@ -21,6 +21,20 @@
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 {
LEFT_EYE,
RIGHT_EYE,
@ -376,6 +390,8 @@ private:
AtRestDetector _hmdAtRestDetector;
glm::vec3 _lastPosition;
bool _lastIsMoving = false;
quint64 _lastStepPulse = 0;
quint64 _thisStepPulse = 0;
};
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);