Controlling bone rotations



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 03/08/2004 at 12:28, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   8.503 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    I'm having a devilish time trying to set bone rotations so that the bone X/Y axes align along nearby World axes. Seems to be no rhyme or reason on how the rotation angles get interpreted using SetMg(MatrixMove(trans) * HPBToMatrix(rot)) (which must be done after parenting).

    When using MatrixRotX/Y/Z() with SetMg() and bones, what is being effected: the Global or Local rotations (and why do using these differ from using HPBToMatrix())? Are they rotations about the World axis or the bone axis system?

    VectorToHPB(v) is nice enough to set the Bank value (bone z-axis rotation) to 0.0. But why are the input angles then recalculated when using HPBToMatrix(v), setting the bone z-axis rotation to something other than 0.0? This is exactly what I DON'T want to happen. I want the HP values set as they are and then be able to torque the bone (z-axis) with SPECIFIC!!!! values that yield the CORRECT bone X/Y axis rotations.

    How????

    Thank you,
    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 03/08/2004 at 13:41, xxxxxxxx wrote:

    Okay, I've found a way to generally align the bones with the World axes (arbitrary alignment). Here's the code:

    // bone has been inserted and parented already (no children attached to it yet)

      
         r = VectorToHPB(endPoint - origin);  
         r.x = Rad(180.0) - r.x; // change handedness  
         r = GetOptimalAngle(Vector(0,0,0), r);  
         boneObject->SetMg(MatrixMove(t) * HPBToMatrix(r));  
         // Align Bone axes with World axes (any direction)  
         Matrix m = boneObject->GetMg();  
         r = MatrixToHPB(m);  
         d = boneObject->GetRot();  
         t = Vector(d.x, d.y, d.z);  
         d.z = r.z;  
         d = GetOptimalAngle(t, d);  
         boneObject->SetRot(d);  
    

    Note the little trick here is to set the Local Z rotation to that of the Global Z rotation. Seems to counteract non-orthogonal settings of the Bank rotation (which, BTW, aren't introduced by me, but by HPBToMatrix() - I can't precompensate whatsoever).

    Good start, but now I need to be able to locally Bank so that Bone X/Y axes point in a particular World axis direction (specifically: World X/Y/-Z pairs dependent upon the Bone Z axis general World direction). Again, I am unable to determine which direction they are oriented - and it varies even for bones with Z axis pointing in similar World directions).

    Help, please?

    Thanks,
    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 03/08/2004 at 17:55, xxxxxxxx wrote:

    Now it is known why precompensation of Bank is not working. The Global transform of bones (anyway) is (left to right) :

    rB*rP*rH*trans (in HPB form)

    Literally, the bone Bank is rotated first, which is not what I want. And since rB = 0.0 and I'm basing my compensation for axis alignment on the rP/rH rotations, everything goes out the window when I set the rB compensation value because it changes the way in which the rP/rH rotations then occur (same pointing, indeterminate axis orientation).

    How can I insert an rB compensation transform such that:

    rB(0)*rP*rH*rBC*trans?

    In other words, rP and rH determine the pointing of the bone. Then I want to twirl the bone into axis alignment Globally. I'm uncertain of a way to twirl the bone and then make changes to rP and rH so that the resultant pointing is equivalent to the original. All calculations must be global since they are the only ones that guarantee angles aligned with the world axes.

    Robert



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 04/08/2004 at 17:48, xxxxxxxx wrote:

    Just figure out what trans is and insert the inverse:

    (rB(0) * rP * rH * trans) * trans^-1 * rBC * trans 
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 05/08/2004 at 15:25, xxxxxxxx wrote:

    I tried that, in a sense. Now I do the translation separately (and later). I still can't control the Bank rotation of bones (which is essential here) - I take it that quaternions are used to avoid gimbal lock, but it also changes the banking in the process.

    My method:

    As in my second message (ALWAYS aligns the bones' XY axes to the world axes - can't ask more than that!). Then, like a biochemist seeking a certain virus, I've attached markers (a temporary PolygonObject child to the bone with two vertices; each one set to align with the other bone axes). After SetMg() and the arbitrary alignment, I get these, transformed by the Global matrix, to determine their REAL and KNOWN orientation. Then I correct these using +-90/+-180 deg. rotation deltas to be as I already discussed.

    The correction is a very simple (nearly binary) process and it works flawlessly (although there is the boundary case when the bone is pointing 45d (rare issue), but easily dealt with).

    Robert


Log in to reply