Attempting to Calculate Center of Mass

A bit of background:
I am working on a M.A.Sc. Biomdedical Engineering degree and part of my thesis makes use of motion capture data. One of the main pieces of information I need out of that data is the center of mass of the human I am capturing the motion of. As the motion capture software can’t calculate this on its own I have slowly made my way towards attempting to use Blender to help with this. I can get my data into C3D format and am looking at the c3d_import.py script that comes with Blender.

What I am hoping to do with Blender, through extending the c3d import python script, is get the geometric center of each bone in the armature that is created by the import script and use that to calculate out center of mass.

I suppose, if I were to summarize, that I have two main issues as far as understanding the API enough to get this done. The first, is that I am assuming this import script is creating a pose for each frame of capture date, but I haven’t figured out how to verify that. The second is that I can’t seem to find a clear enough explanation of the API to understand how I would get about getting the geometric center of the bone (I am using octohedrons) through from whithin my Python code.

My best guesses are that I should loop through each frame, get the pose for that frame, get the bones for that pose and then use the quaternion of the bone plus the matrix of the bone in the rest position to calculate the geometric center? I am just hoping there may be someone with much more expertise and experience who can help guide me through this.

Hopefully I’ve managed to explain things clearly enough and haven’t misused any Blender terminologies.

Thanks for any help you can provide.

Assuming that bones have uniform density along their length and that other body structures such as muscle, organs, etc. have 0 mass then your method could work.

I think that a bone’s position is given as it’s base (head). In this case, you could use the “head” and “tail” properties in the PoseBone class to find the centre of each bone and use the bone’s “length” property to calculate a kind of ‘bone mass’. Weighting the positions of the centres of the bones by the calculated ‘mass’ and averaging them should give a centre of mass. Check here for details on the PoseBone class. It’s in the Pose module.

An alternative assumption that you could make would be to assume uniform density within your mesh. This would be a more difficult approach because it is difficult to retrieve the mesh data of an armature deformed mesh, but might provide more accurate results because the ‘bulk’ of your character would be allowed for (ie. fat people, muscly men with the V-shaped chest, large breasted women, etc.) It might be possible to duplicate the object and apply the pose to the mesh data before finding the mesh centre of mass or even write a script to run in the game engine that records centre of mass for each frame (I think that deformed mesh data is more easily retrieved from the game engine than from the Blender editor). I attempted to write a script that finds the centre of mass of a triangulated mesh here, but got no feedback so I’m not sure how well it works.

Hope you find a solution. :slight_smile:

Edit: Incidentally, if you get the bone head/tail positions directly from the armature, I think you’ll find that they are only available in rest position. To get the position of a bone after a pose has been set, you need to use the PoseBone class. This class will give the bone position considering interpolation between frames so I don’t think that it’s important to know if there is a pose set on each frame, bone position will be interpolated anyway if no pose is set on a given frame.

Hi FunkWyrm. Yes, that is more or less the assumption I will need to make (uniform density). The octohedron, to me, seems like a reasonable analogue to the human extremeties at least, shifting CoM slightly towards the head of the bone compared to geometric center. However, as I’m unaware of anything in the API that would allow me to get the full dimensions of the octohedron, I may have to settle for calculating the center of the line from head to tail as you suggest.

I don’t have a mesh, so I think I will need to deal with the PoseBone class. Looking at the API, I see there is a PoseBone.head and PoseBone.tail. Can I assume these are in world coordinates rather than local bone coordinates? If so, I believe due to the assumptions of uniform density and symettry of the human bones I can ignore the rotation of the bone entirely and calculate its center.

As for weighting, there should be a lot of physiological data regarding percent of total body mass of various segments of the typical human body. I will use that get overall CoM.

Now, for another question. If I wanted to loop through all of the frames would I do something along the lines of:


Blender.set('curFrame', i)
getposebone
calcbonecom
updatetotalcom

The unknowns in that pseudocode would be how do I get the posebone object? Also, do I need to update the scene or something after setting the current frame?

Thanks again