[SOLVED] Ray collision on animated mesh

Hi there,

I have particular problem with animated model, probably someone already asked this before but I’m unable to find appropriate topic.

My imported model consist of several parts, everything is named, rigged and have animations on top of that. Picking (be it by cursor or “crosshair camera”) using jMonkeyEngine 3 Tutorial (8) - Hello Picking :: jMonkeyEngine Docs snippets work, but only when model isn’t playing animation. When it does unfortunately picking doesn’t seem to work on “updated” animated model. Debugging material in wireframe only confirmed this issue.

Is there a clever way to “pick” model parts while they’re animated?

You can pick one of two things:

  1. pickable animated meshes
  2. efficient hardware skinning

…you cannot have both.

If you do not need (2) and require (1) then you can turn off hardware skinning for the model.

1 Like

Thanks for fast reply! Could you point me to appropriate tutorials how to do any of those, because for now I have no clue what “hardware skinning” even means.

EDIT: lurking through examples I’ve managed to disable hardware skinning for my armature via SkinningControl, unfortunately it does nothing.

You could use each major bone’s attachment node to attach simple collision shapes that match the model as close as possible. This is how I handle collisions with animated models in my rpg project

Here you can see how I have separate translucent quads attached to the lower arms, forearm and main body that follow the animation, and at run time they’re culled so they don’t get rendered but still register collisions with Rays and BoundingVolumes.

You can also set this up entirely in the SDK’s scene editor for each model. Although you’d still have to code your game to have rays collide with a list of these hitbox quads instead of the whole model of course.

3 Likes

That’s great idea! Also I didn’t know you can tinker with scene editor for this purpose.

Unfortunately it would mean I have to manually make box for every part I want interact with (and some even don’t have their own bones so it would mean even more tinkering).
And I don’t even want to think about animations that change mesh size.

I thought about making model with already attached “hitbox”-objects what would be culled in game, bound to same rig so they’re somewhat animated. But then again - I can’t force JME to pick animated mesh which brings me back again to problem from my first post.

Well, my mesh is not complex to begin with and I don’t really need to make additional bounding hitboxes. While idea is simple figuring out what to do with outdated tutorials and wiki is completely different issue.

I made simple proof of concept and it works pretty neatly with solution you’ve provided.

Biggest problem remains that it makes me to manually (either in JME scene editor or programmatically) create every hitbox zone (and it won’t work in some particular cases).

If there is something else that might be more precise and workload-friendly it would be most appreciated.

1 Like

Sorry, I didn’t know what version of JME you were using, etc… so instead of typing up 4-5 different answers I left it as an exercise for the reader. It seems you were able to find it so that’s good.

Assuming it is really disabled, you may also need to clear the collision data so that it recalculates.
https://javadoc.jmonkeyengine.org/v3.4.0-stable/com/jme3/scene/Mesh.html#clearCollisionData--

The various things that take CPU time to get ‘pixel accurate’ animated mesh collisions are why it’s appealing to use the suggested solution of simplified collisions shapes attached to the bones.

The other downside of ‘pixel accurate’ animated mesh collision in a game is that it means the bullets/arrows/etc. will collide with capes and hair and other random bits… which is what the simplified shape solves also.

1 Like

I used node crawler for my scene that checks and sets:

SkinningControl sc = s.getControl(SkinningControl.class);
if(sc != null) {
    sc.setHardwareSkinningPreferred(false);
}

and

if(s instanceof Geometry) {
  Geometry g = (Geometry) s;
  g.getMesh().clearCollisionData();
}

both called before even adding scene to rootnode.
It doesn’t work at all.

I’m using jMonkeyEngine SDK v3.3.0-stable with embeded java 11.0.6; OpenJDK Server VM 11.0.6+10

You have to clear the collision data every time you want to pick it. Else it will be stale.

1 Like

Oh, so it has to be re-calculated, I get it now.

This is awesome, now everything works as intended!
I send all of my love to kind and helpful people in this thread, you’re the best!

Thanks,
– Obama.

4 Likes

Obligatory: “Thanks, Obama”

4 Likes