Exporting for games. Weighting issues

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

Post Reply
Llerd
Posts: 2
Joined: Sat Oct 08, 2016 1:07 pm

Exporting for games. Weighting issues

Post by Llerd »

Hi,

We are developing the game http://pinballstories.com and we using Anime Studio for animations. To use these animations in the game, I've reverse-engineered the Anime Studio format to import that into our engine (thanks for choosing a text-format, and also for going json!). We only use limited feature set (bone and layer move, rotate, scale, visibility, switch-layers, anim-offset and actions) and things work pretty good. However, we felt that we needed soft-body animation as well, so I've taken at stab at implementing flexible binding. I'm pretty close to replicating the same behavior in our game, but there is some issue with weighting.

In the base-pose, I generate vertex-weighting per bone in a tessellated version of the layer. There doesn't seem to be too many variables: the bone-start/end position, bone-strength and bone-length. The starting algorithm I have right now is:
weighting-strength = 1 / ([distance between vertex and the line-segment(bone-start, bone-end)] + 1)

However, this algorithm does not take into account bone-strength and bone-length which also seems to affect weighting, and I can't seem to get them to fit in. I bet the underlying algorithm is quite different and can't be applied in the same way, but any insight on how weighting is calculated in Anime Studio would be of great use to me.

Also, if there is interest, I can in return share my importer for others to use as reference code, as I really think Anime Studio is a great tool for use in games.
Llerd
Posts: 2
Joined: Sat Oct 08, 2016 1:07 pm

Re: Exporting for games. Weighting issues

Post by Llerd »

Alright. After a ton of time spent reverse-engineering this behavior, I'm fairly close. Pseudo-code is:

Code: Select all

foreach layer in layers
{
  vertices = tesselateMesh(layer)
  foreach v in vertices
  {
    foreach bone in bones
    {
      d = bone.GetAsLineSegment().GetDistanceTo(v) / bone.boneStrength
      v.weight[bone] = bone.boneLength / Sqr(1 + 50 * Sqr(d))
    }
    v.weight.normalize()
  }
}
 
With some tuning, this algorithm is probably close to good enough for us. Of course, any help provided to understand the actual algorithm would be very appreciated.
Post Reply