mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Avatar snap-turn rotation smoothing (sent out from the local client outward).
This commit is contained in:
parent
2963d3d212
commit
53f47c132f
3 changed files with 51 additions and 2 deletions
|
@ -375,6 +375,10 @@ void MyAvatar::update(float deltaTime) {
|
|||
float tau = deltaTime / HMD_FACING_TIMESCALE;
|
||||
_hmdSensorFacingMovingAverage = lerp(_hmdSensorFacingMovingAverage, _hmdSensorFacing, tau);
|
||||
|
||||
if (_smoothOrientationTimer < _smoothOrientationTime) {
|
||||
_smoothOrientationTimer = min(_smoothOrientationTimer + deltaTime, _smoothOrientationTime);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE
|
||||
glm::vec3 p = transformPoint(getSensorToWorldMatrix(), _hmdSensorPosition + glm::vec3(_hmdSensorFacingMovingAverage.x, 0.0f, _hmdSensorFacingMovingAverage.y));
|
||||
DebugDraw::getInstance().addMarker("facing-avg", getOrientation(), p, glm::vec4(1.0f));
|
||||
|
@ -1742,8 +1746,10 @@ void MyAvatar::updateOrientation(float 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.
|
||||
bool snapTurn = false;
|
||||
if (getDriveKey(STEP_YAW) != 0.0f) {
|
||||
totalBodyYaw += getDriveKey(STEP_YAW);
|
||||
snapTurn = true;
|
||||
}
|
||||
|
||||
// use head/HMD orientation to turn while flying
|
||||
|
@ -1776,10 +1782,17 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
totalBodyYaw += (speedFactor * deltaAngle * (180.0f / PI));
|
||||
}
|
||||
|
||||
|
||||
// update body orientation by movement inputs
|
||||
glm::quat initialOrientation = getOrientation();
|
||||
setOrientation(getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, totalBodyYaw, 0.0f))));
|
||||
|
||||
if (snapTurn) {
|
||||
// Whether or not there is an existing smoothing going on, just reset the smoothing timer and set the starting position as the avatar's current position, then smooth to the new position.
|
||||
_smoothOrientationInitial = initialOrientation;
|
||||
_smoothOrientationTarget = getOrientation();
|
||||
_smoothOrientationTimer = 0.0f;
|
||||
}
|
||||
|
||||
getHead()->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime);
|
||||
|
||||
if (qApp->isHMDMode()) {
|
||||
|
|
|
@ -67,7 +67,11 @@ AvatarData::AvatarData() :
|
|||
_displayNameAlpha(1.0f),
|
||||
_errorLogExpiry(0),
|
||||
_owningAvatarMixer(),
|
||||
_targetVelocity(0.0f)
|
||||
_targetVelocity(0.0f),
|
||||
_smoothOrientationTime(SMOOTH_TIME_ORIENTATION),
|
||||
_smoothOrientationTimer(std::numeric_limits<float>::max()),
|
||||
_smoothOrientationInitial(),
|
||||
_smoothOrientationTarget()
|
||||
{
|
||||
setBodyPitch(0.0f);
|
||||
setBodyYaw(-90.0f);
|
||||
|
@ -1460,6 +1464,17 @@ void AvatarData::parseAvatarIdentityPacket(const QByteArray& data, Identity& ide
|
|||
packetStream >> identityOut.uuid >> identityOut.skeletonModelURL >> identityOut.attachmentData >> identityOut.displayName >> identityOut.sessionDisplayName >> identityOut.avatarEntityData;
|
||||
}
|
||||
|
||||
glm::quat AvatarData::getLocalOrientation() const {
|
||||
if (!isMyAvatar() || (_smoothOrientationTimer > _smoothOrientationTime)) {
|
||||
return (SpatiallyNestable::getLocalOrientation());
|
||||
}
|
||||
|
||||
// Smooth the remote avatar movement.
|
||||
float t = _smoothOrientationTimer / _smoothOrientationTime;
|
||||
float l = easeInOutQuad(glm::clamp(t, 0.0f, 1.0f));
|
||||
return (slerp(_smoothOrientationInitial, _smoothOrientationTarget, l));
|
||||
}
|
||||
|
||||
static const QUrl emptyURL("");
|
||||
QUrl AvatarData::cannonicalSkeletonModelURL(const QUrl& emptyURL) const {
|
||||
// We don't put file urls on the wire, but instead convert to empty.
|
||||
|
|
|
@ -603,6 +603,9 @@ public:
|
|||
|
||||
bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_UPDATE_TIMEOUT; }
|
||||
|
||||
// Overload the local orientation function for this.
|
||||
virtual glm::quat getLocalOrientation() const override;
|
||||
|
||||
static const float OUT_OF_VIEW_PENALTY;
|
||||
|
||||
static void sortAvatars(
|
||||
|
@ -619,7 +622,16 @@ public:
|
|||
static float _avatarSortCoefficientCenter;
|
||||
static float _avatarSortCoefficientAge;
|
||||
|
||||
// Basic ease-in-ease-out function for smoothing values.
|
||||
static inline float easeInOutQuad(float lerpValue) {
|
||||
assert(!((lerpValue < 0.0f) || (lerpValue > 1.0f)));
|
||||
|
||||
if (lerpValue < 0.5f) {
|
||||
return (2.0f * lerpValue * lerpValue);
|
||||
}
|
||||
|
||||
return (lerpValue*(4.0f - 2.0f * lerpValue) - 1.0f);
|
||||
}
|
||||
|
||||
signals:
|
||||
void displayNameChanged();
|
||||
|
@ -778,6 +790,15 @@ protected:
|
|||
quint64 _audioLoudnessChanged { 0 };
|
||||
float _audioAverageLoudness { 0.0f };
|
||||
|
||||
// Smoothing.
|
||||
const float SMOOTH_TIME_ORIENTATION = 0.15f;
|
||||
|
||||
// Smoothing data for blending from one position/orientation to another on remote agents.
|
||||
float _smoothOrientationTime;
|
||||
float _smoothOrientationTimer;
|
||||
glm::quat _smoothOrientationInitial;
|
||||
glm::quat _smoothOrientationTarget;
|
||||
|
||||
private:
|
||||
friend void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar);
|
||||
static QUrl _defaultFullAvatarModelUrl;
|
||||
|
|
Loading…
Reference in a new issue