Advertisement

Generating skeleton bind pose from vertex weights

Started by January 11, 2019 11:33 AM
6 comments, last by Septopus 6 years, 1 month ago

Assuming that you know how many bones should be in the skeleton, and you have the bone hierarchy, is it possible to calculate the bind pose of the bones just based on the vertex weights?

To elaborate it a bit, let's say you have a skinned mesh, and each vertex of this mesh has 4 weights (at most). So you have 4 weight values and 4 bone ids for each vertex. Also let's say you have a skeleton with 10 bones, and all you have is the bone hierarchy. You need to position the bones to match the mesh (bind pose).

I am wondering if this can be done just using the weights/bone ids? I don't know how to approach this so any idea is appreciated.

Thank you.

There are an unlimited amount of poses that can satisfy those conditions, if you're looking for a specific one, you don't have enough information to reconstruct your pose.

What is it that you're trying to do? If you're trying to automatically generate a rig, this paper comes to mind (comes with source and binary files).

Advertisement

I want to calculate just approximate positions. If you think of it like a humanoid model, for example the left shoulder vertices would have weight values nearer to 1.0 (0 - 1.0 range weights) for the left shoulder bone. This is quite normal because the left shoulder bone would generally effect the vertices near the left shoulder most. Of course left elbow vertices might have weight values for this bone too, but they wouldn't be as "strong" as the vertices in the shoulder area. So based on this, can't we say that the left shoulder bone should be located approximately where the left shoulder vertices are (like in the middle of them)?

I would like to do this for every bone and position them as good as possible just based on weight values. Do you think this makes some sense? I was not sure, so I wanted to get some opininions.

It just depends how accurate you want to go for. You can estimate a rough centre of mass for each bone by using something like this:


// for through bones
for (int b=0; b<32; b++)
{
  Vertex3 ptAverage(0, 0, 0);
  float fTotalWeight = 0.0f;
  
  for (int n=0; n<nVerts; n++)
  {
    // for through weights
    for (int w=0; w<4; w++)
    {
      if (vert[n].boneID[w] == b)
      {
        ptAverage += vert[n].pos * vert[n].boneWeight[w];
        fTotalWeight += vert[n].boneWeight[w];
      } // if
    } // for w
  } // for n
  
  ptAverage /= fTotalWeight;
  print ("AveragePosition of bone " + b + " is " + ptAverage);
}

You can also estimate the orientations of the bones by e.g. making a guess of a orientated bounding box, guesstimate some joint positions etc.

17 minutes ago, cofenen said:

So based on this, can't we say that the left shoulder bone should be located approximately where the left shoulder vertices are (like in the middle of them)?

You could do a weighted average for the position and maybe use a covariance matrix to determine the length of the bone? It's impossible to tell if that would give you the results you're looking for.

 

31 minutes ago, cofenen said:

I would like to do this for every bone and position them as good as possible just based on weight values.

Why do you only have weight values? What is the reason you have/want to take this route? I'm asking because there might be a better way to achieve your goal.

Thank you very much for both of your answers. Really great community you got here :D

@lawnjelly That snippet really helped me understand how I can go with this. I am also curious about what you said for the orientation. Could you also share an example code for that when you have the time? Positions are something, but I get really confused when it comes to 3d rotation stuff. An example would help a lot. Thanks.

1 hour ago, Mussi said:

Why do you only have weight values?

I am reading the model data from an undocumented binary format. All I have is vertices/indices data, and bone count/hierarchy. I am pretty sure no bind pose bone position/orientation is stored. Animation files might have these values, but I don't want to bother with those at all, and also there is no guarantee that they store the bind pose (maybe first frame but doesn't have to be). So vertex weights seemed like the only way to me.

Advertisement
2 hours ago, cofenen said:

I am reading the model data from an undocumented binary format.

Undocumented, why again?  (As in, I hope this is approved by those who didn't document it..)

This topic is closed to new replies.

Advertisement