mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 21:29:33 +02:00
Fix for jerky behavior when positionDelta is zero.
This can occur with vsync disabled. Possibly due to two avatar updates occurring within a single physics time-step.
This commit is contained in:
parent
de31b92fd5
commit
471400e595
1 changed files with 14 additions and 24 deletions
|
@ -419,12 +419,21 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
|
|
||||||
glm::vec3 front = worldRotation * IDENTITY_FRONT;
|
glm::vec3 front = worldRotation * IDENTITY_FRONT;
|
||||||
|
|
||||||
|
// It can be more accurate/smooth to use velocity rather than position,
|
||||||
|
// but some modes (e.g., hmd standing) update position without updating velocity.
|
||||||
|
// It's very hard to debug hmd standing. (Look down at yourself, or have a second person observe. HMD third person is a bit undefined...)
|
||||||
|
// So, let's create our own workingVelocity from the worldPosition...
|
||||||
|
glm::vec3 positionDelta = worldPosition - _lastPosition;
|
||||||
|
glm::vec3 workingVelocity = positionDelta / deltaTime;
|
||||||
|
|
||||||
|
// But for smoothest (non-hmd standing) results, go ahead and use velocity:
|
||||||
|
if (!positionDelta.x && !positionDelta.y && !positionDelta.z) {
|
||||||
|
workingVelocity = worldVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
if (_enableAnimGraph) {
|
if (_enableAnimGraph) {
|
||||||
|
|
||||||
// at the moment worldVelocity comes from the Avatar physics body, which is not always correct when
|
glm::vec3 localVel = glm::inverse(worldRotation) * workingVelocity;
|
||||||
// moving in the HMD, so let's compute our own veloicty.
|
|
||||||
glm::vec3 worldVel = (worldPosition - _lastPosition) / deltaTime;
|
|
||||||
glm::vec3 localVel = glm::inverse(worldRotation) * worldVel;
|
|
||||||
float forwardSpeed = glm::dot(localVel, IDENTITY_FRONT);
|
float forwardSpeed = glm::dot(localVel, IDENTITY_FRONT);
|
||||||
float lateralSpeed = glm::dot(localVel, IDENTITY_RIGHT);
|
float lateralSpeed = glm::dot(localVel, IDENTITY_RIGHT);
|
||||||
float turningSpeed = glm::orientedAngle(front, _lastFront, IDENTITY_UP) / deltaTime;
|
float turningSpeed = glm::orientedAngle(front, _lastFront, IDENTITY_UP) / deltaTime;
|
||||||
|
@ -496,20 +505,9 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
glm::vec3 right = worldRotation * IDENTITY_RIGHT;
|
glm::vec3 right = worldRotation * IDENTITY_RIGHT;
|
||||||
const float PERCEPTIBLE_DELTA = 0.001f;
|
const float PERCEPTIBLE_DELTA = 0.001f;
|
||||||
const float PERCEPTIBLE_SPEED = 0.1f;
|
const float PERCEPTIBLE_SPEED = 0.1f;
|
||||||
// It can be more accurate/smooth to use velocity rather than position,
|
|
||||||
// but some modes (e.g., hmd standing) update position without updating velocity.
|
|
||||||
// It's very hard to debug hmd standing. (Look down at yourself, or have a second person observe. HMD third person is a bit undefined...)
|
|
||||||
// So, let's create our own workingVelocity from the worldPosition...
|
|
||||||
glm::vec3 positionDelta = worldPosition - _lastPosition;
|
|
||||||
glm::vec3 workingVelocity = positionDelta / deltaTime;
|
|
||||||
// But for smoothest (non-hmd standing) results, go ahead and use velocity:
|
|
||||||
#if !WANT_DEBUG
|
|
||||||
// Note: Separately, we've arranged for starting/stopping animations by role (as we've done here) to pick up where they've left off when fading,
|
// Note: Separately, we've arranged for starting/stopping animations by role (as we've done here) to pick up where they've left off when fading,
|
||||||
// so that you wouldn't notice the start/stop if it happens fast enough (e.g., one frame). But the print below would still be noisy.
|
// so that you wouldn't notice the start/stop if it happens fast enough (e.g., one frame). But the print below would still be noisy.
|
||||||
if (!positionDelta.x && !positionDelta.y && !positionDelta.z) {
|
|
||||||
workingVelocity = worldVelocity;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float forwardSpeed = glm::dot(workingVelocity, front);
|
float forwardSpeed = glm::dot(workingVelocity, front);
|
||||||
float rightLateralSpeed = glm::dot(workingVelocity, right);
|
float rightLateralSpeed = glm::dot(workingVelocity, right);
|
||||||
|
@ -1001,19 +999,11 @@ void Rig::initAnimGraph(const QUrl& url, const FBXGeometry& fbxGeometry) {
|
||||||
AnimPose geometryOffset(fbxGeometry.offset);
|
AnimPose geometryOffset(fbxGeometry.offset);
|
||||||
_animSkeleton = std::make_shared<AnimSkeleton>(joints, geometryOffset);
|
_animSkeleton = std::make_shared<AnimSkeleton>(joints, geometryOffset);
|
||||||
|
|
||||||
// add skeleton to the debug renderer, so we can see it.
|
|
||||||
// AnimDebugDraw::getInstance().addSkeleton("my-avatar-skeleton", _animSkeleton, AnimPose::identity);
|
|
||||||
// _animSkeleton->dump();
|
|
||||||
|
|
||||||
// load the anim graph
|
// load the anim graph
|
||||||
_animLoader.reset(new AnimNodeLoader(url));
|
_animLoader.reset(new AnimNodeLoader(url));
|
||||||
connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) {
|
connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) {
|
||||||
_animNode = nodeIn;
|
_animNode = nodeIn;
|
||||||
_animNode->setSkeleton(_animSkeleton);
|
_animNode->setSkeleton(_animSkeleton);
|
||||||
|
|
||||||
// add node to debug renderer, for debugging
|
|
||||||
// AnimPose xform(glm::vec3(1), glm::quat(), glm::vec3(0, 0, -1));
|
|
||||||
// AnimDebugDraw::getInstance().addAnimNode("my-avatar-animation", _animNode, xform);
|
|
||||||
});
|
});
|
||||||
connect(_animLoader.get(), &AnimNodeLoader::error, [this, url](int error, QString str) {
|
connect(_animLoader.get(), &AnimNodeLoader::error, [this, url](int error, QString str) {
|
||||||
qCCritical(animation) << "Error loading" << url.toDisplayString() << "code = " << error << "str =" << str;
|
qCCritical(animation) << "Error loading" << url.toDisplayString() << "code = " << error << "str =" << str;
|
||||||
|
|
Loading…
Reference in a new issue