mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 06:44:17 +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
interface/resources/meshes/defaultAvatar_full
libraries
|
@ -248,8 +248,10 @@
|
|||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isFlying", "state": "fly" },
|
||||
{ "var": "isTakeoff", "state": "takeoff" },
|
||||
{ "var": "isInAir", "state": "inAir" }
|
||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -266,8 +268,10 @@
|
|||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isFlying", "state": "fly" },
|
||||
{ "var": "isTakeoff", "state": "takeoff" },
|
||||
{ "var": "isInAir", "state": "inAir" }
|
||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -283,8 +287,10 @@
|
|||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isFlying", "state": "fly" },
|
||||
{ "var": "isTakeoff", "state": "takeoff" },
|
||||
{ "var": "isInAir", "state": "inAir" }
|
||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -300,8 +306,10 @@
|
|||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isFlying", "state": "fly" },
|
||||
{ "var": "isTakeoff", "state": "takeoff" },
|
||||
{ "var": "isInAir", "state": "inAir" }
|
||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -317,8 +325,10 @@
|
|||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isFlying", "state": "fly" },
|
||||
{ "var": "isTakeoff", "state": "takeoff" },
|
||||
{ "var": "isInAir", "state": "inAir" }
|
||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -334,8 +344,10 @@
|
|||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isFlying", "state": "fly" },
|
||||
{ "var": "isTakeoff", "state": "takeoff" },
|
||||
{ "var": "isInAir", "state": "inAir" }
|
||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -351,8 +363,10 @@
|
|||
{ "var": "isTurningLeft", "state": "turnLeft" },
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isFlying", "state": "fly" },
|
||||
{ "var": "isTakeoff", "state": "takeoff" },
|
||||
{ "var": "isInAir", "state": "inAir" }
|
||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -368,8 +382,10 @@
|
|||
{ "var": "isTurningRight", "state": "turnRight" },
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isFlying", "state": "fly" },
|
||||
{ "var": "isTakeoff", "state": "takeoff" },
|
||||
{ "var": "isInAir", "state": "inAir" }
|
||||
{ "var": "isTakeoffStand", "state": "takeoffStand" },
|
||||
{ "var": "isTakeoffRun", "state": "takeoffRun" },
|
||||
{ "var": "isInAirStand", "state": "inAirStand" },
|
||||
{ "var": "isInAirRun", "state": "inAirRun" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -407,18 +423,38 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "takeoff",
|
||||
"id": "takeoffStand",
|
||||
"interpTarget": 0,
|
||||
"interpDuration": 6,
|
||||
"transitions": [
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isNotTakeoff", "state": "inAir" }
|
||||
{ "var": "isNotTakeoff", "state": "inAirStand" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "inAir",
|
||||
"id": "takeoffRun",
|
||||
"interpTarget": 0,
|
||||
"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": [
|
||||
{ "var": "isAway", "state": "awayIntro" },
|
||||
{ "var": "isNotInAir", "state": "idle" }
|
||||
|
@ -723,19 +759,31 @@
|
|||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "takeoff",
|
||||
"id": "takeoffStand",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_takeoff.fbx",
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 2.5,
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_takeoff.fbx",
|
||||
"startFrame": 17.0,
|
||||
"endFrame": 25.0,
|
||||
"timeScale": 1.0,
|
||||
"loopFlag": false
|
||||
},
|
||||
"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",
|
||||
"data": {
|
||||
"alpha": 0.0,
|
||||
|
@ -743,10 +791,10 @@
|
|||
},
|
||||
"children": [
|
||||
{
|
||||
"id": "inAirPreApex",
|
||||
"id": "inAirStandPreApex",
|
||||
"type": "clip",
|
||||
"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,
|
||||
"endFrame": 0.0,
|
||||
"timeScale": 0.0,
|
||||
|
@ -755,10 +803,56 @@
|
|||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "inAirApex",
|
||||
"id": "inAirStandApex",
|
||||
"type": "clip",
|
||||
"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,
|
||||
"endFrame": 6.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -767,10 +861,10 @@
|
|||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "inAirPostApex",
|
||||
"id": "inAirRunPostApex",
|
||||
"type": "clip",
|
||||
"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,
|
||||
"endFrame": 11.0,
|
||||
"timeScale": 1.0,
|
||||
|
|
|
@ -627,6 +627,8 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
// Skip hystersis timer for jump transitions.
|
||||
if (_desiredState == RigRole::Takeoff) {
|
||||
_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) {
|
||||
_desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER;
|
||||
}
|
||||
|
@ -679,9 +681,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isNotTurning", true);
|
||||
_animVars.set("isFlying", false);
|
||||
_animVars.set("isNotFlying", true);
|
||||
_animVars.set("isTakeoff", false);
|
||||
_animVars.set("isTakeoffStand", false);
|
||||
_animVars.set("isTakeoffRun", false);
|
||||
_animVars.set("isNotTakeoff", true);
|
||||
_animVars.set("isInAir", false);
|
||||
_animVars.set("isInAirStand", false);
|
||||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
}
|
||||
} else if (_state == RigRole::Turn) {
|
||||
|
@ -703,9 +707,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isNotMoving", true);
|
||||
_animVars.set("isFlying", false);
|
||||
_animVars.set("isNotFlying", true);
|
||||
_animVars.set("isTakeoff", false);
|
||||
_animVars.set("isTakeoffStand", false);
|
||||
_animVars.set("isTakeoffRun", false);
|
||||
_animVars.set("isNotTakeoff", true);
|
||||
_animVars.set("isInAir", false);
|
||||
_animVars.set("isInAirStand", false);
|
||||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
|
||||
} else if (_state == RigRole::Idle ) {
|
||||
|
@ -720,9 +726,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isNotTurning", true);
|
||||
_animVars.set("isFlying", false);
|
||||
_animVars.set("isNotFlying", true);
|
||||
_animVars.set("isTakeoff", false);
|
||||
_animVars.set("isTakeoffStand", false);
|
||||
_animVars.set("isTakeoffRun", false);
|
||||
_animVars.set("isNotTakeoff", true);
|
||||
_animVars.set("isInAir", false);
|
||||
_animVars.set("isInAirStand", false);
|
||||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
|
||||
} else if (_state == RigRole::Hover) {
|
||||
|
@ -737,9 +745,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isNotTurning", true);
|
||||
_animVars.set("isFlying", true);
|
||||
_animVars.set("isNotFlying", false);
|
||||
_animVars.set("isTakeoff", false);
|
||||
_animVars.set("isTakeoffStand", false);
|
||||
_animVars.set("isTakeoffRun", false);
|
||||
_animVars.set("isNotTakeoff", true);
|
||||
_animVars.set("isInAir", false);
|
||||
_animVars.set("isInAirStand", false);
|
||||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", true);
|
||||
|
||||
} else if (_state == RigRole::Takeoff) {
|
||||
|
@ -754,9 +764,19 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isNotTurning", true);
|
||||
_animVars.set("isFlying", false);
|
||||
_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("isInAir", true);
|
||||
_animVars.set("isInAirStand", false);
|
||||
_animVars.set("isInAirRun", false);
|
||||
_animVars.set("isNotInAir", false);
|
||||
|
||||
} else if (_state == RigRole::InAir) {
|
||||
|
@ -771,9 +791,18 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
|||
_animVars.set("isNotTurning", true);
|
||||
_animVars.set("isFlying", false);
|
||||
_animVars.set("isNotFlying", true);
|
||||
_animVars.set("isTakeoff", false);
|
||||
_animVars.set("isTakeoffStand", false);
|
||||
_animVars.set("isTakeoffRun", false);
|
||||
_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);
|
||||
|
||||
// compute blend based on velocity
|
||||
|
|
|
@ -301,7 +301,7 @@ public:
|
|||
std::map<QString, AnimNode::Pointer> _origRoleAnimations;
|
||||
std::vector<AnimNode::Pointer> _prefetchedAnimations;
|
||||
|
||||
bool _lastEnableInverseKinematics { false };
|
||||
bool _lastEnableInverseKinematics { true };
|
||||
bool _enableInverseKinematics { true };
|
||||
|
||||
private:
|
||||
|
|
|
@ -60,9 +60,10 @@ CharacterController::CharacterController() {
|
|||
_jumpSpeed = JUMP_SPEED;
|
||||
_state = State::Hover;
|
||||
_isPushingUp = false;
|
||||
_jumpButtonDownStart = 0;
|
||||
_rayHitStartTime = 0;
|
||||
_takeoffToInAirStartTime = 0;
|
||||
_jumpButtonDownStartTime = 0;
|
||||
_jumpButtonDownCount = 0;
|
||||
_takeoffToInAirStart = 0;
|
||||
_followTime = 0.0f;
|
||||
_followLinearDisplacement = btVector3(0, 0, 0);
|
||||
_followAngularDisplacement = btQuaternion::getIdentity();
|
||||
|
@ -417,6 +418,8 @@ glm::vec3 CharacterController::getLinearVelocity() const {
|
|||
|
||||
void CharacterController::preSimulation() {
|
||||
if (_enabled && _dynamicsWorld) {
|
||||
quint64 now = usecTimestampNow();
|
||||
|
||||
// slam body to where it is supposed to be
|
||||
_rigidBody->setWorldTransform(_characterBodyTransform);
|
||||
btVector3 velocity = _rigidBody->getLinearVelocity();
|
||||
|
@ -432,27 +435,30 @@ void CharacterController::preSimulation() {
|
|||
btScalar rayLength = _radius + MAX_FALL_HEIGHT;
|
||||
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);
|
||||
rayCallback.m_closestHitFraction = 1.0f;
|
||||
_dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback);
|
||||
if (rayCallback.hasHit()) {
|
||||
bool rayHasHit = rayCallback.hasHit();
|
||||
if (rayHasHit) {
|
||||
_rayHitStartTime = now;
|
||||
_floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
|
||||
} else if ((now - _rayHitStartTime) < RAY_HIT_START_PERIOD) {
|
||||
rayHasHit = true;
|
||||
} else {
|
||||
_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.
|
||||
if ((_previousFlags & PENDING_FLAG_JUMP) != (_pendingFlags & PENDING_FLAG_JUMP)) {
|
||||
if (_pendingFlags & PENDING_FLAG_JUMP) {
|
||||
_jumpButtonDownStart = now;
|
||||
_jumpButtonDownStartTime = now;
|
||||
_jumpButtonDownCount++;
|
||||
}
|
||||
}
|
||||
|
@ -462,19 +468,22 @@ void CharacterController::preSimulation() {
|
|||
|
||||
switch (_state) {
|
||||
case State::Ground:
|
||||
if (!rayCallback.hasHit() && !_hasSupport) {
|
||||
SET_STATE(State::Hover, "no ground");
|
||||
} else if (_pendingFlags & PENDING_FLAG_JUMP) {
|
||||
_takeOffJumpButtonID = _jumpButtonDownCount;
|
||||
if (!rayHasHit && !_hasSupport) {
|
||||
SET_STATE(State::Hover, "no ground detected");
|
||||
} else if (_pendingFlags & PENDING_FLAG_JUMP && _jumpButtonDownCount != _takeoffJumpButtonID) {
|
||||
_takeoffJumpButtonID = _jumpButtonDownCount;
|
||||
_takeoffToInAirStartTime = now;
|
||||
SET_STATE(State::Takeoff, "jump pressed");
|
||||
} else if (rayHasHit && !_hasSupport && _floorDistance > JUMP_PROXIMITY_THRESHOLD) {
|
||||
SET_STATE(State::InAir, "falling");
|
||||
}
|
||||
break;
|
||||
case State::Takeoff:
|
||||
if (!rayCallback.hasHit() && !_hasSupport) {
|
||||
if (!rayHasHit && !_hasSupport) {
|
||||
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");
|
||||
_takeoffToInAirStart = now + USECS_PER_SECOND * 86500.0f;
|
||||
_takeoffToInAirStartTime = now + USECS_PER_SECOND * 86500.0f;
|
||||
velocity += _jumpSpeed * _currentUp;
|
||||
_rigidBody->setLinearVelocity(velocity);
|
||||
}
|
||||
|
@ -482,9 +491,9 @@ void CharacterController::preSimulation() {
|
|||
case State::InAir: {
|
||||
if ((velocity.dot(_currentUp) <= (JUMP_SPEED / 2.0f)) && ((_floorDistance < JUMP_PROXIMITY_THRESHOLD) || _hasSupport)) {
|
||||
SET_STATE(State::Ground, "hit ground");
|
||||
} else if (jumpButtonHeld && (_takeOffJumpButtonID != _jumpButtonDownCount)) {
|
||||
} else if (jumpButtonHeld && (_takeoffJumpButtonID != _jumpButtonDownCount)) {
|
||||
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");
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -114,10 +114,11 @@ protected:
|
|||
|
||||
glm::vec3 _boxScale; // used to compute capsule shape
|
||||
|
||||
quint64 _takeoffToInAirStart;
|
||||
quint64 _jumpButtonDownStart;
|
||||
quint64 _rayHitStartTime;
|
||||
quint64 _takeoffToInAirStartTime;
|
||||
quint64 _jumpButtonDownStartTime;
|
||||
quint32 _jumpButtonDownCount;
|
||||
quint32 _takeOffJumpButtonID;
|
||||
quint32 _takeoffJumpButtonID;
|
||||
|
||||
btScalar _halfHeight;
|
||||
btScalar _radius;
|
||||
|
|
Loading…
Reference in a new issue