Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Nonuniform scaling - dilemma

    SDK Help
    0
    1
    131
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

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

      On 08/05/2006 at 17:02, xxxxxxxx wrote:

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

      ---------
      I've found probably the best solution available for handling shear in nonuniform scaling - SoftImage 'SI transformation' as it's called. It works by sort of rearranging the concatenation of transformation matrices - from classical (in C4D concatenation order) :

      A(global) = B(global) x A(local)

      to 'SI':

      A(global) = AB(pos) x B(rot) x A(rot) x B(scale) x A(scale)

      where AB(pos) = MatrixMove(A(pos) * B(global))

      This works for the most part, but scaling gets wonky as the hierarchy gets deeper. And I can't seem to understand why this occurs, so here is an example of my code which sets the 'bone' rotation:

      // IPPDial.UpdateRotation  
      //*---------------------------------------------------------------------------*  
      void IPPDial::UpdateRotation(BaseObject* obj, UCHAR sub, Real value)  
      //*---------------------------------------------------------------------------*  
      {  
      // Get the changed rotation component  
           BaseContainer*     bc =     obj->GetDataInstance();  
           Vector               rotV =     bc->GetVector(IPP_ROTATION);  
           if          (sub == CHAN_SUB_X)     rotV.x =     Rad(value);  
           else if (sub == CHAN_SUB_Y)     rotV.y =     Rad(value);  
           else if (sub == CHAN_SUB_Z)     rotV.z =     Rad(-value);  
           bc->SetVector(IPP_ROTATION, rotV);  
        
      // Create an axis-ordered rotation matrix with the updated rotation component  
           Matrix               rot;  
           UCHAR               order =          bc->GetBool(IPP_RORDER);  
           if          (order == ROTORDER_XYZ)     rot = bc->GetMatrix(IPP_ORIENTMATRIX) * MatrixRotZ(rotV.z) * MatrixRotY(rotV.y) * MatrixRotX(rotV.x);  
           else if (order == ROTORDER_XZY)     rot = bc->GetMatrix(IPP_ORIENTMATRIX) * MatrixRotY(rotV.y) * MatrixRotZ(rotV.z) * MatrixRotX(rotV.x);  
           else if (order == ROTORDER_YXZ)     rot = bc->GetMatrix(IPP_ORIENTMATRIX) * MatrixRotZ(rotV.z) * MatrixRotX(rotV.x) * MatrixRotY(rotV.y);  
           else if (order == ROTORDER_YZX)     rot = bc->GetMatrix(IPP_ORIENTMATRIX) * MatrixRotX(rotV.x) * MatrixRotZ(rotV.z) * MatrixRotY(rotV.y);  
           else if (order == ROTORDER_ZXY)     rot = bc->GetMatrix(IPP_ORIENTMATRIX) * MatrixRotY(rotV.y) * MatrixRotX(rotV.x) * MatrixRotZ(rotV.z);  
           else if (order == ROTORDER_ZYX)     rot = bc->GetMatrix(IPP_ORIENTMATRIX) * MatrixRotX(rotV.x) * MatrixRotY(rotV.y) * MatrixRotZ(rotV.z);  
      // SI transformation  
           Matrix               mg =          obj->GetUpMg();  
           mg =               MatrixMove(obj->GetPos()*mg) * HPBToMatrix(MatrixToHPB(mg)) * rot * MatrixScale(Vector(Len(mg.v1),Len(mg.v2),Len(mg.v3))) * MatrixScale(obj->GetScale());  
           obj->SetMg(mg, FALSE);  
           obj->Message(MSG_UPDATE);  
      }
      

      For position and scale, the same basic format applies for the SI transformation. If anyone can spot an error or has a better algorithmic approach, love to hear about it.

      Thanks,

      1 Reply Last reply Reply Quote 0
      • First post
        Last post