Archive 17/01/2023.

Animating Collisions?

Alex-Doc

Hello,
let’s suppose we have a 3D model, which has an animated part(bone) and we want it to push the other RigidBodies.

As (by design?) this will not work as I expect it:

< Main Node >
    < rigidbody />
    < collisionShape />
    < AnimatedModel />
    < Child Bone Node >
        < other collisionShape />
    < /Child Bone Node >
< /Main Node >

Adding a second non-trigger RigidBody to the child node it’s probably not a good idea,
how would you normally overcome this?

So far, the only solution I have in mind, is to add a RigidBody to the Child Bone Node as a Trigger and manually check/apply the collisions.

Any ideas?

Lumak

Isn’t having char capsule sufficient enough to know that you’ve collided with a “push-able” object and transition to push-anim state?

Alex-Doc

Not in this case, I better explain:
Imagine the model as an AT-ST from Star Wars (the biped robot thing), we want the player to be able to pass between the legs but also the legs to collide while it “walks”.

The model in question (biped) is not the player.
The player just has a capsule as usual.

Lumak

I see. I know you discussed using static collision objects on another thread, that didn’t work? If not, apply kinematic to it.

Alex-Doc

That was referred to collisions between triggers, no forces involved.(I’ve used that for melee weapons)

I know I could just set the children bodies as Triggers and use the contacts to apply the forces, but I’d like to know if there’s some other way.

Basically I’m looking for a way to tell physicsWorld to ignore collisions between two bodies, I know I could do this with masks, but I want it to be limited to the node’s children.

Setting the children Rigidbody to kinematic makes the simulation go crazy, as the “main” body is set to use physics.

Lumak

Try this:

ColLayer_Static     = (1<<0),
ColLayer_ATST       = (1<<6), // just as example
ColLayer_ATST_Parts = (1<<7),

ColMask_ATST         = ~(ColLayer_ATST_Parts),
ColMask_ATST_Parts   = ~(ColLayer_Static | ColLayer_ATST | ColLayer_ATST_Parts),

also ATST parts:
kinematic, apply gravity = false, linear factor = 0, angular factor = 0, and mass > 0

edit: added collayer_static and atstparts to not collide with it

Alex-Doc

Thanks, I’ve already thought about setting the collision masks but I’d have preferred if the “ATST part” VS other node “ATST part” case, would have collided.

I have also wondered about adding the ignore list functionality to PhysicsWorld but I don’t see it so good performance-wise:
Something like having each body to preserve a Vector of Rigidbody pointers and check if it should collide or not.

Lumak

I’m trying to understand why you’d desire to have atstpart vs atstpart collision. So say you have upperleg, leg, and foot - you’re wanting the leg and foot to collide as it walks? I know you are aware that collision resolver will try to separate them.

edit: i thought you were referring to the ignore list as the rigidbody settings, sry.

Alex-Doc

I mean to have two separate instances of ATST collide:
ATST0 foot, able to collide with ATST1 body.

That would exclude the Mask and Layer settings as I want them to only ignore the children Rigidbody recursively.

This introduces the ignore list feature, pretty much consists of:

RigidBody has a

Which can be used as:

RigidBody* body = node_->GetComponent<RigidBody>();
RigidBody* other = GetOtherBodyExample();
body->AddToIgnoreList(other);
other->AddToIgnoreList (body);

And finally, where PhysicsWorld processes the collisions, it does a check of Rigidbody’s ignoreList content and decides whether to apply forces and report the collisions or not.

Lumak

You know, I didn’t know what ATST looked like and had to look it up when you first mentioned it, but for one ATST to have its foot on another’s body either the 1st is doing some high kicks or the 2nd is dead? If the 2nd is dead and in a ragdoll state then it’s easier problem to solve.

And I agree, your ignore list check would eat performance.

Alex-Doc

The AT-ST reference is more about having an exaggerated example of body+legs collisions, the actual in-game models are more generic and various.

At this point I think the best way would be to work-around it where possible and use triggers or masks on the “foot” where unavoidable.

The last doubt I have is about the animated and kinematic RigidBody with the Mask/Layer configuration:
Would it push non-kinematic RigidBody in a strange way?
I will test it later today and report here.

Alex-Doc

I might have found the solution:
I could make the RigidBody to have the ignore list in its members and then,
I can probably add a custom NearCallback in PhysicsWorld.

see here and here

Surely it can impact performances, but I don’t think it would be that worse than a Trigger calling collision events to apply forces on each physics tick.

Lumak

Best solution is to use Constraints and not have connected bodies collide with each other, see 13_Ragdoll/CreateRagdoll.cpp, line 164.