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
    • Register
    • Register
    • Login

    Retrieving Viewport Camera Matrix

    Cinema 4D SDK
    r20 sdk c++
    4
    9
    1.6k
    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.
    • J
      JohnThomas
      last edited by

      Hello,

      I'm trying to get the matrix from the active camera view in a scene, I can get the matrix from a camera in the scene fairly easily and from the viewport in perspective mode.

      I'm running into trouble when getting the matrix from the viewport camera when it is one of the other modes: top, right, front, etc.

      I tried using the code from the BaseView/BaseDraw Manual to get the matrix.

      BaseDraw* const baseDraw = doc->GetActiveBaseDraw(); 
      if (baseDraw == nullptr) 
              return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION); 
      BaseObject* const cameraObject = baseDraw->GetEditorCamera(); // move active object into the camera view 
      
      const Matrix cameraMatrix = cameraObject->GetMg();
      

      It works properly when the camera is in "Perspective" mode, in every other mode the angle from the matrix is not the right result. Is there another way that I should be doing this?

      Any help would be greatly appreciated.

      John Thomas

      1 Reply Last reply Reply Quote 0
      • P
        PluginStudent
        last edited by

        According to the documentation, the midpoint of orthogonal projections is set with the "Offset" property.

        See CameraObject Manual.

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

          Hi @JohnThomas thanks for reaching out us. According to @PluginStudent remark you can use the CameraObject::GetOffset() to place the object at the center of the active orthogonal view, but if you also need to orient the object according to the view you should also consider to use the BaseView::GetMg() which orient and locate the active object.

          Best, R

          1 Reply Last reply Reply Quote 0
          • J
            JohnThomas
            last edited by

            Thanks for the responses.

            I am able to use BaseDraw::GetMg() to get the proper orientation from the active view for most of the different modes. When I try using that method on the Military, Gentleman, Bird, and Frog modes it is returning an orientation vector that is clearly not right.

            Is there a different method needed to retrieve the data from those camera modes?

            John Thomas

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

              Hi @JohnThomas,

              I've tried all the cases and I can't spot anything with the above solution.

              Assuming you create a 3 sides pyramid pointing to -Z by default, you have:

              • Top:
                19034aa5-39e8-4ab7-b2b9-cfc5547fc62c-image.png
              • Left:
                1000dbdb-fe54-4450-b2b7-4446656821ca-image.png
              • Front:
                4355d442-2eea-453b-a297-256ba8124216-image.png
              • Isometric:
                fd6f31bf-1e5c-46ae-8836-7747b4a3175d-image.png
              • Dimetric:
                374f834a-1a18-43c9-9176-60a5a3329c95-image.png

              With regard to orthogonal axonometries, given that the result of an axonometric procedure is a uniformly-scaled parallel projection of the object and considering the following drawing conventions (right-hand coordinate) where cavalier == gentlemen we still have correct representations.
              647c6049-ff8c-4147-8d8e-658075d2c16b-image.png

              Given the above convention, in a left-hand coordinate system, for Bird, Military and Frog (which are ortographic axonometries) the results is correct because the base of the pyramid still look correct and oriented properly (with the Y axis being represented with different scale)

              • Bird:
                ef535e9a-7dcd-4a38-9ade-ea227a2e20bc-image.png
              • Military:
                bd47c7fd-3019-4400-85ff-7b0a71c5f295-image.png
              • Frog:
                bf631e5c-8dcc-4e79-b499-e6458ca07dd9-image.png
                as well as
              • Gentlemen:
                53adfa39-1b09-429b-96b1-facf0ebcb7d9-image.png
              1 Reply Last reply Reply Quote 2
              • ferdinandF
                ferdinand
                last edited by ferdinand

                Hi,

                I might be misunderstanding the spirit of the question, but I think you misunderstood the question (and misconecption) of @JohnThomas. The bottom line is - the fixed orthographic projections "do not point", or slightly less naive - the transform of a camera object does not (necessarily) reflect a camera projection transform in these cases. You have to "emulate" these on your own. Here is some Python code which should illustrate the problem.

                """Run this in the script manager and read the commented code. It should 
                clear up some misconceptions.
                """
                
                import c4d
                
                
                def main():
                    """
                    """
                    # Create a new camera and set its offset to a distinctive value.
                    camera = c4d.BaseList2D(c4d.Ocamera)
                    if camera is None:
                        raise MemoryError()
                    doc.InsertObject(camera)
                    camera.SetMg(c4d.Matrix(off=c4d.Vector(100)))
                
                    # Go over the projection modes of our camera object.
                    msg = "projection: {}\nframe:\n\t{}\n\t{}\n\t{}\noffset: {}\n"
                    for pid in range(14):
                        camera[c4d.CAMERA_PROJECTION] = pid
                        c4d.EventAdd()
                        # Judging by your code, you do expect this transform to change,
                        # depending on the projection mode, i.e. be some kind of camera
                        # projection transform. But it is not, it is just the same old
                        # transform of the camera object.
                        mg = camera.GetMg()
                        # What the C++ Doc's sell you as the midpoint/offset of the camera
                        # is just the offset of the transform of the camera object.
                        if mg.off != camera.GetOffset():
                            raise ValueError("This should not happen.")
                        # Print out the data.
                        print msg.format(pid, mg.v1, mg.v2, mg.v3, mg.off)
                        # Bottom line - you cannot access the camera projection transforms
                        # in Cinema and have to recreate them more or less faithfully on your
                        # own.
                        # Or in other words, changing the projection mode of the camera
                        # does not change where it "points".
                
                
                if __name__ == "__main__":
                    main()
                

                Cheers,
                zipit

                MAXON SDK Specialist
                developers.maxon.net

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

                  Hi @zipit, thanks for joining the thread, you insights are always very appreciated.

                  Your example shows, as expected, that the camera transformation matrix doesn't change when switching between different projection modes, because Cinema 4D decouples camera transformation from BaseView transformation and, I think, I never said that the camera changes its orientation when switching among projections.

                  The point is to understand what is the final goal of @JohnThomas because arguing from his initial code seems like he wants to move an object into the camera view which can be just by moving the object into the camera center or by also re-orienting the object in the current projection space.

                  I just had to explain where the correct matrix orientation should be found (BaseView::GetMg()) and to show that the matrix values are correct respect to the different projections.

                  Cheers, R

                  1 Reply Last reply Reply Quote 0
                  • ferdinandF
                    ferdinand
                    last edited by ferdinand

                    Hi,

                    wasn't arguing that this is your misconception @r_gigante, but @JohnThomas's. He shows getting the global transform of a camera object and then talks about an "orientation vector clearly not being right".

                    This is phrasing of his is a bit ambiguous, which is why I said I might be misunderstanding something here, but I red it as if he was expecting the projection plane of the camera to always be aligned with the xy plane of the transform of the camera object. So I just pointed out that this is not guaranteed in all projection modes.

                    Cheers,
                    zipit

                    MAXON SDK Specialist
                    developers.maxon.net

                    1 Reply Last reply Reply Quote 0
                    • J
                      JohnThomas
                      last edited by

                      Thanks for the detailed response @r_gigante, sorry about the late post. I wasn't trying to move an object into the camera view, I was just trying to get the information about a cameras perspective so that if necessary I could create an object that would have an orientation parallel to it.

                      John Thomas

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