Rag doll mesh deformation theory. NOW FUNCTIONING!!

I’m updating this first post with a link to my test .blend. Here it is:
QuaternionTest_254_Final.blend

The implementation is a bit different from the method outlined in the post below, but is now fully functional. See my later post for a full description.

Original post follows:


I’ve been away from Blender for a while so that the 2.5 series API can stabilise a bit, but have recently become inspired to attack the rag doll mesh deform issue again.

I’ve searched around and it seems that there is still no facility to deform a mesh using physics (like blowing up npcs and having them crash into walls and draped over scenery etc.). If there is any progress on this elsewhere then I would appreciate a link.

My theory is to construct a rigid body network that corresponds to the structure of an armature. It would haveone rigid body for each bone with rigid body joints connecting the netwok into an amature-like structure on which physics calculations can be run When the npc is killed there will be a trigger that stops all actions on the armature, tuns off the regular object collision and activates the rigid body structure. The rigid bodies that are linked together will respond to physics and the environment like a rag doll. Since each rigid body corresponds to a bone in the armature, the rotation of each rigid body can be used to set the rotation of it’s corresponding bone. This would drive the armature and hence deform the mesh using “rag doll physics”.

The main issue with this approach is that bone rotations can be get/set only in bone space. The orientation of a bone’s space is dependent on it’s initial orientation and how that orientation has been rotated by each bone closer to the root bone.
ie. The rotation of the foot bone is given relative to the bone space of the foot bone, the bone space of the foot bone has been rotated by the lower leg bone, the lower leg bone has in turn been rotated by the upper leg and the hip before it reaches the root bone at the end of the chain.

Taking all this into account, I have made some notes. Any thoughts on this would be appreciated.

The issue is each bone’s orientation is given in it’s bone space. The bone space has been rotated from it’s rest orientation by each bone in the hierarchy down to the root bone.
Need to find the rotation of each bone in bone space.

#######################################
Formulae used:

To apply a rotation use the sandwich product:
Qo0 = quaternion representing starting orientation
Qo1 = quaternion representing resulting orientation after first rotation
Qo2 = quaternion representing resulting orientation after first rotation then second rotation
Qr1 = quaternion representing first rotation to be applied
Qr2 = quaternion representing second rotation to be applied

First rotation:
Qo1 = Qr1 * Qo0 * Qr1.inverse

Second rotation:
Qo2 = Qr2 * Qo1 * Qr2.inverse

>> Qo2 = Qr2 * (Qr1 * Qo0 * Qr1.inverse) * Qr2.inverse
>> Qo2 = (Qr2 * Qr1) * Qo0 * (Qr1.inverse * Qr2.inverse)

>> Qo2 = (Qr2 * Qr1) * Qo0 * (Qr2 * Qr1).inverse

(Note reversal of Qr1 and Qr2 in the right hand of the sandwich product when taking the inverse of both
components together.)

Subsequent rotations can be applied in the same way, see combining rotations below.

Combining rotations:
R = total rotation
R0 = root bone’s rotation
R1 = first bone’s rotation
RN = rotation of Nth bone

R = R(N-1) * ... * R1 * R0
R.inverse = R0.inverse * R1.inverse * ... * R(N-1).inverse (As required for sandwich product.)

Note:
For unit quaternions, as used to represent rotations, the conjugate is equal to the inverse. Since it
is a faster operation to find the conjugate compared to finding the inverse and all quaternions are unit,
quaternion.conjugate will be used instead of quaternion.inverse in the final code.

#######################################
Procedure:

1>> Find orientation of bone space in the global frame. This is not provided by the game engine so needs to be calculated.
Orientation of bone space can be determined by applying all rotations of all parent bones in the global frame to the rest orientation of the bone in the global frame.
spaceRotation represents the rotation required to transform the bone space from rest to it’s current orientation.

spaceRotation(of bone N space) = bone(N-1)rot * ... * bone1rot * bone0rot
boneSpaceOrientation = spaceRotation * restOrientation * spaceRotation.inverse

2>> Find rotation from rest in the global frame by applying the inverse of the rest orientation to the current orientation. This will rotate the current orientation so that the deviation from the identity will represent the rotation from the rest position in the global frame.

rotationFromRest = restOrientation.inverse * currentOrientation * restOrientation.inverse.inverse

The inverse of an inverse gives the original value so simplifies to:

>> rotationFromRest = restOrientation.inverse * currentOrientation * restOrientation

3>> Apply orientation of bone space to rotation from rest to convert rotation into bone space.

boneRotation = boneSpaceOrientation * rotationFromRest * boneSpaceOrientation.inverse

#######################################
Final notes:
All of this code is required because bone rotations can only be set in bone space.

This procedure would be greatly simplified by the facility to get/set bone orientations in global space
in addition to the current single option of bone space. If coded into the game engine in C/C++ this would
probably have a far faster operation speed.

Using the current orientation of the rigid body object whose rest orientation corresponds to the rest
orientation of the bone, it would be a simple matter of using the following line of code for each rigid
body/bone pair to apply the ragdoll effect to the armature/mesh:

bone1.worldOrientation = obj1.worldOrientation

Edit:

To clarify…

restOrientation
is the rest orientation of both a bone and it’s corresponding rigid body object in the global frame of reference (world space).

currentOrientation
is the current orientation of a rigid body object that will be used to calculate the rotation of the corresponding bone in the global frame.

spaceRotation
is the combined rotations of all bones from the root to the curent bone being considered in the global frame.

rotationFromRest
is the rotation required to rotate a rigid body object from it’s rest orientation to it’s current orientation.

boneSpaceOrientation
is the orientation of a bone’s space in the global frame of reference. If a bone had no rotation in it’s own bone space, this would be it’s world orientation. We need to set the bone’s rotation relative to this orientation.

boneRotation
is the whole point of the exercise. This is the rotation in it’s own space that a bone has to have in order to have it’s correct final orientation that corresponds to the orientation of it’s rigid body companion object.

Everything’s possible! I agree on that!!! :spin:

Now to your task… I think its a quite big one! Im not saying it wont be possible to fake in Blender a proper rag-doll tests. This will require a lot of preparation and set-up work though. Are you planning to use Blender’s internal physics engine? I’ve heard there is one but Im not quite sure how realistic it is and how to control it totally. For rag-doll tests you’d need more that a total control of everything in the scene so that you know what is really happening and if it is truthful or wrong, how wrong, etc.

The idea of having a rag-doll constructed by separate object for arms, legs, etc. is pretty good! I think that’s the best for the purpose. I have made several robots on this logic - parts are different object (see here) but not for that purpose although I though on your direction as well, i.e. collision effects, how to fake the object is hard/soft, etc. Apparently, there is a problem to faking strength on integrity of the whole body (doll). Sorry if certain terms I use are not quite correct ones in English but this is not my first language… What I mean is after a collision at rag-doll tests, depending on the speed, mass, force(s) the doll may get disassembled (that is the main purpose of such test, right?)… Sooo you need to have data (thresholds of stability or resistance) at each joint of the armature. For this situation, perfectly, your bone set-up should NOT be of connected bones! And at each part and each bone joint you should have a correctly set-up limits of deforming the object, holding objects together and such… That’s a tricky part, I think… Cause I dont really have such data!!! But once established, another hard part comes - calculating the collision effects: when it happens (geometry), forces of collision, resistance of parts (possible deformations) and if certain parts will fly away of the whole body (disintegration) plus where should they fall and under what trajectory… Your mathematical and mechanical model should be very truthful and stable… Phewwww… :cool:

As I said in the beginning - ALL this is possible! Only HARD work for the designer and computer(s). As soon as I have more to say here (and the time) I’ll share more of my thoughts on the matter, if you like so :yes:

Regards,

Have you tried making each bone copy Location of its rigid body and track to / look at the next child rigid body?

EDIT: With the existing Ragdoll from bullet implementation, I meant.

I would suggest that you use aligoriths google summer of code bullet work since I believe this will be the future. Otherwise I am guessing that it will need to be rebuilt I would defintely check with him. I came up with a proposal on using dance(gpl ) and integrate it and what not a few years ago. But it is very difficult.

Thanks for all your responses. :slight_smile:

Perhaps I should reiterate that I am working to display mesh deformation according to physics in the game engine. I might be in the wrong forum, but this is a feature that doesn’t currently exist so will require extensive coding and I thought it would be more appropriate in the Python forum.

Aligorith’s GSoC project is very interesting for achieving the opposite of what I am trying to do. ie. incorporate bullet into the 3d view. What I am attempting is to improve the control of bones within an armature in the game engine. If I can get this working and when Aligorith has merged his code into trunk then rag doll mesh deformation and indeed any physics-object driven mesh deformation should be possible in both the game engine and the main editor. I am aware that rag doll systems can currently be constructed in the editor and then be subjected to physics simulations in the game engine. There is a great technique for baking the physics to an armature (I forget the author now, maybe bugman2000?.. it’s been a while) and Aligorith’s work would remove the necessity for this step when involved in rendered animation.

The issue I am trying to resolve is binding the action of bones in an armature to the action of a rigid body object in the game engine. I am effectively trying to simulate rigid body bones by using rigid body objects as a proxy that will handle the physics calculations. The orientations/locations of the rigid body objects will then be transfered to the bones, thus deforming the mesh accoding to physics.

The appoach that seems most promising to me at this time is to create a RB_Bone (rigid body bone) class (and possibly an RB_Armature class for extensibility) that can store the necessary values and that has the capability to perfom the calculations necessary to convert the global space orientation of the rigid bodies to the local space of the bones in an armature and then apply the orientation to the bones.The class idea stems from the potential to have more than one rigid body structure active at once. The class would contain references to the armature and to each rigid body object in the rigid body structue. This should have sufficient encapsulation to enable instancing of the objects/structures.

I am hoping to ultimately create a little Python library and tool set that can be used by game developers in the community to easily incorporate rag dolls into their games. Recently, I saw a demo of a rigid body character walking fairly realistically over any terrain using preplaced targets for the feet. This character consists of discrete rigid bodies because of the issue with driving bones that I have raised. Without the ability to drive bones by the action of rigid bodies could not be used on a skinned, armature driven mesh.

This is by far my most ambitious project to date and I understand that my explanations may not be as clear as they could be.

The big issue I’m having is dealing with all the different quaternion orientations and rotations in a chain of bones.

I am seriously thinking of biting the bullet (accidental pun :)) and buying Quaternions and Rotation Sequences: A Primer with Applications to Orbits, Aerospace and Virtual Reality”

Hey great glad your doing that it looks very complex, go for it. You might want to look at this its not based on bullet I think its based on ode. Here is his web site http://www.arishapiro.com/ He even thought of trying to put it in blender at on point I believe.

I’ve finally managed to get this working. :smiley:

My test .blend linked to near the top of the first post is available for people to check out.
Another link is here for convenience:
QuaternionTest_254_Final.blend

The test does not use rigid bodies, but is a proof of concept for driving an armature in the game engine using the orientation of driver objects only. Since only the object world orientation is used by the script, it should be a trivial matter to replace the driver objects with rigid body objects.

See my BRIK (Blender Ragdoll Implentation Kit) thread for further updates and implementations, but I’ll outline the functionality of the above .blend since the development of that test was the purpose of this thread.

Logic bricks have been set up to enable the operator (me whilst I was working on the script, drinking coffee, scratching my head, thinking hard, getting confused and finally succeeding, you if you want to try it out ;)) to rotate 3 driver objects. This is done using keys to rotate the driver objects in +/- direction about the 3 axes. W/S rotate about Y axis, A/D rotate about X axis, Q/E rotate about Z axis. The keys 1/2/3 can be used to select the object that is rotated, with the base object selected by default or hitting 1, the middle object selected by hitting 2 and the top object selected by hitting 3.

The script Control_Armature.py then reads the orientation of each object and compares the current orientation to the rest orientation, thus working out the rotation of the object. This rotation is then tweaked to represent a bone rotation and then applied to the armature by means of the setChannel() method of an action actuator linked to the script in the armature’s logic editor.

Hard coded in the script are the PoseBone rest orientations as matrices. This had to be done since the game engine cannot read information from PoseBones yet bone rotations can only be set relative to the rest orientation of the PoseBones. In a ragdoll implementation, these values will be saved to a text file during the generation of a ragdoll rigid body structure and then read back by the game engine when the ragdoll is instanced. Ragdoll rigid body structures should be familiar to Blender users and can be seen in action if you search youtube for “blender ragdoll”. I have already implemented a script to generate these rigid body structures, see the BRIK thread (linked above) for development updates.

My hope with the BRIK script is to do away with all the blocky ragdolls that people keep producing and allow people to easily implement a ragdoll mesh that can can be deformed by an armature in the game engine. YES!! Real ragdoll meshes like you see in ‘proper’ games. :wink:

I have comprehensively commented the script in this thread to help people understand how it works. Note that the script in this thread is a proof of concept and not ready for use in a game as it is.

As always, comment/constructive criticism/questions are welcome. :slight_smile:

Nice example! Like it!

Note, you may save computation time

(m1*m2)^(-1) = m2^(-1)*m1^(-1)

mul, inv < inv, mu,l inv


from mathutils import *
M1 = Matrix((1,2),(3,7))
M2 = Matrix((1,3),(3,10))
print(M1)
print(M1.invert())
print(M2)
print(M2.invert())

print("should be zero matrix and it is")
print((M2*M1).invert() - M1.invert()*M2.invert())

gives:
Matrix((1.000000, 3.000000), (2.000000, 7.000000))
Matrix((7.000000, -3.000000), (-2.000000, 1.000000))
Matrix((1.000000, 3.000000), (3.000000, 10.000000))
Matrix((10.000000, -3.000000), (-3.000000, 1.000000))
should be zero matrix and it is
Matrix((0.000000, 0.000000), (0.000000, 0.000000))

Thanks for the tip. :slight_smile:

I’ll try to keep a look out for things like doubling up operations unnecessarily. You’ve got me wondering if I should handle the inverses after changing the matrices to quaternions too. I’m thinking that the quaternion invert will be faster. I’ll have to do some checks.

Speed is essential for this script since it’s for the game engine. The use case I’m basing my thinking on is 6 ragdolls being exploded simultaneously, each with 22 bones at 60 logic ticks per second, meaning the rotation calculation runs 7920 times per second. With other logic, physics and the rasterizer running at the same time this has the potential to cause a serious drop in frame rate. This is the reason I change to quats so early on even though I find matrices easier to work with. When I get to instancing the ragdolls in realtime to take over from action based movement, I’ll need all the optimisation help I can get. :spin:

I hope I can get it to run fast enough to be usable. Initial tests on larger armatures give pretty decent results.

Edit:
Just tested the matrix and quaternion invert functions and quaternion is about 5 times faster, or runs in about 20% of the time. This is useful information. :slight_smile:

Always after created structures, created hitboxes and create logic for armature when press P got error current armature not in list

look console picture 1

if i try press tab got error clist.reverse() internal values cant be modifield in brik_spawn.py

look console picture 2

Can you creator of this addon help me with this error please.I,m using blender 2.79 stable version

                picture 1                                 picture 2



thanks