WIP Screenshot - Everyone loves zombies!


#43

You’re probably too deep into it for it to matter now, but Bullet has a PID example in the InverseDynamics section: https://github.com/bulletphysics/bullet3/tree/master/src/BulletInverseDynamics it’s a raw PID so it’s sort of sketchy with high-velocity and sudden stops, but a safe base.

I was under the impression that “collision ended” indicated that two colliding bodies have separated - if that is not the case, what exactly constitutes the “end of a collision event” ? I ask because several render frames and one physics step have passed between receipt of “collision start” and “collision end” events.

IIRC, bullet constructs the manifold over time/substeps, collision separation likely doesn’t occur until the active manifold no longer contains a point sourced from the respective other object.

There is a check in PhysicsWorld in Urho3D for the number of contacts to minimize that, but it can only be as reliable as Bullet is. If you really care about accuracy, you’re going to have to use a ghost-object/query to find it on demand.


#44

I don’t really care that much about accuracy. All my current problems stem from the fact that the zombie walk is almost a shuffle, and so contact make and break is not reliable. Today I enabled IK, and now the feet of my zombie are spinning around wildly :frowning: Gah.


#45

Maybe you forgot a minus or transform space conversion?


#46

I have attached the ik to descaling nodes under the respective joints - this is probably playing hell with two-bone ik solver trying to ascertain parents, but otherwise its basically cut and pasted from the sample

[EDIT]
Yeah it definitely appears to me that my “descaling nodes” are the source of the problems with foot IK.
My model was 100x too big (fbx unit bug in assimp), so I added a scaling node near the root to make it 100x smaller. This presented a problem when I wanted to attach rigidbodies to the skeleton - Urho3D automatically sets the local scale of collision shapes to the inherited scale of the parent node. So to counter that, and rather than make my physics armature 100 bigger to compensate, I injected “descaling” nodes attached to the skeleton, and then attached my rigidbodies (and ik elements) to the descaling nodes. These “false bones” are taken into account by the ik solver as being part of the ik chain(s), causing strange results.
At this point I am seriously tempted to extend AssetImporter with an optional scaling feature, which applies a user-defined scale to all vertex and bone positions, because I think that solution is preferable to having to manually rescale all my assets in Blender or Maya, due to the promise of batch-execution.


#47

Having fixed up the zombie asset scale in blender, I am now getting “crazy legs” due to foot IK, so I probably somehow didnt scale bone positions in animations or something - I’m a Maya guy, trying to learn blender rapidly :frowning:


#48

The “crazy-legs” bug has been resolved - I now have a walking zombie, with a foot-slipping solver, and leg ik is working too! I just made my zombie walk with one foot on a slope, and the other on flat ground, and found that my foot-slipping solver works perfectly in conjunction with foot ik!
I’ll post a video soon-ish, feeling kinda burned from three days of debugging physics issues.


#49

https://www.dropbox.com/s/qzuo1wcyzylyvbz/FootSlipping.mp4?dl=0
There’s a problem with the foot ik orientation, but otherwise, everythings working as expected :slight_smile:


#50

Do you use functions such as SetRotationSilent to help the character or zombie make turns without jumpiness?


#51

No - a fun side-effect of my “foot-planting” solution allows the walking zombie to “pivot” on the planted foot while turning - it looks quite smooth and natural.
Without talking about how I detect footfalls, here is the code I am using to prevent foot-slipping.
The reason that the zombie appears to pivot on the planted foot is because I am teleporting the character’s worldspace position such that the planted foot remains planted, thus any simultaneous rotation of the body is compensated for.

void Character::HandleFootSlipping(){

    if(rightFoot_)
    {

        auto* phyWorld = node_->GetScene()->GetComponent<PhysicsWorld>();
        Vector3 leftFootPosition = leftFoot_->GetWorldPosition();
        Vector3 rightFootPosition = rightFoot_->GetWorldPosition();

        // Cast ray down to get the normal of the underlying surface
        PhysicsRaycastResult result;

        if(rightFootPlanted){

            phyWorld->RaycastSingle(result, Ray(rightFootPosition + Vector3(0, 1, 0), Vector3(0, -1, 0)), 3.0f, CollisionFilter::Static);
            if (result.body_)
                rightFootPosition = result.position_;

            RigidBody* rb = node_->GetComponent<RigidBody>();
            Vector3 slippedPos = rightFootPosition - FootPlantedPosition;
            slippedPos.y_=0; /// Deliberately ignore error in Y : respect the physics hull!
            Vector3 bodyPos = node_->GetWorldPosition();
            Vector3 newPos = (bodyPos - slippedPos);
            node_->SetWorldPosition( newPos );


        }else if(leftFootPlanted){

            phyWorld->RaycastSingle(result, Ray(leftFootPosition + Vector3(0, 1, 0), Vector3(0, -1, 0)), 3.0f, CollisionFilter::Static);
            if (result.body_)
                leftFootPosition = result.position_;

            RigidBody* rb = node_->GetComponent<RigidBody>();
            Vector3 slippedPos = leftFootPosition - FootPlantedPosition;
            slippedPos.y_=0;
            Vector3 bodyPos = node_->GetWorldPosition();
            Vector3 newPos = (bodyPos - slippedPos);
            node_->SetWorldPosition( newPos );

        }
    }
}

My current issue is that the “foot ik” is forcing the orientation of the zombie’s feet (and legs, and hips apparently) to all face in the world-z direction that was set up prior to attaching the ik elements. That is to say, the ik solver is being solved in worldspace, and not respecting the fact that I have rotated the entire character around the world Y axis!
When the player character walks up behind a zombie who is facing away from player, the zombie turns around and begins walking toward the player, but its feet (and the rest of the ik chains) remain oriented in the original direction, so now the feet are backwards, and the legs are twisted.

Here’s what the IK effector setup looks like (per foot):

            leftEffector_ = leftFoot_->CreateComponent<IKEffector>();
            leftEffector_->SetChainLength(2);
            leftEffector_->SetINHERIT_PARENT_ROTATION(true);

and here’s what the ik solver setup looks like:

        bone = skel.GetBone("Hips");
        if(bone!=nullptr && leftFoot_!=nullptr && rightFoot_!=nullptr)
        {
            Node* hips = bone->node_;//->GetChild("Descaling_Hips");
            solver_ = hips->CreateComponent<IKSolver>();

            // Two-bone solver is more efficient and more stable than FABRIK (but only
            // works for two bones, obviously).
            solver_->SetAlgorithm(IKSolver::TWO_BONE);

            // Disable auto-solving, which means we need to call Solve() manually
            solver_->SetFeature(IKSolver::AUTO_SOLVE, false);

            solver_->SetFeature(IKSolver::JOINT_ROTATIONS, true);       // Character is skinned
            solver_->SetFeature(IKSolver::TARGET_ROTATIONS, false);     // Don't align to target orientation
            solver_->SetFeature(IKSolver::USE_ORIGINAL_POSE, false);    // Don't use original pose
            solver_->SetFeature(IKSolver::UPDATE_ACTIVE_POSE, true);    // Do update animated pose

I enabled “Inherit Parent Rotation” on effectors for the following reason:

But it seems to be not doing anything :frowning:

Can anyone give me some guidance on how to make the ik solver respect the orientation of the character to which it is attached?


#52

I’ve solved all my foot-ik issues.
In my case, I needed to disable both joint and target rotations.
The following quote taken from Urho documentation apparently is not true for my use-case:

Urho documentation says that disabling joint rotations on skinned characters “will look wrong” - but I handle foot orientation myself (to align feet to slopes) as per the ik sample.
Looking good :slight_smile:

[EDIT]
Hmm, that first screenshot does look weird - I may need to do more work on this issue, I’d love to hear from anyone who has dealt with the issue - we want the ik solver to apply rotations in character space, and also to specifically omit the bones where the end-effectors are attached.


#53

I’m in a jam.
With JOINT_ROTATIONS disabled, the character’s foot orientation is coming from the bone animation, and looks correct, but the legs of the character are distorted at the knee.
With JOINT_ROTATIONS enabled, the knee looks correct, but the feet are oriented in a fixed worldspace direction, and when the character rotates 180 degrees in Y, the feet are backwards, the ik chains remain relative to worldspace so the body is contorted from the hips down.
I can’t seem to find a combination of settings that lets the ik solver apply joint rotations correctly on a bone-animated skinned character. Somehow, I need to inform the solver root node to inherit the orientation of the character, not to operate in worldspace but to operate in characterspace.

I guess I am running out of options, the only thing I haven’t tried is ik target orientation. I guess I could compute the orientation of the target, but it seems like overkill, and likely I’ll lose the animated orientation of the raised foot (which flops around adorably). I was hoping not to have to solve foot orientation as part of the ik solver. Love to hear from you guys about it.


#54

My view of zombies and kinetics is stilted … I mean why mess around with lots of details when you can do it in one slap?

zombies


#55

Eventually, I did find settings for foot ik that work on an animated skinned mesh that has a dynamic physics controller.


            solver_->SetFeature(IKSolver::JOINT_ROTATIONS, true);      // Character is skinned - we care about rotations
            solver_->SetFeature(IKSolver::TARGET_ROTATIONS, false);     // Don't align to target orientation
            solver_->SetFeature(IKSolver::USE_ORIGINAL_POSE, false);    // Don't use original pose
            solver_->SetFeature(IKSolver::UPDATE_ACTIVE_POSE, true);    // Do update animated pose
            solver_->SetFeature(IKSolver::UPDATE_ORIGINAL_POSE, true);  // Do apply the solution to the original pose

That last one was required to ensure that the ik solver respected the orientation of the character when JOINT_ROTATIONS is enabled :slight_smile: I truly hope that this information is useful to anyone who attempts to deal with a similar scenario - the ik sample does not use these settings, but then again, that character never moves or rotates.


#56

My player character derives from the same class as non player characters (well, not quite derives from, there’s currently an isPlayer flag, and some switchcase logic, though I plan to derive soon) - I’ve now applied all this foot-ik and foot-slipping stuff to the player character, who has more locomotion animations than the zombies.
It’s a bit twitchy sometimes, and the feet appear to be bent too much on some slopes, but I have not yet tweaked the ik settings (they are default values), or closely examined the foot orientation stuff.

I’ve got two outstanding issues at the moment - walking downhill looks wrong because the character outer hull prevents the front foot from reaching the ground (I think I can tackle this one easily enough), and the animations for walking forwards and strafing sideways are incompatible - they have the same length, but the footfalls are not on the same keys, so blending them leads to bad-looking results.

Manually cutting and pasting a few keys should bring my animations into synch, and moving the outer hull down to satisfy the lower foot should let the leading foot reach the ground when travelling downhill / walking down steps.

I’m tempted to remove the outer hull altogether, in favour of ragdoll bodypart hulls - but that turned out to be a bad idea in terms of detecting footfalls on a staggering (shuffling) zombie, as it was difficult to tune the foot bodies for clean make-and-break with a level surface, let alone uneven terrain.


#57

Insight from the work of others:
Here’s how I plan to deal with walking “downhill”.

Anytime in our walk cycle, we can measure the height of the ‘unplanted’ foot with respect to a theoretical level plane (lets call it A - in my drawing its zero, so I don’t show it). We can also measure the height from that plane to the terrain surface - this is our error term, B (shown in red).
We want to move the root of our character DOWN, such that the height from the terrain to the unplanted foot equals A (I believe this is simply pelvis Y - B, plus accounting for the foot offset, since the foot bone is really the ankle, and is never equal to the plane Y). We want to do this immediately after animation is applied, but before IK is applied. The result should be that the unplanted foot has height A above the terrain, and the planted foot, and its leg, bend further to make that happen.

The proposed solution was borrowed from Unreal engine.

StepDown

Super sorry for my terrible coder art, but the final result from the proposed solution would be something like this golden thing: (noting, I don’t think we need to lean forward and backward at this stage)
StepDown2

This solution violates the length of a single step in the walk cycle with respect to the animation, but I suspect my foot-planting solution will compensate somewhat for the error, and IK solver will at least try hard to do the rest. Essentially, we will take longer steps when moving downhill, as we already take shorter steps when moving uphill - the animation speed is already tied to the velocity of the hull, and it all should “just work” - maybe.

The foot-planting solver is tied to the animation speed, and adjusts the velocity of the hull (through sheer position teleport) to tie in with footfall triggers in the animations. It effectively “post-empts” the velocity of the hull, and compensates for weirdness in walk cycles. I’m sort of crossing my fingers, but in my engineers mind, there are two levels of compensation on top of basic dynamics, it might just work (on slopes or stairs that climb by a max of 30 degrees per step) :slight_smile:

I’ve not needed target orientation for orienting feet so far, and trying hard to resist predicting footfalls (like some other solutions do) as I don’t want to analyze animation keys unless I have absolutely run out of options. I don’t need perfect accuracy, just fluid motion.


#58

I’d like someone to doublecheck my logic before I code this up, perhaps it can be optimized.


#59

I wonder how this approach will work on steep slopes, stairs and cliff edges.


#60

It should work well on slopes of (+/-) 30 degrees or less, and stairs, and obstacles, where the “rise over run” is 30 or less. I expect it to work terribly on slopes of 45 or more degrees (which we typically can’t climb with a dynamic controller) - but the typical “rise” on staircases happens to be 30 deg.
It won’t work for cliffs :stuck_out_tongue: It won’t work for Quadrupeds, or for spiders, although I am certain that a similar algorithm could be evolved that can cope with more than two feet (Final IK for Unity manages to do so, therefore it can be done).

I did mention, this technique is not mine - my description of the technique is all I can lay claim to, this stuff was based on a solution that ships with the Unreal engine, and is described somewhat in the documentation.

Also, I expect to have to modify the existing foot ik logic, which makes assumptions about where we want to plant the ik targets for the feet, but I expect that to be trivial, and indeed, I expect to marry the proposed and existing code to eliminate redundant raycasts (my foot-slipping solution runs just after the foot ik solver, and requires a ray be cast from each foot, so I already have something to eliminate in the name of efficiency).

Finally, I have a gut feeling that I’m going to need to execute the IK Solver twice, to deal with the fact that the unplanted foot becomes unplanted when it is leaving the ground, which on a theoretical plane, sets it inside the terrain on a downhill slope.
I hope to take advantage of the foot-planting positions to avoid that, by remembering not just where the current planted foot is, but where the previous planted foot was. I may need to start using more than two keys on my animation triggers (Unreal uses four). The algo as presented will likely be refined. Etc.


#61

I disable the foot IK stuff when jumping - in debug it looks very funny to see the IK legs stuck to the ground while the character and its physics body (or bodies) are jumping. Falling is equivalent to jumping, if I have to deal with cliffs, and my character is not a spider, I should be ok - maybe.


#62

One issue with the primitive collision hull (character capsule), due to my foot-planting solution, is that its fairly easy to teleport through solid walls. Effectively, I am teleporting the hull to compensate for the planted foot. CCD could help here. I remember bugs in Star Wars : Battlefront (the first one) that could be explained by this. There were quite a few. (One of my teachers, during my bachelor degree, worked on KOTOR, and Sims 3, he had plenty to say about bugs and deadlines).
I am sorely tempted to eliminate the character hull in favour of potential ragdoll bodypart hulls, and discounting the extra processing cost in terms of “hey, I know what bodypart I hit, I can do a partial ragdoll on that”