Added strafe and backward blending

This commit is contained in:
Anthony J. Thibault 2015-10-21 17:34:09 -07:00
parent 41cce4320a
commit c83af43d0e
3 changed files with 133 additions and 41 deletions

View file

@ -4,7 +4,7 @@
"id": "ikOverlay",
"type": "overlay",
"data": {
"alpha": 0.0,
"alpha": 1.0,
"boneSet": "fullBody"
},
"children": [
@ -532,8 +532,8 @@
"alpha": 0.0,
"sync": true,
"timeScale": 1.0,
"timeScaleVar": "walkTimeScale",
"alphaVar": "walkAlpha"
"timeScaleVar": "moveForwardTimeScale",
"alphaVar": "moveForwardAlpha"
},
"children": [
{
@ -576,16 +576,40 @@
},
{
"id": "walkBwd",
"type": "clip",
"type": "blendLinear",
"data": {
"url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_bwd.fbx",
"startFrame": 0.0,
"endFrame": 37.0,
"alpha": 1.0,
"sync": true,
"timeScale": 1.0,
"loopFlag": true,
"timeScaleVar": "walkTimeScale"
"timeScaleVar": "moveBackwardTimeScale",
"alphaVar": "moveBackwardAlpha"
},
"children": []
"children": [
{
"id": "walkBwdShort",
"type": "clip",
"data": {
"url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_short_bwd.fbx",
"startFrame": 0.0,
"endFrame": 38.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "walkBwdNormal",
"type": "clip",
"data": {
"url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_bwd.fbx",
"startFrame": 0.0,
"endFrame": 36.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "turnLeft",
@ -613,27 +637,77 @@
},
{
"id": "strafeLeft",
"type": "clip",
"type": "blendLinear",
"data": {
"url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"alpha": 0.0,
"sync": true,
"timeScale": 1.0,
"loopFlag": true
"timeScaleVar": "moveLateralTimeScale",
"alphaVar": "moveLateralAlpha"
},
"children": []
"children": [
{
"id": "strafeLeftShort",
"type": "clip",
"data": {
"url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 28.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftNormal",
"type": "clip",
"data": {
"url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "strafeRight",
"type": "clip",
"type": "blendLinear",
"data": {
"url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_right.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"alpha": 0.0,
"sync": true,
"timeScale": 1.0,
"loopFlag": true
"timeScaleVar": "moveLateralTimeScale",
"alphaVar": "moveLateralAlpha"
},
"children": []
"children": [
{
"id": "strafeRightShort",
"type": "clip",
"data": {
"url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_short_right.fbx",
"startFrame": 0.0,
"endFrame": 28.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeRightNormal",
"type": "clip",
"data": {
"url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_right.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
}
]
}

View file

@ -408,25 +408,20 @@ glm::mat4 Rig::getJointTransform(int jointIndex) const {
return _jointStates[jointIndex].getTransform();
}
void Rig::calcWalkForwardAlphaAndTimeScale(float speed, float* alphaOut, float* timeScaleOut) {
void Rig::calcAnimAlphaAndTimeScale(float speed, const std::vector<float>& referenceSpeeds, float* alphaOut, float* timeScaleOut) const {
// filter speed using a moving average.
_averageForwardSpeed.updateAverage(speed);
speed = _averageForwardSpeed.getAverage();
const int NUM_FWD_SPEEDS = 3;
float FWD_SPEEDS[NUM_FWD_SPEEDS] = { 0.3f, 1.4f, 2.7f }; // m/s
assert(referenceSpeeds.size() > 0);
// first calculate alpha by lerping between speeds.
float alpha = 0.0f;
if (speed <= FWD_SPEEDS[0]) {
if (speed <= referenceSpeeds.front()) {
alpha = 0.0f;
} else if (speed > FWD_SPEEDS[NUM_FWD_SPEEDS - 1]) {
alpha = (float)(NUM_FWD_SPEEDS - 1);
} else if (speed > referenceSpeeds.back()) {
alpha = (float)(referenceSpeeds.size() - 1);
} else {
for (int i = 0; i < NUM_FWD_SPEEDS - 1; i++) {
if (FWD_SPEEDS[i] < speed && speed < FWD_SPEEDS[i + 1]) {
alpha = (float)i + ((speed - FWD_SPEEDS[i]) / (FWD_SPEEDS[i + 1] - FWD_SPEEDS[i]));
for (size_t i = 0; i < referenceSpeeds.size() - 1; i++) {
if (referenceSpeeds[i] < speed && speed < referenceSpeeds[i + 1]) {
alpha = (float)i + ((speed - referenceSpeeds[i]) / (referenceSpeeds[i + 1] - referenceSpeeds[i]));
break;
}
}
@ -436,13 +431,18 @@ void Rig::calcWalkForwardAlphaAndTimeScale(float speed, float* alphaOut, float*
// NOTE: This makes the assumption that the velocity of a linear blend between two animations is also linear.
int prevIndex = glm::floor(alpha);
int nextIndex = glm::ceil(alpha);
float animSpeed = lerp(FWD_SPEEDS[prevIndex], FWD_SPEEDS[nextIndex], (float)glm::fract(alpha));
float animSpeed = lerp(referenceSpeeds[prevIndex], referenceSpeeds[nextIndex], (float)glm::fract(alpha));
float timeScale = glm::clamp(0.5f, 2.0f, speed / animSpeed);
*alphaOut = alpha;
*timeScaleOut = timeScale;
}
// animation reference speeds.
static const std::vector<float> FORWARD_SPEEDS = { 0.4f, 1.4f, 2.5f }; // m/s
static const std::vector<float> BACKWARD_SPEEDS = { 0.45f, 1.4f }; // m/s
static const std::vector<float> LATERAL_SPEEDS = { 0.2f, 0.65f }; // m/s
void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation) {
glm::vec3 front = worldRotation * IDENTITY_FRONT;
@ -468,15 +468,32 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
float lateralSpeed = glm::dot(localVel, IDENTITY_RIGHT);
float turningSpeed = glm::orientedAngle(front, _lastFront, IDENTITY_UP) / deltaTime;
// filter speeds using a simple moving average.
_averageForwardSpeed.updateAverage(forwardSpeed);
_averageLateralSpeed.updateAverage(lateralSpeed);
// sine wave LFO var for testing.
static float t = 0.0f;
_animVars.set("sine", 2.0f * static_cast<float>(0.5 * sin(t) + 0.5));
float walkAlpha, walkTimeScale;
calcWalkForwardAlphaAndTimeScale(glm::length(localVel), &walkAlpha, &walkTimeScale);
float moveForwardAlpha = 0.0f;
float moveForwardTimeScale = 1.0f;
float moveBackwardAlpha = 0.0f;
float moveBackwardTimeScale = 1.0f;
float moveLateralAlpha = 0.0f;
float moveLateralTimeScale = 1.0f;
_animVars.set("walkTimeScale", walkTimeScale);
_animVars.set("walkAlpha", walkAlpha);
// calcuate the animation alpha and timeScale values based on current speeds and animation reference speeds.
calcAnimAlphaAndTimeScale(_averageForwardSpeed.getAverage(), FORWARD_SPEEDS, &moveForwardAlpha, &moveForwardTimeScale);
calcAnimAlphaAndTimeScale(-_averageForwardSpeed.getAverage(), BACKWARD_SPEEDS, &moveBackwardAlpha, &moveBackwardTimeScale);
calcAnimAlphaAndTimeScale(fabsf(_averageLateralSpeed.getAverage()), LATERAL_SPEEDS, &moveLateralAlpha, &moveLateralTimeScale);
_animVars.set("moveFowardTimeScale", moveForwardTimeScale);
_animVars.set("moveForwardAlpha", moveForwardAlpha);
_animVars.set("moveBackwardTimeScale", moveBackwardTimeScale);
_animVars.set("moveBackwardAlpha", moveBackwardAlpha);
_animVars.set("moveLateralTimeScale", moveLateralTimeScale);
_animVars.set("moveLateralAlpha", moveLateralAlpha);
const float MOVE_ENTER_SPEED_THRESHOLD = 0.2f; // m/sec
const float MOVE_EXIT_SPEED_THRESHOLD = 0.07f; // m/sec

View file

@ -208,7 +208,7 @@ public:
void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
void updateNeckJoint(int index, const HeadParameters& params);
void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade);
void calcWalkForwardAlphaAndTimeScale(float speed, float* alphaOut, float* timeScaleOut);
void calcAnimAlphaAndTimeScale(float speed, const std::vector<float>& referenceSpeeds, float* alphaOut, float* timeScaleOut) const;
QVector<JointState> _jointStates;
int _rootJointIndex = -1;
@ -245,6 +245,7 @@ public:
float _rightHandOverlayAlpha = 0.0f;
SimpleMovingAverage _averageForwardSpeed{ 25 };
SimpleMovingAverage _averageLateralSpeed{ 25 };
};
#endif /* defined(__hifi__Rig__) */