Animated model's geometry is not updated offscreen

Hi fellas, I have an small issue, let me explain my situation.
My enemies are composed by a basic skeleton model and several armature parts that are attached to the skeleton attachment nodes.
Trying to do some optimizations, as soon as the “Die” animation finishes I attach the enemy node to the current room node (level is spatially divided in rooms) and batch the whole thing so all the dead bodies became one object instead of several (material is shared among enemy parts).

So far it works as expected, however if I turn the camera away from the enemy while it’s dying (I have heart you know :chimpanzee_cry: ), let the animation go through and turn back to the dead body, the skeleton model is standing still in a “Classic Lorne Green death pose from Battlestar Galactica” and all the attachments are OK in their terminal position.

Apparently the mesh is not updated when not necessary, and that seems fine, I think I’d need some way to force the mesh update before batching the node, but I don’t see how.

I made a test to show the problem, TestOgreAnim.java · GitHub
Space to start the animation, look away, wait 2 seconds and look back, you’ll see the robot is not fully down but the red attachment is.

Thanks.

1 Like

Have you tried to set the cullHint of the dying people to Never?

Thanks, that worked out!
Inside the listener I set the CullHint to Never and then wait some frames to do the batching and setting back the CullHint to Inherit.
This way the enemy is rendered only after is completely dead for a short time.

Alternatively another solution I just tried was to force an update of the mesh by manually calling the “controlRenderHardware” or “controlRenderSoftware” (depending on what is set) once as soon as the animation finishes.
The downside is that I needed to use reflection as those methods are private in the SkeletonControl, hacky but I didn’t find any error yet.

1 Like

It would be less hack to force call controlRender() on the spatial.

Possibly, yes.
But it’s also good to consider it receives a RenderManager and a ViewPort, the ViewPort isn’t used apparently. And the RM seems to be used for testing hardware skinning capability, although it’s checked just the first pass.
I would have to call controlUpdate(null, null) and I would depend on those assumptions to be maintained in future jME versions (of course calling a private method is dangerous too).

Thanks.

No… you would have to call controlUpdate(rm, vp) with the appropriate values. Which you should already have easy access to wherever you are doing just about anything else… but especially in simpleRender() or an AppState’s render method.

Somewhere you are calling your hack. I don’t know where that is so I can’t provide more specific information but it has to be somewhere where you have access to rm or vp or you have done something odd.

And actually, setting to CullHint.Never is not a bad way… very few down sides.

I’m calling my hack from the AnimEventListener as in the code posted before, I guess that’s called from the anim control update.

Yes, I think I may stick with this solution.

…then it’s kind of too early anyway.

Yes, plenty of large assumptions going around now.

Two things will always work:
-setting the cull hint
-calling controlRender() with proper values at the appropriate time.

One of those is really easy, though. :slight_smile: