In the research category i will talk about the procedures and workflow i try to develop for character setup and deformation.Each article will begin with the analysis of some of my past works, and end with what i try to improve.
One of the first project where i was able to include pose space deformation in a character work was for a TV commercial for “UnicorToys”.
The production schedule was long enough to test new ideas and allows some mistakes.My previous experience with corrective shapes was mainly to enhance the result of hinge joint deformation such as elbows or knees.The next logical step was to use the same technique for the wrist, heel, shoulder and leg area.
In most situation my setup was working quite well:
- Working with body segment as influences object allowed me to share the arm, leg and foot between my two character
- Later on the project I was able to change the topology of the head without loosing the work on the other region.
On the overhand there was several points where this experiment has fail miserably:
- by its very nature this techniques is both time consuming and expensive
- the active range of motion where the deformations were valid was not broad enough : it had a negative impact on the animation side of the project
–Above we can see the sheer number of correctives shapes created .–
In order to apply these shapes I used a tool that was provide with 3dsmax 2009: the skinMorph modifier.
- The first obstacle i stumbled upon was the behavior of the shape mixing in this animation modifier : the interpolation between the key pose was not reliable enough. one work around was to assign 1 shape per modifier
- the second pitfall I encountered was the naive method used to read the pose a limb is achieving .
- The third mistake done was the lack of tool and procedure to mirror the setup
1) Twist decomposition:
The usual goal of a pose reader is to drive the amount of influence of a corrective shape , for this project i tried to use it to extract the amount of twisting in a body region.
The main idea to extract this rotational value was to compare the orientation of a first object(orientation Joint) which can rotate freely on 3 axis with a second one (target arrow) whose twist axis has been neutralize. The two object aim at same point in space ( on the image above Aim Locator ) .
One of the simplest way to meet this requirement is to use a lookAt constraint in 3dstudioMax or an aim constraint in maya. In the image above we can see that the twisting axis is driven by a secondary object (upnode Control ) which will remain static.
The last step to complete this twist extractor was to use an expose transform helper in order to read the desired channel value ( in this case X angle value in degrees ). As a side note, this step doesn’t exist in maya where the value of an attribute is always output in its local parent space.
Above we can see a practical use of this extracted twist value: it was split evenly and map onto a secondary hierarchy of joints
2) Pose reader inner working:
Traditionally a pose reader compute a weight value from two vectors, as the sample vector gets near the pose vector , the angle between them will reach 0.0 meaning that this pose has a weight value of a hundred per cent.
The second important parameter of a pose reader is its maximum reading angle : This parameter defines a cone of influence that determines when a pose starts to be triggered and how several poses can be mixed and blend together.
In this project I choose a purely additive solution for my corrective shapes: each set of delta are not blended together but will instead override the previous one.
As a matter of fact my requirement for a pose reader was a little bit different from the standard tool in 3dsMax:
- The first goal of this pose reader was to output 2 angle value : one for the amount of rotation in the “Front_Rear_Axis” ( Z axis in the image above ) and one in the “Up_Down_Axis” ( Y axis ) .
- From this data the next step was split each axis into two zones.
- The last step was to divide each zone into nth number of sector
The main idea behind this procedure is to trigger each sector weight sequentially from A to Nth , and to clamp the value of the lower sector to a value 100.0 when we travel in a higher sector.
In order to build this custom pose driver another expose transform helper was used to read the Z and Y axis values of my target arrow.These values were then plug in several expression controller to compute the weight of each zone sector.
– ( Above we can see a snapshot of float expression controller: the syntax is read as follow: output the incoming value of the variable Z_Axis_Value if it is lower than 0.0, else clamp it at 0.0 ) –
3) Pushing vertices is not fun:
At the start of the project i was aware that this techniques was time consuming, but i quickly realized that a couple of corrective shapes was not enough to achieve the level of quality required , after 15 days of hard work i end up with huge database to maintain ,mirror and setup for the opposite side of the body.
– ( In this image we can see the 80 driver channels that are computed by the pose reader of the leg) –
The most difficult part of the process was to sculpt and maintain the volume of a body region when it reach the most extreme pose, it was also vital to check the overall interpolation of the mesh between the previous key pose.
- My first mistake was that i did not account for the fact that the number of division of this mesh was too high to efficiently process the key pose correction
- At that time i did not though of a correct methodology to sculpt these shapes: i was not using any kind of lattice, sculpt brush or soft selection method, it was purely a brute force method.
- To account for the loss of volume when twisting I was using 4 shapes to enforce proper deformation: while this was a good move in general it turns out to be a poor choice for the girl shoulder.In this region combining the action of the scapula, humerus, and twisting has lead to the creation of an exponential number of shapes: even after some simplification i ended with 183 elements which where barely manageable by hand.
4) The harsh reality of math in a 3d program:
The second major flaw in my work was related to the LookAt constraint use in the twist extractor and the pose reader : before committing to learn the python maya API I was not knowledgeable of vector and matrix math, nor did I care about trigonometry.
In the image above we can see the effect of the 2 singularities generated by this method: when the target arrow pass through the axis defined by the origin and the up vector node position, the constraint operator cannot compute a proper orientation and the driven object flips brutally in the opposite direction.
This instability ripples down and invalidates both the twist value extracted and the pose reader.