mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 11:44:09 +02:00
MyAvatar: Standing Takeoff and In-Air Animations
Now there are two sets of of jump takeoff and in-air animations. * Run - Used when the character jumps or falls with a small forward velocity. * Standing - Used when the character jumps or falls in-place or backward. CharacterController * increased takeoff duration to 250 ms * increased takeoff to fly duration to 1100 ms * added standing jump and in-air animations * added 250 milisecond delay between ground and hover, to prevent going into hover when walking over cracks. * take-off to in-air transitions now use the new snapshotPrev interp type for a smoother tweening.
This commit is contained in:
parent
a8e092272c
commit
8ca8550f26
5 changed files with 200 additions and 67 deletions
|
@ -248,8 +248,10 @@
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoff", "state": "takeoff" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isInAir", "state": "inAir" }
|
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -266,8 +268,10 @@
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoff", "state": "takeoff" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isInAir", "state": "inAir" }
|
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -283,8 +287,10 @@
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoff", "state": "takeoff" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isInAir", "state": "inAir" }
|
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -300,8 +306,10 @@
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoff", "state": "takeoff" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isInAir", "state": "inAir" }
|
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -317,8 +325,10 @@
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoff", "state": "takeoff" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isInAir", "state": "inAir" }
|
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -334,8 +344,10 @@
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoff", "state": "takeoff" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isInAir", "state": "inAir" }
|
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -351,8 +363,10 @@
|
||||||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoff", "state": "takeoff" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isInAir", "state": "inAir" }
|
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -368,8 +382,10 @@
|
||||||
{ "var": "isTurningRight", "state": "turnRight" },
|
{ "var": "isTurningRight", "state": "turnRight" },
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isFlying", "state": "fly" },
|
{ "var": "isFlying", "state": "fly" },
|
||||||
{ "var": "isTakeoff", "state": "takeoff" },
|
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||||
{ "var": "isInAir", "state": "inAir" }
|
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||||
|
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||||
|
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -407,18 +423,38 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "takeoff",
|
"id": "takeoffStand",
|
||||||
"interpTarget": 0,
|
"interpTarget": 0,
|
||||||
"interpDuration": 6,
|
"interpDuration": 6,
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isNotTakeoff", "state": "inAir" }
|
{ "var": "isNotTakeoff", "state": "inAirStand" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "inAir",
|
"id": "takeoffRun",
|
||||||
"interpTarget": 0,
|
"interpTarget": 0,
|
||||||
"interpDuration": 6,
|
"interpDuration": 6,
|
||||||
|
"transitions": [
|
||||||
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
|
{ "var": "isNotTakeoff", "state": "inAirRun" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "inAirStand",
|
||||||
|
"interpTarget": 0,
|
||||||
|
"interpDuration": 6,
|
||||||
|
"interpType": "snapshotPrev",
|
||||||
|
"transitions": [
|
||||||
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
|
{ "var": "isNotInAir", "state": "idle" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "inAirRun",
|
||||||
|
"interpTarget": 0,
|
||||||
|
"interpDuration": 6,
|
||||||
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{ "var": "isAway", "state": "awayIntro" },
|
{ "var": "isAway", "state": "awayIntro" },
|
||||||
{ "var": "isNotInAir", "state": "idle" }
|
{ "var": "isNotInAir", "state": "idle" }
|
||||||
|
@ -723,19 +759,31 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "takeoff",
|
"id": "takeoffStand",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_takeoff.fbx",
|
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_takeoff.fbx",
|
||||||
"startFrame": 1.0,
|
"startFrame": 17.0,
|
||||||
"endFrame": 2.5,
|
"endFrame": 25.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
"loopFlag": false
|
"loopFlag": false
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "inAir",
|
"id": "takeoffRun",
|
||||||
|
"type": "clip",
|
||||||
|
"data": {
|
||||||
|
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_takeoff.fbx",
|
||||||
|
"startFrame": 1.0,
|
||||||
|
"endFrame": 2.5,
|
||||||
|
"timeScale": 0.01,
|
||||||
|
"loopFlag": false
|
||||||
|
},
|
||||||
|
"children": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "inAirStand",
|
||||||
"type": "blendLinear",
|
"type": "blendLinear",
|
||||||
"data": {
|
"data": {
|
||||||
"alpha": 0.0,
|
"alpha": 0.0,
|
||||||
|
@ -743,10 +791,10 @@
|
||||||
},
|
},
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"id": "inAirPreApex",
|
"id": "inAirStandPreApex",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_apex.fbx",
|
||||||
"startFrame": 0.0,
|
"startFrame": 0.0,
|
||||||
"endFrame": 0.0,
|
"endFrame": 0.0,
|
||||||
"timeScale": 0.0,
|
"timeScale": 0.0,
|
||||||
|
@ -755,10 +803,56 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "inAirApex",
|
"id": "inAirStandApex",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_apex.fbx",
|
||||||
|
"startFrame": 1.0,
|
||||||
|
"endFrame": 1.0,
|
||||||
|
"timeScale": 1.0,
|
||||||
|
"loopFlag": false
|
||||||
|
},
|
||||||
|
"children": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "inAirStandPostApex",
|
||||||
|
"type": "clip",
|
||||||
|
"data": {
|
||||||
|
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_apex.fbx",
|
||||||
|
"startFrame": 2.0,
|
||||||
|
"endFrame": 2.0,
|
||||||
|
"timeScale": 1.0,
|
||||||
|
"loopFlag": false
|
||||||
|
},
|
||||||
|
"children": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "inAirRun",
|
||||||
|
"type": "blendLinear",
|
||||||
|
"data": {
|
||||||
|
"alpha": 0.0,
|
||||||
|
"alphaVar": "inAirAlpha"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "inAirRunPreApex",
|
||||||
|
"type": "clip",
|
||||||
|
"data": {
|
||||||
|
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
||||||
|
"startFrame": 0.0,
|
||||||
|
"endFrame": 0.0,
|
||||||
|
"timeScale": 0.0,
|
||||||
|
"loopFlag": false
|
||||||
|
},
|
||||||
|
"children": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "inAirRunApex",
|
||||||
|
"type": "clip",
|
||||||
|
"data": {
|
||||||
|
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
||||||
"startFrame": 6.0,
|
"startFrame": 6.0,
|
||||||
"endFrame": 6.0,
|
"endFrame": 6.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
|
@ -767,10 +861,10 @@
|
||||||
"children": []
|
"children": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "inAirPostApex",
|
"id": "inAirRunPostApex",
|
||||||
"type": "clip",
|
"type": "clip",
|
||||||
"data": {
|
"data": {
|
||||||
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
||||||
"startFrame": 11.0,
|
"startFrame": 11.0,
|
||||||
"endFrame": 11.0,
|
"endFrame": 11.0,
|
||||||
"timeScale": 1.0,
|
"timeScale": 1.0,
|
||||||
|
|
|
@ -627,6 +627,8 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
// Skip hystersis timer for jump transitions.
|
// Skip hystersis timer for jump transitions.
|
||||||
if (_desiredState == RigRole::Takeoff) {
|
if (_desiredState == RigRole::Takeoff) {
|
||||||
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
||||||
|
} else if (_state == RigRole::Takeoff && _desiredState == RigRole::InAir) {
|
||||||
|
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
||||||
} else if (_state == RigRole::InAir && _desiredState != RigRole::InAir) {
|
} else if (_state == RigRole::InAir && _desiredState != RigRole::InAir) {
|
||||||
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
||||||
}
|
}
|
||||||
|
@ -679,9 +681,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isNotTurning", true);
|
_animVars.set("isNotTurning", true);
|
||||||
_animVars.set("isFlying", false);
|
_animVars.set("isFlying", false);
|
||||||
_animVars.set("isNotFlying", true);
|
_animVars.set("isNotFlying", true);
|
||||||
_animVars.set("isTakeoff", false);
|
_animVars.set("isTakeoffStand", false);
|
||||||
|
_animVars.set("isTakeoffRun", false);
|
||||||
_animVars.set("isNotTakeoff", true);
|
_animVars.set("isNotTakeoff", true);
|
||||||
_animVars.set("isInAir", false);
|
_animVars.set("isInAirStand", false);
|
||||||
|
_animVars.set("isInAirRun", false);
|
||||||
_animVars.set("isNotInAir", true);
|
_animVars.set("isNotInAir", true);
|
||||||
}
|
}
|
||||||
} else if (_state == RigRole::Turn) {
|
} else if (_state == RigRole::Turn) {
|
||||||
|
@ -703,9 +707,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isNotMoving", true);
|
_animVars.set("isNotMoving", true);
|
||||||
_animVars.set("isFlying", false);
|
_animVars.set("isFlying", false);
|
||||||
_animVars.set("isNotFlying", true);
|
_animVars.set("isNotFlying", true);
|
||||||
_animVars.set("isTakeoff", false);
|
_animVars.set("isTakeoffStand", false);
|
||||||
|
_animVars.set("isTakeoffRun", false);
|
||||||
_animVars.set("isNotTakeoff", true);
|
_animVars.set("isNotTakeoff", true);
|
||||||
_animVars.set("isInAir", false);
|
_animVars.set("isInAirStand", false);
|
||||||
|
_animVars.set("isInAirRun", false);
|
||||||
_animVars.set("isNotInAir", true);
|
_animVars.set("isNotInAir", true);
|
||||||
|
|
||||||
} else if (_state == RigRole::Idle ) {
|
} else if (_state == RigRole::Idle ) {
|
||||||
|
@ -720,9 +726,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isNotTurning", true);
|
_animVars.set("isNotTurning", true);
|
||||||
_animVars.set("isFlying", false);
|
_animVars.set("isFlying", false);
|
||||||
_animVars.set("isNotFlying", true);
|
_animVars.set("isNotFlying", true);
|
||||||
_animVars.set("isTakeoff", false);
|
_animVars.set("isTakeoffStand", false);
|
||||||
|
_animVars.set("isTakeoffRun", false);
|
||||||
_animVars.set("isNotTakeoff", true);
|
_animVars.set("isNotTakeoff", true);
|
||||||
_animVars.set("isInAir", false);
|
_animVars.set("isInAirStand", false);
|
||||||
|
_animVars.set("isInAirRun", false);
|
||||||
_animVars.set("isNotInAir", true);
|
_animVars.set("isNotInAir", true);
|
||||||
|
|
||||||
} else if (_state == RigRole::Hover) {
|
} else if (_state == RigRole::Hover) {
|
||||||
|
@ -737,9 +745,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isNotTurning", true);
|
_animVars.set("isNotTurning", true);
|
||||||
_animVars.set("isFlying", true);
|
_animVars.set("isFlying", true);
|
||||||
_animVars.set("isNotFlying", false);
|
_animVars.set("isNotFlying", false);
|
||||||
_animVars.set("isTakeoff", false);
|
_animVars.set("isTakeoffStand", false);
|
||||||
|
_animVars.set("isTakeoffRun", false);
|
||||||
_animVars.set("isNotTakeoff", true);
|
_animVars.set("isNotTakeoff", true);
|
||||||
_animVars.set("isInAir", false);
|
_animVars.set("isInAirStand", false);
|
||||||
|
_animVars.set("isInAirRun", false);
|
||||||
_animVars.set("isNotInAir", true);
|
_animVars.set("isNotInAir", true);
|
||||||
|
|
||||||
} else if (_state == RigRole::Takeoff) {
|
} else if (_state == RigRole::Takeoff) {
|
||||||
|
@ -754,9 +764,19 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isNotTurning", true);
|
_animVars.set("isNotTurning", true);
|
||||||
_animVars.set("isFlying", false);
|
_animVars.set("isFlying", false);
|
||||||
_animVars.set("isNotFlying", true);
|
_animVars.set("isNotFlying", true);
|
||||||
_animVars.set("isTakeoff", true);
|
|
||||||
|
bool takeOffRun = forwardSpeed > 0.1f;
|
||||||
|
if (takeOffRun) {
|
||||||
|
_animVars.set("isTakeoffStand", false);
|
||||||
|
_animVars.set("isTakeoffRun", true);
|
||||||
|
} else {
|
||||||
|
_animVars.set("isTakeoffStand", true);
|
||||||
|
_animVars.set("isTakeoffRun", false);
|
||||||
|
}
|
||||||
|
|
||||||
_animVars.set("isNotTakeoff", false);
|
_animVars.set("isNotTakeoff", false);
|
||||||
_animVars.set("isInAir", true);
|
_animVars.set("isInAirStand", false);
|
||||||
|
_animVars.set("isInAirRun", false);
|
||||||
_animVars.set("isNotInAir", false);
|
_animVars.set("isNotInAir", false);
|
||||||
|
|
||||||
} else if (_state == RigRole::InAir) {
|
} else if (_state == RigRole::InAir) {
|
||||||
|
@ -771,9 +791,18 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
_animVars.set("isNotTurning", true);
|
_animVars.set("isNotTurning", true);
|
||||||
_animVars.set("isFlying", false);
|
_animVars.set("isFlying", false);
|
||||||
_animVars.set("isNotFlying", true);
|
_animVars.set("isNotFlying", true);
|
||||||
_animVars.set("isTakeoff", false);
|
_animVars.set("isTakeoffStand", false);
|
||||||
|
_animVars.set("isTakeoffRun", false);
|
||||||
_animVars.set("isNotTakeoff", true);
|
_animVars.set("isNotTakeoff", true);
|
||||||
_animVars.set("isInAir", true);
|
|
||||||
|
bool inAirRun = forwardSpeed > 0.1f;
|
||||||
|
if (inAirRun) {
|
||||||
|
_animVars.set("isInAirStand", false);
|
||||||
|
_animVars.set("isInAirRun", true);
|
||||||
|
} else {
|
||||||
|
_animVars.set("isInAirStand", true);
|
||||||
|
_animVars.set("isInAirRun", false);
|
||||||
|
}
|
||||||
_animVars.set("isNotInAir", false);
|
_animVars.set("isNotInAir", false);
|
||||||
|
|
||||||
// compute blend based on velocity
|
// compute blend based on velocity
|
||||||
|
|
|
@ -301,7 +301,7 @@ public:
|
||||||
std::map<QString, AnimNode::Pointer> _origRoleAnimations;
|
std::map<QString, AnimNode::Pointer> _origRoleAnimations;
|
||||||
std::vector<AnimNode::Pointer> _prefetchedAnimations;
|
std::vector<AnimNode::Pointer> _prefetchedAnimations;
|
||||||
|
|
||||||
bool _lastEnableInverseKinematics { false };
|
bool _lastEnableInverseKinematics { true };
|
||||||
bool _enableInverseKinematics { true };
|
bool _enableInverseKinematics { true };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -60,9 +60,10 @@ CharacterController::CharacterController() {
|
||||||
_jumpSpeed = JUMP_SPEED;
|
_jumpSpeed = JUMP_SPEED;
|
||||||
_state = State::Hover;
|
_state = State::Hover;
|
||||||
_isPushingUp = false;
|
_isPushingUp = false;
|
||||||
_jumpButtonDownStart = 0;
|
_rayHitStartTime = 0;
|
||||||
|
_takeoffToInAirStartTime = 0;
|
||||||
|
_jumpButtonDownStartTime = 0;
|
||||||
_jumpButtonDownCount = 0;
|
_jumpButtonDownCount = 0;
|
||||||
_takeoffToInAirStart = 0;
|
|
||||||
_followTime = 0.0f;
|
_followTime = 0.0f;
|
||||||
_followLinearDisplacement = btVector3(0, 0, 0);
|
_followLinearDisplacement = btVector3(0, 0, 0);
|
||||||
_followAngularDisplacement = btQuaternion::getIdentity();
|
_followAngularDisplacement = btQuaternion::getIdentity();
|
||||||
|
@ -417,6 +418,8 @@ glm::vec3 CharacterController::getLinearVelocity() const {
|
||||||
|
|
||||||
void CharacterController::preSimulation() {
|
void CharacterController::preSimulation() {
|
||||||
if (_enabled && _dynamicsWorld) {
|
if (_enabled && _dynamicsWorld) {
|
||||||
|
quint64 now = usecTimestampNow();
|
||||||
|
|
||||||
// slam body to where it is supposed to be
|
// slam body to where it is supposed to be
|
||||||
_rigidBody->setWorldTransform(_characterBodyTransform);
|
_rigidBody->setWorldTransform(_characterBodyTransform);
|
||||||
btVector3 velocity = _rigidBody->getLinearVelocity();
|
btVector3 velocity = _rigidBody->getLinearVelocity();
|
||||||
|
@ -432,27 +435,30 @@ void CharacterController::preSimulation() {
|
||||||
btScalar rayLength = _radius + MAX_FALL_HEIGHT;
|
btScalar rayLength = _radius + MAX_FALL_HEIGHT;
|
||||||
btVector3 rayEnd = rayStart - rayLength * _currentUp;
|
btVector3 rayEnd = rayStart - rayLength * _currentUp;
|
||||||
|
|
||||||
|
const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
|
||||||
|
const quint64 TAKE_OFF_TO_IN_AIR_PERIOD = 250 * MSECS_PER_SECOND;
|
||||||
|
const btScalar MIN_HOVER_HEIGHT = 2.5f;
|
||||||
|
const quint64 JUMP_TO_HOVER_PERIOD = 1100 * MSECS_PER_SECOND;
|
||||||
|
const btScalar MAX_WALKING_SPEED = 2.5f;
|
||||||
|
const quint64 RAY_HIT_START_PERIOD = 500 * MSECS_PER_SECOND;
|
||||||
|
|
||||||
ClosestNotMe rayCallback(_rigidBody);
|
ClosestNotMe rayCallback(_rigidBody);
|
||||||
rayCallback.m_closestHitFraction = 1.0f;
|
rayCallback.m_closestHitFraction = 1.0f;
|
||||||
_dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback);
|
_dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback);
|
||||||
if (rayCallback.hasHit()) {
|
bool rayHasHit = rayCallback.hasHit();
|
||||||
|
if (rayHasHit) {
|
||||||
|
_rayHitStartTime = now;
|
||||||
_floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
|
_floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
|
||||||
|
} else if ((now - _rayHitStartTime) < RAY_HIT_START_PERIOD) {
|
||||||
|
rayHasHit = true;
|
||||||
} else {
|
} else {
|
||||||
_floorDistance = FLT_MAX;
|
_floorDistance = FLT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
|
|
||||||
const quint64 TAKE_OFF_TO_IN_AIR_PERIOD = 200 * MSECS_PER_SECOND;
|
|
||||||
const btScalar MIN_HOVER_HEIGHT = 2.5f;
|
|
||||||
const quint64 JUMP_TO_HOVER_PERIOD = 750 * MSECS_PER_SECOND;
|
|
||||||
const btScalar MAX_WALKING_SPEED = 2.5f;
|
|
||||||
|
|
||||||
quint64 now = usecTimestampNow();
|
|
||||||
|
|
||||||
// record a time stamp when the jump button was first pressed.
|
// record a time stamp when the jump button was first pressed.
|
||||||
if ((_previousFlags & PENDING_FLAG_JUMP) != (_pendingFlags & PENDING_FLAG_JUMP)) {
|
if ((_previousFlags & PENDING_FLAG_JUMP) != (_pendingFlags & PENDING_FLAG_JUMP)) {
|
||||||
if (_pendingFlags & PENDING_FLAG_JUMP) {
|
if (_pendingFlags & PENDING_FLAG_JUMP) {
|
||||||
_jumpButtonDownStart = now;
|
_jumpButtonDownStartTime = now;
|
||||||
_jumpButtonDownCount++;
|
_jumpButtonDownCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -462,19 +468,22 @@ void CharacterController::preSimulation() {
|
||||||
|
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case State::Ground:
|
case State::Ground:
|
||||||
if (!rayCallback.hasHit() && !_hasSupport) {
|
if (!rayHasHit && !_hasSupport) {
|
||||||
SET_STATE(State::Hover, "no ground");
|
SET_STATE(State::Hover, "no ground detected");
|
||||||
} else if (_pendingFlags & PENDING_FLAG_JUMP) {
|
} else if (_pendingFlags & PENDING_FLAG_JUMP && _jumpButtonDownCount != _takeoffJumpButtonID) {
|
||||||
_takeOffJumpButtonID = _jumpButtonDownCount;
|
_takeoffJumpButtonID = _jumpButtonDownCount;
|
||||||
|
_takeoffToInAirStartTime = now;
|
||||||
SET_STATE(State::Takeoff, "jump pressed");
|
SET_STATE(State::Takeoff, "jump pressed");
|
||||||
|
} else if (rayHasHit && !_hasSupport && _floorDistance > JUMP_PROXIMITY_THRESHOLD) {
|
||||||
|
SET_STATE(State::InAir, "falling");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case State::Takeoff:
|
case State::Takeoff:
|
||||||
if (!rayCallback.hasHit() && !_hasSupport) {
|
if (!rayHasHit && !_hasSupport) {
|
||||||
SET_STATE(State::Hover, "no ground");
|
SET_STATE(State::Hover, "no ground");
|
||||||
} else if ((now - _takeoffToInAirStart) > TAKE_OFF_TO_IN_AIR_PERIOD) {
|
} else if ((now - _takeoffToInAirStartTime) > TAKE_OFF_TO_IN_AIR_PERIOD) {
|
||||||
SET_STATE(State::InAir, "takeoff done");
|
SET_STATE(State::InAir, "takeoff done");
|
||||||
_takeoffToInAirStart = now + USECS_PER_SECOND * 86500.0f;
|
_takeoffToInAirStartTime = now + USECS_PER_SECOND * 86500.0f;
|
||||||
velocity += _jumpSpeed * _currentUp;
|
velocity += _jumpSpeed * _currentUp;
|
||||||
_rigidBody->setLinearVelocity(velocity);
|
_rigidBody->setLinearVelocity(velocity);
|
||||||
}
|
}
|
||||||
|
@ -482,9 +491,9 @@ void CharacterController::preSimulation() {
|
||||||
case State::InAir: {
|
case State::InAir: {
|
||||||
if ((velocity.dot(_currentUp) <= (JUMP_SPEED / 2.0f)) && ((_floorDistance < JUMP_PROXIMITY_THRESHOLD) || _hasSupport)) {
|
if ((velocity.dot(_currentUp) <= (JUMP_SPEED / 2.0f)) && ((_floorDistance < JUMP_PROXIMITY_THRESHOLD) || _hasSupport)) {
|
||||||
SET_STATE(State::Ground, "hit ground");
|
SET_STATE(State::Ground, "hit ground");
|
||||||
} else if (jumpButtonHeld && (_takeOffJumpButtonID != _jumpButtonDownCount)) {
|
} else if (jumpButtonHeld && (_takeoffJumpButtonID != _jumpButtonDownCount)) {
|
||||||
SET_STATE(State::Hover, "double jump button");
|
SET_STATE(State::Hover, "double jump button");
|
||||||
} else if (jumpButtonHeld && (now - _jumpButtonDownStart) > JUMP_TO_HOVER_PERIOD) {
|
} else if (jumpButtonHeld && (now - _jumpButtonDownStartTime) > JUMP_TO_HOVER_PERIOD) {
|
||||||
SET_STATE(State::Hover, "jump button held");
|
SET_STATE(State::Hover, "jump button held");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -114,10 +114,11 @@ protected:
|
||||||
|
|
||||||
glm::vec3 _boxScale; // used to compute capsule shape
|
glm::vec3 _boxScale; // used to compute capsule shape
|
||||||
|
|
||||||
quint64 _takeoffToInAirStart;
|
quint64 _rayHitStartTime;
|
||||||
quint64 _jumpButtonDownStart;
|
quint64 _takeoffToInAirStartTime;
|
||||||
|
quint64 _jumpButtonDownStartTime;
|
||||||
quint32 _jumpButtonDownCount;
|
quint32 _jumpButtonDownCount;
|
||||||
quint32 _takeOffJumpButtonID;
|
quint32 _takeoffJumpButtonID;
|
||||||
|
|
||||||
btScalar _halfHeight;
|
btScalar _halfHeight;
|
||||||
btScalar _radius;
|
btScalar _radius;
|
||||||
|
|
Loading…
Reference in a new issue