tonihele / OpenKeeper

Dungeon Keeper II remake
GNU General Public License v3.0
437 stars 42 forks source link

Migrate to the new animation system #362

Closed tonihele closed 1 year ago

tonihele commented 4 years ago

Migrate to the new animation system. It supposedly comes with some goodies, and our morph animations are supported out of the box as well as hardware accelerated (?). Should be worthwhile to check it out, at least to get rid of the warnings.

Some write up about the new animation system: https://hub.jmonkeyengine.org/t/monkanim-v2/39877

Also the place where the magic is currently done is in the KmfModelLoader.

tonihele commented 4 years ago

Not as I would have hoped.... I assumed we can use the new morph animation & hardware acceleration straight... But that is a no-go. The morph animation supports kinda whole poses, and you are not supposed to have a lot of them. Up to 14 (well simplification, the rules are a bit more complicated than this...) could be hardware accelerated via the default shader that we are also using.

The problem is that we have a lot of poses in a way. The DK 2 system is very fine grained, it animates specific subsets of vertices between the frames. Thus creating a huge number of complete poses if you translate them to complete poses that is. I tried with the Fairy dancing and it went to 1700 poses (start and end both). That is a no-go. One could with very complex algorithm to try to compress these to smaller amount, combine etc.. But that alone would also be way more than 14 poses and bloat the saved binary.

If you profile OpenKeeper, this pose animation running is what we mostly do, so that is why I'm a bit disappointed. But yeah, we should anyway port our Pose animation to the new animation system anyway.

Trass3r commented 2 years ago

How does that AnimMigrationUtils.migrate(model) handle this then? https://hub.jmonkeyengine.org/t/pose-animation-deprecated/42031

tonihele commented 2 years ago

It doesn't, right? https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/anim/util/AnimMigrationUtils.java.

Also does what? :D The only problem I encountered is that the support for the LoopMode is non-existent and it can't be emulated properly due to a bug/missing feature.

The vertex animation? That I have thought sometimes that if we could do our own Fragment shader. We could feed the animation data as it is in the KMF file (it is packed very nicely) and just have it play on the GPU itself rather than spending a lot of time feeding vertex data to GPU on each frame... But this is just a theory. I have no idea how much memory that would use on GPU and does it really benefit...

Trass3r commented 2 years ago

Ah yeah true looks like that migration script just handles skeletal animation.

Trass3r commented 2 years ago

Regarding vertex animation, for the record:

I remember initially we had all frames as full meshes, like full vertex data for each frame. That was really inefficient. Then we just went with the key frames per group of vertices like in KMF. There can be multiple sub animations in progress each mesh frame. Calling it a key frame may be misleading in this case. We move the vertices of the animation mesh on the CPU each frame and upload them, that's fairly expensive. For the future, my idea would be to transfer this kind of lookup table to the GPU (https://github.com/tonihele/OpenKeeper/blob/master/src/toniarts/openkeeper/tools/convert/kmf/Anim.java#L62) <-- the original file format BTW

The polygon counts are tiny by today's standards and just brute force uploading all frames as whole meshes to a VBO (and switching between them) will probably be faster (and easier to implement) than all those dependent lookups to unpack the KMF data on the GPU, see here. Also HD replacement models in some future would be normal skeletal animation based anyway.

I guess one could also do a hybrid solution. Precompute all possible vertex positions and then only switch the index buffer for each frame, very similar to what my KMF export script does. Would require custom vertex fetch with exactly the kind of index packing described here: https://forum.beyond3d.com/threads/programmable-vertex-fetching-and-index-buffering.57591/

tonihele commented 1 year ago

Fixed via #412