Merge pull request #13655 from amantley/animationBlendChanges

New Default Strafe Animations Plus Animation Tuning Support
This commit is contained in:
John Conklin II 2018-08-10 15:03:30 -07:00 committed by GitHub
commit 644ff1eafa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 584 additions and 120 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -585,8 +585,9 @@
"states": [
{
"id": "idle",
"interpTarget": 10,
"interpDuration": 10,
"interpTarget": 0,
"interpDuration": 4,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isMovingForward", "state": "idleToWalkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
@ -598,13 +599,16 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "idleToWalkFwd",
"interpTarget": 3,
"interpDuration": 3,
"interpTarget": 10,
"interpDuration": 4,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "idleToWalkFwdOnDone", "state": "walkFwd" },
{ "var": "isNotMoving", "state": "idle" },
@ -617,6 +621,30 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "idleSettle",
"interpTarget": 10,
"interpDuration": 10,
"interpType": "snapshotPrev",
"transitions": [
{"var": "idleSettleOnDone", "state": "idle" },
{"var": "isMovingForward", "state": "idleToWalkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" },
{ "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isFlying", "state": "fly" },
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
]
},
@ -624,8 +652,9 @@
"id": "walkFwd",
"interpTarget": 16,
"interpDuration": 6,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idle" },
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
@ -635,15 +664,18 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "walkBwd",
"interpTarget": 6,
"interpTarget": 8,
"interpDuration": 6,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idle" },
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
@ -653,15 +685,18 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "strafeRight",
"interpTarget": 6,
"interpDuration": 6,
"interpTarget": 5,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idle" },
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
@ -671,18 +706,65 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "strafeLeft",
"interpTarget": 5,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isFlying", "state": "fly" },
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "strafeRightHmd",
"interpTarget": 5,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isFlying", "state": "fly" },
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
]
},
{
"id": "strafeLeft",
"interpTarget": 6,
"interpDuration": 6,
"id": "strafeLeftHmd",
"interpTarget": 5,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idle" },
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isFlying", "state": "fly" },
@ -695,7 +777,8 @@
{
"id": "turnRight",
"interpTarget": 6,
"interpDuration": 6,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotTurning", "state": "idle" },
{ "var": "isMovingForward", "state": "walkFwd" },
@ -707,13 +790,16 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "turnLeft",
"interpTarget": 6,
"interpDuration": 6,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotTurning", "state": "idle" },
{ "var": "isMovingForward", "state": "walkFwd" },
@ -725,7 +811,9 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
@ -733,7 +821,7 @@
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "isNotFlying", "state": "idle" }
{ "var": "isNotFlying", "state": "idleSettle" }
]
},
{
@ -797,7 +885,9 @@
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "landStandOnDone", "state": "idle" }
{ "var": "landStandOnDone", "state": "idle" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
@ -871,13 +961,13 @@
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.5, 1.4, 4.5],
"characteristicSpeeds": [0.5, 1.5, 2.5, 3.2, 4.5],
"alphaVar": "moveForwardAlpha",
"desiredSpeedVar": "moveForwardSpeed"
},
"children": [
{
"id": "walkFwdShort",
"id": "walkFwdShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_short_fwd.fbx",
@ -889,7 +979,7 @@
"children": []
},
{
"id": "walkFwdNormal",
"id": "walkFwdNormal_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_fwd.fbx",
@ -901,7 +991,31 @@
"children": []
},
{
"id": "walkFwdRun",
"id": "walkFwdFast_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_fwd_fast.fbx",
"startFrame": 0.0,
"endFrame": 25.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "walkFwdJog_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/jog_fwd.fbx",
"startFrame": 0.0,
"endFrame": 25.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "walkFwdRun_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/run_fwd.fbx",
@ -926,13 +1040,25 @@
},
"children": []
},
{
"id": "idleSettle",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/settle_to_idle.fbx",
"startFrame": 1.0,
"endFrame": 48.0,
"timeScale": 1.0,
"loopFlag": false
},
"children": []
},
{
"id": "walkBwd",
"type": "blendLinearMove",
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.6, 1.45],
"characteristicSpeeds": [0.6, 1.7],
"alphaVar": "moveBackwardAlpha",
"desiredSpeedVar": "moveBackwardSpeed"
},
@ -953,9 +1079,9 @@
"id": "walkBwdNormal",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_bwd.fbx",
"url": "qrc:///avatar/animations/walk_bwd_fast.fbx",
"startFrame": 0.0,
"endFrame": 36.0,
"endFrame": 27.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -969,7 +1095,7 @@
"data": {
"url": "qrc:///avatar/animations/turn_left.fbx",
"startFrame": 0.0,
"endFrame": 28.0,
"endFrame": 32.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -981,7 +1107,7 @@
"data": {
"url": "qrc:///avatar/animations/turn_left.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"endFrame": 32.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
@ -994,30 +1120,66 @@
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.2, 0.65],
"characteristicSpeeds": [0, 0.5, 1.5, 2.6, 3.0],
"alphaVar": "moveLateralAlpha",
"desiredSpeedVar": "moveLateralSpeed"
},
"children": [
{
"id": "strafeLeftShort",
"id": "strafeLeftShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 28.0,
"endFrame": 29.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftNormal",
"id": "strafeLeft_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"endFrame": 20.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftAnim_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_left.fbx",
"startFrame": 0.0,
"endFrame": 33.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftFast_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_left_fast.fbx",
"startFrame": 0.0,
"endFrame": 21.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftJog_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/jog_left.fbx",
"startFrame": 0.0,
"endFrame": 24.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -1031,34 +1193,175 @@
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.2, 0.65],
"characteristicSpeeds": [0, 0.5, 1.5, 2.6, 3.0],
"alphaVar": "moveLateralAlpha",
"desiredSpeedVar": "moveLateralSpeed"
},
"children": [ {
"id": "stepRightShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 29.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "stepRight_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 20.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "strafeRight_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_left.fbx",
"startFrame": 0.0,
"endFrame": 33.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "strafeRightFast_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_left_fast.fbx",
"startFrame": 0.0,
"endFrame": 21.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "strafeRightJog_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/jog_left.fbx",
"startFrame": 0.0,
"endFrame": 24.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
}
]
},
{
"id": "strafeLeftHmd",
"type": "blendLinearMove",
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0, 0.5, 2.5],
"alphaVar": "moveLateralAlpha",
"desiredSpeedVar": "moveLateralSpeed"
},
"children": [
{
"id": "strafeRightShort",
"id": "stepLeftShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_short_right.fbx",
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 28.0,
"endFrame": 29.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeRightNormal",
"id": "stepLeft_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_right.fbx",
"url": "qrc:///avatar/animations/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"endFrame": 20.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftAnim_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left_fast.fbx",
"startFrame": 0.0,
"endFrame": 16.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "strafeRightHmd",
"type": "blendLinearMove",
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0, 0.5, 2.5],
"alphaVar": "moveLateralAlpha",
"desiredSpeedVar": "moveLateralSpeed"
},
"children": [
{
"id": "stepRightShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 29.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "stepRight_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 20.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "strafeRightAnim_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left_fast.fbx",
"startFrame": 0.0,
"endFrame": 16.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
}
]
},

View file

@ -173,6 +173,21 @@ Item {
StatText {
text: "Yaw: " + root.yaw.toFixed(1)
}
StatText {
visible: root.animStackNames.length > 0;
text: "Anim Stack Names:"
}
ListView {
width: geoCol.width
height: root.animStackNames.length * 15
visible: root.animStackNames.length > 0;
model: root.animStackNames
delegate: StatText {
text: modelData.length > 30
? modelData.substring(0, 5) + "..." + modelData.substring(modelData.length - 22)
: modelData
}
}
StatText {
visible: root.expanded;
text: "Avatar Mixer In: " + root.avatarMixerInKbps + " kbps, " +

View file

@ -2336,6 +2336,23 @@ void MyAvatar::updateOrientation(float deltaTime) {
}
}
static float scaleSpeedByDirection(const glm::vec2 velocityDirection, const float forwardSpeed, const float backwardSpeed) {
// for the elipse function --> (x^2)/(backwardSpeed*backwardSpeed) + y^2/(forwardSpeed*forwardSpeed) = 1, scale == y^2 when x is 0
float fwdScale = forwardSpeed * forwardSpeed;
float backScale = backwardSpeed * backwardSpeed;
float scaledX = velocityDirection.x * backwardSpeed;
float scaledSpeed = forwardSpeed;
if (velocityDirection.y < 0.0f) {
if (backScale > 0.0f) {
float yValue = sqrtf(fwdScale * (1.0f - ((scaledX * scaledX) / backScale)));
scaledSpeed = sqrtf((scaledX * scaledX) + (yValue * yValue));
}
} else {
scaledSpeed = backwardSpeed;
}
return scaledSpeed;
}
void MyAvatar::updateActionMotor(float deltaTime) {
bool thrustIsPushing = (glm::length2(_thrust) > EPSILON);
bool scriptedMotorIsPushing = (_motionBehaviors & AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED)
@ -2397,7 +2414,10 @@ void MyAvatar::updateActionMotor(float deltaTime) {
_actionMotorVelocity = motorSpeed * direction;
} else {
// we're interacting with a floor --> simple horizontal speed and exponential decay
_actionMotorVelocity = getSensorToWorldScale() * (_walkSpeed.get() * _walkSpeedScalar) * direction;
const glm::vec2 currentVel = { direction.x, direction.z };
float scaledSpeed = scaleSpeedByDirection(currentVel, _walkSpeed.get(), _walkBackwardSpeed.get());
// _walkSpeedScalar is a multiplier if we are in sprint mode, otherwise 1.0
_actionMotorVelocity = getSensorToWorldScale() * (scaledSpeed * _walkSpeedScalar) * direction;
}
float previousBoomLength = _boomLength;
@ -3449,18 +3469,34 @@ float MyAvatar::getWalkSpeed() const {
return _walkSpeed.get() * _walkSpeedScalar;
}
float MyAvatar::getWalkBackwardSpeed() const {
return _walkSpeed.get() * _walkSpeedScalar;
}
bool MyAvatar::isReadyForPhysics() const {
return qApp->isServerlessMode() || _haveReceivedHeightLimitsFromDomain;
}
void MyAvatar::setSprintMode(bool sprint) {
_walkSpeedScalar = sprint ? AVATAR_SPRINT_SPEED_SCALAR : AVATAR_WALK_SPEED_SCALAR;
_walkSpeedScalar = sprint ? _sprintSpeed.get() : AVATAR_WALK_SPEED_SCALAR;
}
void MyAvatar::setWalkSpeed(float value) {
_walkSpeed.set(value);
}
void MyAvatar::setWalkBackwardSpeed(float value) {
_walkBackwardSpeed.set(value);
}
void MyAvatar::setSprintSpeed(float value) {
_sprintSpeed.set(value);
}
float MyAvatar::getSprintSpeed() const {
return _sprintSpeed.get();
}
QVector<QString> MyAvatar::getScriptUrls() {
QVector<QString> scripts = _skeletonModel->isLoaded() ? _skeletonModel->getFBXGeometry().scripts : QVector<QString>();
return scripts;

View file

@ -138,6 +138,8 @@ class MyAvatar : public Avatar {
* where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain). Note: Likely to be deprecated.
* <em>Read-only.</em>
* @property {number} walkSpeed
* @property {number} walkBackwardSpeed
* @property {number} sprintSpeed
*
* @property {Vec3} skeletonOffset - Can be used to apply a translation offset between the avatar's position and the
* registration point of the 3D model.
@ -233,6 +235,8 @@ class MyAvatar : public Avatar {
Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT)
Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed);
Q_PROPERTY(float walkBackwardSpeed READ getWalkBackwardSpeed WRITE setWalkBackwardSpeed);
Q_PROPERTY(float sprintSpeed READ getSprintSpeed WRITE setSprintSpeed);
const QString DOMINANT_LEFT_HAND = "left";
const QString DOMINANT_RIGHT_HAND = "right";
@ -1074,6 +1078,10 @@ public:
void setWalkSpeed(float value);
float getWalkSpeed() const;
void setWalkBackwardSpeed(float value);
float getWalkBackwardSpeed() const;
void setSprintSpeed(float value);
float getSprintSpeed() const;
QVector<QString> getScriptUrls();
@ -1745,6 +1753,8 @@ private:
// max unscaled forward movement speed
ThreadSafeValueCache<float> _walkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED };
ThreadSafeValueCache<float> _walkBackwardSpeed { DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED };
ThreadSafeValueCache<float> _sprintSpeed { AVATAR_SPRINT_SPEED_SCALAR };
float _walkSpeedScalar { AVATAR_WALK_SPEED_SCALAR };
// load avatar scripts once when rig is ready

View file

@ -191,6 +191,14 @@ void Stats::updateStats(bool force) {
// Third column, avatar stats
auto myAvatar = avatarManager->getMyAvatar();
auto animStack = myAvatar->getSkeletonModel()->getRig().getAnimStack();
_animStackNames.clear();
for (auto animStackIterator = animStack.begin(); animStackIterator != animStack.end(); ++animStackIterator) {
_animStackNames << animStackIterator->first + ": " + QString::number(animStackIterator->second,'f',3);
}
emit animStackNamesChanged();
glm::vec3 avatarPos = myAvatar->getWorldPosition();
STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z));
STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getWorldVelocity()), 0.01f);
@ -251,7 +259,6 @@ void Stats::updateStats(bool force) {
STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount());
STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
// See if the active download urls have changed
bool shouldUpdateUrls = _downloads != _downloadUrls.size();
@ -346,7 +353,6 @@ void Stats::updateStats(bool force) {
auto config = qApp->getRenderEngine()->getConfiguration().get();
STAT_UPDATE(engineFrameTime, (float) config->getCPURunTime());
STAT_UPDATE(avatarSimulationTime, (float)avatarManager->getAvatarSimulationTime());
STAT_UPDATE(gpuBuffers, (int)gpu::Context::getBufferGPUCount());
STAT_UPDATE(gpuBufferMemory, (int)BYTES_TO_MB(gpu::Context::getBufferGPUMemSize()));

View file

@ -135,6 +135,7 @@ private: \
* @property {number} batchFrameTime - <em>Read-only.</em>
* @property {number} engineFrameTime - <em>Read-only.</em>
* @property {number} avatarSimulationTime - <em>Read-only.</em>
* @property {string[]} animStackNames - <em>Read-only.</em>
*
*
* @property {number} x
@ -282,6 +283,7 @@ class Stats : public QQuickItem {
STATS_PROPERTY(float, batchFrameTime, 0)
STATS_PROPERTY(float, engineFrameTime, 0)
STATS_PROPERTY(float, avatarSimulationTime, 0)
Q_PROPERTY(QStringList animStackNames READ animStackNames NOTIFY animStackNamesChanged)
public:
static Stats* getInstance();
@ -306,6 +308,7 @@ public:
}
QStringList downloadUrls () { return _downloadUrls; }
QStringList animStackNames() { return _animStackNames; }
public slots:
void forceUpdateStats() { updateStats(true); }
@ -999,6 +1002,13 @@ signals:
*/
void avatarSimulationTimeChanged();
/**jsdoc
* Triggered when the value of the <code>animStackNames</code> property changes.
* @function Stats.animStackNamesChanged
* @returns {Signal}
*/
void animStackNamesChanged();
/**jsdoc
* Triggered when the value of the <code>rectifiedTextureCount</code> property changes.
* @function Stats.rectifiedTextureCountChanged
@ -1244,6 +1254,7 @@ private:
QString _monospaceFont;
const AudioIOStats* _audioStats;
QStringList _downloadUrls = QStringList();
QStringList _animStackNames = QStringList();
};
#endif // hifi_Stats_h

View file

@ -27,6 +27,7 @@ AnimBlendLinear::~AnimBlendLinear() {
const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
_alpha = animVars.lookup(_alphaVar, _alpha);
float parentAlpha = _animStack[_id];
if (_children.size() == 0) {
for (auto&& pose : _poses) {
@ -34,16 +35,27 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, con
}
} else if (_children.size() == 1) {
_poses = _children[0]->evaluate(animVars, context, dt, triggersOut);
_animStack[_children[0]->getID()] = parentAlpha;
} else {
float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
size_t prevPoseIndex = glm::floor(clampedAlpha);
size_t nextPoseIndex = glm::ceil(clampedAlpha);
float alpha = glm::fract(clampedAlpha);
auto alpha = glm::fract(clampedAlpha);
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, dt);
}
// weights are for animation stack debug purposes only.
float weight1 = 0.0f;
float weight2 = 0.0f;
if (prevPoseIndex == nextPoseIndex) {
weight2 = 1.0f;
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
} else {
weight2 = alpha;
weight1 = 1.0f - weight2;
_animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha;
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
}
}
processOutputJoints(triggersOut);
return _poses;

View file

@ -26,13 +26,46 @@ AnimBlendLinearMove::~AnimBlendLinearMove() {
}
static float calculateAlpha(const float speed, const std::vector<float>& characteristicSpeeds) {
assert(characteristicSpeeds.size() > 0);
// calculate alpha from linear combination of referenceSpeeds.
float alpha = 0.0f;
if (speed <= characteristicSpeeds.front()) {
alpha = 0.0f;
} else if (speed > characteristicSpeeds.back()) {
alpha = (float)(characteristicSpeeds.size() - 1);
} else {
for (size_t i = 0; i < characteristicSpeeds.size() - 1; i++) {
if (characteristicSpeeds[i] < speed && speed < characteristicSpeeds[i + 1]) {
alpha = (float)i + ((speed - characteristicSpeeds[i]) / (characteristicSpeeds[i + 1] - characteristicSpeeds[i]));
break;
}
}
}
return alpha;
}
const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
assert(_children.size() == _characteristicSpeeds.size());
_alpha = animVars.lookup(_alphaVar, _alpha);
_desiredSpeed = animVars.lookup(_desiredSpeedVar, _desiredSpeed);
float speed = 0.0f;
if (_alphaVar.contains("Lateral")) {
speed = animVars.lookup("moveLateralSpeed", speed);
} else if (_alphaVar.contains("Backward")) {
speed = animVars.lookup("moveBackwardSpeed", speed);
} else {
//this is forward movement
speed = animVars.lookup("moveForwardSpeed", speed);
}
_alpha = calculateAlpha(speed, _characteristicSpeeds);
float parentAlpha = _animStack[_id];
_animStack["speed"] = speed;
if (_children.size() == 0) {
for (auto&& pose : _poses) {
pose = AnimPose::identity;
@ -44,8 +77,8 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
float prevDeltaTime, nextDeltaTime;
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
_animStack[_children[0]->getID()] = parentAlpha;
} else {
auto clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
auto prevPoseIndex = glm::floor(clampedAlpha);
auto nextPoseIndex = glm::ceil(clampedAlpha);
@ -53,6 +86,19 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
float prevDeltaTime, nextDeltaTime;
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
// weights are for animation stack debug purposes only.
float weight1 = 0.0f;
float weight2 = 0.0f;
if (prevPoseIndex == nextPoseIndex) {
weight2 = 1.0f;
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
} else {
weight2 = alpha;
weight1 = 1.0f - weight2;
_animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha;
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
}
}
processOutputJoints(triggersOut);

View file

@ -12,6 +12,10 @@
#include <QtGlobal>
std::map<QString, float> AnimNode::_animStack = {
{"none", 0.0f}
};
AnimNode::Pointer AnimNode::getParent() {
return _parent.lock();
}

View file

@ -84,6 +84,7 @@ public:
}
void setCurrentFrame(float frame);
const std::map<QString, float> getAnimStack() { return _animStack; }
template <typename F>
bool traverse(F func) {
@ -126,6 +127,9 @@ protected:
std::weak_ptr<AnimNode> _parent;
std::vector<QString> _outputJointNames;
// global available to Stats.h
static std::map<QString, float> _animStack;
// no copies
AnimNode(const AnimNode&) = delete;
AnimNode& operator=(const AnimNode&) = delete;

View file

@ -661,7 +661,7 @@ bool processStateMachineNode(AnimNode::Pointer node, const QJsonObject& jsonObj,
return false;
}
AnimStateMachine::InterpType interpTypeEnum = AnimStateMachine::InterpType::SnapshotBoth; // default value
AnimStateMachine::InterpType interpTypeEnum = AnimStateMachine::InterpType::SnapshotPrev; // default value
if (!interpType.isEmpty()) {
interpTypeEnum = stringToInterpType(interpType);
if (interpTypeEnum == AnimStateMachine::InterpType::NumTypes) {

View file

@ -23,12 +23,18 @@ AnimStateMachine::~AnimStateMachine() {
const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
if (_id.contains("userAnimStateMachine")) {
_animStack.clear();
}
QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID());
if (_currentState->getID() != desiredStateID) {
// switch states
bool foundState = false;
for (auto& state : _states) {
if (state->getID() == desiredStateID) {
// parenthesis means previous state, which is a snapshot.
_previousStateID = "(" + _currentState->getID() + ")";
switchState(animVars, context, state);
foundState = true;
break;
@ -42,6 +48,8 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
// evaluate currentState transitions
auto desiredState = evaluateTransitions(animVars);
if (desiredState != _currentState) {
// parenthesis means previous state, which is a snapshot.
_previousStateID = "(" + _currentState->getID() + ")";
switchState(animVars, context, desiredState);
}
@ -49,8 +57,17 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
auto currentStateNode = _children[_currentState->getChildIndex()];
assert(currentStateNode);
if (!_previousStateID.contains("none")) {
_animStack[_previousStateID] = 1.0f - _alpha;
}
if (_duringInterp) {
_alpha += _alphaVel * dt;
if (_alpha > 1.0f) {
_animStack[_currentState->getID()] = 1.0f;
} else {
_animStack[_currentState->getID()] = _alpha;
}
if (_alpha < 1.0f) {
AnimPoseVec* nextPoses = nullptr;
AnimPoseVec* prevPoses = nullptr;
@ -68,20 +85,23 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
} else {
assert(false);
}
if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) {
::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]);
}
} else {
_duringInterp = false;
if (_animStack.count(_previousStateID) > 0) {
_animStack.erase(_previousStateID);
}
_previousStateID = "none";
_prevPoses.clear();
_nextPoses.clear();
}
}
if (!_duringInterp) {
_animStack[_currentState->getID()] = 1.0f;
_poses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
}
processOutputJoints(triggersOut);
return _poses;

View file

@ -133,11 +133,12 @@ protected:
// interpolation state
bool _duringInterp = false;
InterpType _interpType { InterpType::SnapshotBoth };
InterpType _interpType { InterpType::SnapshotPrev };
float _alphaVel = 0.0f;
float _alpha = 0.0f;
AnimPoseVec _prevPoses;
AnimPoseVec _nextPoses;
QString _previousStateID { "none" };
State::Pointer _currentState;
std::vector<State::Pointer> _states;

View file

@ -590,28 +590,6 @@ bool Rig::getAbsoluteJointPoseInRigFrame(int jointIndex, AnimPose& returnPose) c
}
}
void Rig::calcAnimAlpha(float speed, const std::vector<float>& referenceSpeeds, float* alphaOut) const {
ASSERT(referenceSpeeds.size() > 0);
// calculate alpha from linear combination of referenceSpeeds.
float alpha = 0.0f;
if (speed <= referenceSpeeds.front()) {
alpha = 0.0f;
} else if (speed > referenceSpeeds.back()) {
alpha = (float)(referenceSpeeds.size() - 1);
} else {
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;
}
}
}
*alphaOut = alpha;
}
void Rig::setEnableInverseKinematics(bool enable) {
_enableInverseKinematics = enable;
}
@ -651,11 +629,6 @@ bool Rig::getRelativeDefaultJointTranslation(int index, glm::vec3& translationOu
}
}
// animation reference speeds.
static const std::vector<float> FORWARD_SPEEDS = { 0.4f, 1.4f, 4.5f }; // m/s
static const std::vector<float> BACKWARD_SPEEDS = { 0.6f, 1.45f }; // 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, CharacterControllerState ccState) {
glm::vec3 forward = worldRotation * IDENTITY_FORWARD;
@ -675,24 +648,9 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// sine wave LFO var for testing.
static float t = 0.0f;
_animVars.set("sine", 2.0f * 0.5f * sinf(t) + 0.5f);
float moveForwardAlpha = 0.0f;
float moveBackwardAlpha = 0.0f;
float moveLateralAlpha = 0.0f;
// calcuate the animation alpha and timeScale values based on current speeds and animation reference speeds.
calcAnimAlpha(_averageForwardSpeed.getAverage(), FORWARD_SPEEDS, &moveForwardAlpha);
calcAnimAlpha(-_averageForwardSpeed.getAverage(), BACKWARD_SPEEDS, &moveBackwardAlpha);
calcAnimAlpha(fabsf(_averageLateralSpeed.getAverage()), LATERAL_SPEEDS, &moveLateralAlpha);
_animVars.set("moveForwardSpeed", _averageForwardSpeed.getAverage());
_animVars.set("moveForwardAlpha", moveForwardAlpha);
_animVars.set("moveBackwardSpeed", -_averageForwardSpeed.getAverage());
_animVars.set("moveBackwardAlpha", moveBackwardAlpha);
_animVars.set("moveLateralSpeed", fabsf(_averageLateralSpeed.getAverage()));
_animVars.set("moveLateralAlpha", moveLateralAlpha);
const float MOVE_ENTER_SPEED_THRESHOLD = 0.2f; // m/sec
const float MOVE_EXIT_SPEED_THRESHOLD = 0.07f; // m/sec
@ -777,6 +735,8 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", false);
} else {
@ -785,28 +745,48 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isMovingForward", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", false);
}
} else {
if (lateralSpeed > 0.0f) {
// right
_animVars.set("isMovingRight", true);
_animVars.set("isMovingLeft", false);
if (!_headEnabled) {
_animVars.set("isMovingRight", true);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
} else {
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", true);
_animVars.set("isMovingLeftHmd", false);
}
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isNotMoving", false);
} else {
// left
_animVars.set("isMovingLeft", true);
_animVars.set("isMovingRight", false);
if (!_headEnabled) {
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", true);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
} else {
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", true);
}
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isNotMoving", false);
}
}
}
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -825,14 +805,16 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isNotTurning", false);
} else {
// turning left
_animVars.set("isTurningLeft", true);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", true);
_animVars.set("isNotTurning", false);
}
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -843,15 +825,17 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isInAirRun", false);
_animVars.set("isNotInAir", true);
} else if (_state == RigRole::Idle ) {
} else if (_state == RigRole::Idle) {
// default anim vars to notMoving and notTurning
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -866,11 +850,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// flying.
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", true);
_animVars.set("isNotFlying", false);
@ -885,11 +871,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// jumping in-air
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -912,11 +900,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// jumping in-air
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -1623,7 +1613,7 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
_animVars.set("isTalking", params.isTalking);
_animVars.set("notIsTalking", !params.isTalking);
bool headEnabled = params.primaryControllerFlags[PrimaryControllerType_Head] & (uint8_t)ControllerFlags::Enabled;
_headEnabled = params.primaryControllerFlags[PrimaryControllerType_Head] & (uint8_t)ControllerFlags::Enabled;
bool leftHandEnabled = params.primaryControllerFlags[PrimaryControllerType_LeftHand] & (uint8_t)ControllerFlags::Enabled;
bool rightHandEnabled = params.primaryControllerFlags[PrimaryControllerType_RightHand] & (uint8_t)ControllerFlags::Enabled;
bool hipsEnabled = params.primaryControllerFlags[PrimaryControllerType_Hips] & (uint8_t)ControllerFlags::Enabled;
@ -1635,18 +1625,18 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
bool rightArmEnabled = params.secondaryControllerFlags[SecondaryControllerType_RightArm] & (uint8_t)ControllerFlags::Enabled;
glm::mat4 sensorToRigMatrix = glm::inverse(params.rigToSensorMatrix);
updateHead(headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]);
updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]);
updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, headEnabled, dt,
updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt,
params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand],
params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo,
params.rigToSensorMatrix, sensorToRigMatrix);
updateFeet(leftFootEnabled, rightFootEnabled, headEnabled,
updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled,
params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot],
params.rigToSensorMatrix, sensorToRigMatrix);
if (headEnabled) {
if (_headEnabled) {
// Blend IK chains toward the joint limit centers, this should stablize head and hand ik.
_animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses);
} else {

View file

@ -221,6 +221,9 @@ public:
// input assumed to be in rig space
void computeHeadFromHMD(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut) const;
const std::map<QString, float> getAnimStack() { return _animNode->getAnimStack(); }
void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; };
signals:
void onLoadComplete();
@ -298,6 +301,7 @@ protected:
std::shared_ptr<AnimSkeleton> _animSkeleton;
std::unique_ptr<AnimNodeLoader> _animLoader;
AnimVariantMap _animVars;
enum class RigRole {
Idle = 0,
Turn,
@ -383,6 +387,7 @@ protected:
bool _smoothPoleVectors { false };
int _rigId;
bool _headEnabled { false };
};
#endif /* defined(__hifi__Rig__) */

View file

@ -66,6 +66,7 @@ const glm::vec3 DEFAULT_AVATAR_RIGHTFOOT_POS { 0.08f, -0.96f, 0.029f };
const glm::quat DEFAULT_AVATAR_RIGHTFOOT_ROT { -0.4016716778278351f, 0.9154615998268127f, 0.0053307069465518f, 0.023696165531873703f };
const float DEFAULT_AVATAR_MAX_WALKING_SPEED = 2.6f; // meters / second
const float DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED = 2.2f; // meters / second
const float DEFAULT_AVATAR_MAX_FLYING_SPEED = 30.0f; // meters / second
const float DEFAULT_AVATAR_GRAVITY = -5.0f; // meters / second^2