mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 18:23:22 +02:00
Wiring step yaw to the avatar
This commit is contained in:
parent
637654adea
commit
044a28212d
5 changed files with 78 additions and 96 deletions
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue