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

    Object Target Expression in Python

    Cinema 4D SDK
    3
    8
    2.1k
    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.
    • T
      Tudor
      last edited by r_gigante

      Hi Friends,
      I try to build the Object Target Expression in Python.
      So far I have this and it works but with a little issue.
      I have a flipping problem and I don't know how to build the up-vector in, so that it works perfectly.
      –

      import c4d
      cam = op.GetObject()
      target = op[c4d.ID_USERDATA,1]
          
      def main():    
          cObj = cam.GetMg().off  
          tObj = target.GetMg().off
          upV =  c4d.Vector(0, 1, 0)
      
          m = c4d.Matrix()
      
          m.off = cObj   
          m.v1 = (tObj-cObj).Cross(cObj-upV).GetNormalized() 
          m.v3 = (tObj-cObj).GetNormalized() 
          m.v2 = (tObj-cObj).Cross(m.v1).GetNormalized()
      
          cam.SetMg(m)
      
      1 Reply Last reply Reply Quote 0
      • r_giganteR
        r_gigante
        last edited by

        Hi Tudor,

        looking at your code I think there's a wrong assumption about the up-vector and how consequently it is used in the definition of the transformation matrix.

        The correct approach should look like:

        import c4d
        
        cam = op.GetObject()    
        target = cam[c4d.ID_USERDATA, 1]
        
        def main():    
            # get "from" and "to vectors
            fromVec = cam.GetMg().off
            toVec = target.GetMg().off
            
            # use a temporary Up-vector
            tmpVec = c4d.Vector(0, 1, 0)
            # calculate the forward-vector
            fVec = (toVec - fromVec).GetNormalized()
            # calculate the right-vector
            rVec = tmpVec.Cross(fVec)
            # recalculate the proper up-vector
            uVec = fVec.Cross(rVec)
            
            # fill-up the transformation matrix
            m = c4d.Matrix()
            m.off = fromVec
            m.v1 = rVec
            m.v2 = uVec
            m.v3 = fVec
            
            # set the camera transformation
            cam.SetMg(m)
        

        Last but not least, please set tags accordingly to your topic and use the Q&A functionality.

        Best, Riccardo

        1 Reply Last reply Reply Quote 2
        • T
          Tudor
          last edited by

          Hi Riccardo,
          thank you for your help.
          After I put GetNormalized() in your line rVec and uVec it works.
          But now I get a flipping problem if the cam-Obj is direct over (or under) the target-Obj.
          The same happened by the Target-Tag. The Target-Tag has a option to stabilize the system with an up-Vector.
          Could I calculate this up-Vector to my matrix to stabilize it too? Or maybe there is a other approach?
          Thanks
          Tudor

          1 Reply Last reply Reply Quote 0
          • r_giganteR
            r_gigante
            last edited by ferdinand

            Hi Tudor, thanks for following up.

            The issue you notice takes place when the temporary up-vector is aligned with the forward-vector: under this scenario the rVec is ambiguous and the whole system results unstable. The solution to the issue is represented by Quaternions or, alternatively you can try to mitigate the effect by putting in place some "work-around" like:

                ...
                uVec = fVec.Cross(rVec).GetNormalized()
            
                # try to mitigate Gimbal-lock
                if (fVec + tmpVec).z < 0:
                    uVec.x = -uVec.x
            
                if abs(rVec.x - 1.0) < 0.001:
                    rVec.x = -rVec.x
            
                # fill-up the transformation matrix
                ...
            

            Best, Riccardo

            edit: @ferdinand

            The approach shown here can be problematic. You instead should choose an up-vector which is not parallel or anti-parallel to the input vector. See Gimbal Lock Safe Target Expression for an example.

            1 Reply Last reply Reply Quote 3
            • T
              Tudor
              last edited by

              Hi,
              thanks again.
              I really do not understand it yet but it works.
              There are some strange camera behaviors in the viewport but the system still stable.
              I have tried also the Quaternions-solution, but I don't know really now the syntax work.
              Do you have an idea?

              1 Reply Last reply Reply Quote 0
              • r_giganteR
                r_gigante
                last edited by

                Hi Tudor, with regard to using quaternions, I suggest to search around the web for it: there are hundreds of sites talking extensively about.
                I warmly suggest to have a look here where Gimbal lock is presented and some notes are spent on how to avoid it.

                Best, Riccardo

                1 Reply Last reply Reply Quote 3
                • T
                  Tudor
                  last edited by

                  Does anyone have a suggestion how to work with Quaternions in my case to avoid the gimbal lock? I realy dont find any examples or approaches to this. Other APIs have different methods for this like SetFromToRotation, SetLookRotation, lookAt ....
                  Maybe its possible to extend the Python Library with other classes? Don‘t have any idea and not very advanced in this.
                  Thanks!

                  1 Reply Last reply Reply Quote 0
                  • a_blockA
                    a_block
                    last edited by

                    Hi,

                    unfortunately we can't help developing algorithms. So, what has been said here and in the Quaternion Rotation thread, is probably all we can contribute from MAXON's side.

                    Maybe somebody from our community is willing to step into this and help out?

                    Cheers,
                    Andreas

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