Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    matrix functions

    SDK Help
    0
    7
    603
    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

      On 28/11/2013 at 11:53, xxxxxxxx wrote:

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

      ---------
      Matrix stuff is still a little confusing to me - even (or especially) after reading the COFFEE SDK piece on it.

      I am trying to align two objects in C4D. 
      Where the root object (A) is stationary and a second object (B) is aligned to one of the sides taking into consideration rotation of both objects.

      At the moment I can do this by making B a child of A and clear its position and rotation. Then it's easy to move it to the required position relative object A. After it's all lined up I move it out of the hierarchy and reinsert it at the top-level. Not very elegant since it messes around with the hierarchy.

      Is there a way to do this via matrix manipulation where each object can stay at its place in the hierarchy?
      I have tried various approaches while reading through the COFFEE chapter about matrices but not achieved much.

      In a nutshell: Object B needs to be moved/rotated as if it was a child of A.

      Thanks

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 29/11/2013 at 06:05, xxxxxxxx wrote:

        In hierarchies, each object has its own 'local matrix' which describes its position, scale, rotation with respect to its own coordinate system (typically, the object's origin).  In relation to an object's parents in the hierarchy, each parent is related thus:

        ObjectA: Local Matrix OA; ObjectB matrix relative to ObjectA = OA x OB, ObjectC matrix relative to ObjectA = OA x OB x OC
        ->ObjectB: Local Matrix OB; ObjectC matrix relative to ObjectB = OB x OC
        --->ObjectC : Local matrix OC

        If ObjectA is at the root of the hierarchy, its coordinate system is relative to the global coordinate system. The combination for ObjectB and ObjectC to put each into this Global space is called the Global matrix.

        Therefore, if you want to move ObjectC out of the hierarchy to the root (global space), you must update its matrix to include the influences of its previous parents so as to maintain its orientation.  This is called a coordinate system or spatial transform.  In the case of Cinema 4D, you can get the global matrix prior to moving out of the hierarchy using ObjectC->GetMg() (where Mg is the 'Matrix global').  After you insert ObjectC at the root (into global space), you can then SetMg() with the matrix retrieved by GetMg() in order to maintain that orientation.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 29/11/2013 at 06:59, xxxxxxxx wrote:

          I think I didn't explain clearly.
          Currently my object to be aligned (B) is a child of A.
          I would like to align B without it being a child of A. So it never changes hierarchy.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 29/11/2013 at 08:51, xxxxxxxx wrote:

            Robert did explain what you asked for.

            It's hard to learn this matrix stuff using just words. You really need some code to play with to understand it.
            Create two objects in your scene and call them "master" and "slave". And Don't make the slave object a child of the master.
            Then try out these two examples on them to see what it does.

            Example#1

                //Get the two object's and their global matrix  
              BaseObject *master = doc->SearchObject("master");  
              Matrix masterMtx = master->GetMg();  
              BaseObject *slave = doc->SearchObject("slave");  
              Matrix slaveMtx = slave->GetMg();  
              
              //This will make the slave use the master's matrix. So it will rotate with the master  
              //But...it also positions the slave at the master's axis position too!!  
              //Sometimes this is a desired thing..sometimes it's not  
              slave->SetMg(masterMtx);  
              slave->Message(MSG_UPDATE);
            

            Example#2

                BaseObject *master = doc->SearchObject("master");  
              Matrix masterMtx = master->GetMg();  
              
              //Convert the master's matrix values to vector values  
              Vector mRot = MatrixToHPB(masterMtx, ROTATIONORDER_DEFAULT);  
                
              
              BaseObject *slave = doc->SearchObject("slave");      
                
              slave->SetAbsRot(mRot);                     //Apply the rotation to the slave object using the vectors from the masterMtx         
              //slave->SetAbsRot(Vector(mRot.x, 0 , 0));  //<--You can also write it like this to only follow master's X rotations  
              slave->Message(MSG_UPDATE);
            

            This is the kind of stuff the constraint tags are doing in C4D behind the scenes.

            -ScottA

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 02/12/2013 at 21:21, xxxxxxxx wrote:

              Thanks, guys
              After some more experimenting I got it figured out. The key for me was to use 
              matrixSlave = matrixSlave * matrixMaster;

              Peter

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 03/12/2013 at 04:59, xxxxxxxx wrote:

                In 'matrix speak' (not, 'take the blue pill'), that is 'matrix concatenation'.  The * operator for the Matrix class is a nice convenience to the more complex process involved in concatenating two matrices.  As you see, hierarchical (or parental) relationships of matrices allow for a matrix for an object (its own space) and application of other objects' spaces through their matrices via concatenation.  This is how you can easily rotate 'Master' and it affects 'Slave'.  The spatial changes to Master are passed along to Slave through matrix concatenation (just as you showed above).  It is not a passive response - it is active by application to the Slave's global matrix.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 03/12/2013 at 05:23, xxxxxxxx wrote:

                  I myself now use Matrices all the time, together with Quaternions. I must admit I am not always sure what is really happening, it just works. Especially Quaternions, opened up a new door.

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