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

    Global pos to camera view

    Scheduled Pinned Locked Moved PYTHON Development
    3 Posts 0 Posters 544 Views
    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 Offline
      Helper
      last edited by

      On 01/03/2018 at 11:46, xxxxxxxx wrote:

      How i can convert global coordinates of object in relation to specific camera view?
      I've managed to create a Python Generator which returns quad polygon with points linked to top-left, top-right, bottom-right and bottom-left coordinates of camera-view:

      import c4d,math
      # Cam Quad Maker
        
      def fov(fv) : #get FoV-point
          return math.tan(fv*.5)
        
      def main() :
          op[c4d.ID_BASEOBJECT_ABS_POSITION] = c4d.Vector(0)
          op[c4d.ID_BASEOBJECT_ABS_ROTATION] = c4d.Vector(0)
          op[c4d.ID_BASEOBJECT_ABS_SCALE] = c4d.Vector(1)
          cam=op[c4d.ID_USERDATA,1] #Link-field for Camera
          if(not cam)or(cam.GetType()!=c4d.Ocamera) :
              return None
          cMat=cam.GetMg() #camera-matrix
          cZ=cam[c4d.CAMERAOBJECT_TARGETDISTANCE] #z-distance
          cvH=fov(cam[c4d.CAMERAOBJECT_FOV])*cZ #view-Horz
          cvV=fov(cam[c4d.CAMERAOBJECT_FOV_VERTICAL])*cZ #view-Vert
          qd=c4d.BaseObject(c4d.Opolygon)
          pts=[c4d.Vector(0,0,0)]*4
          pts[0]=c4d.Vector(-cvH,-cvV,cZ)*cMat #topLeft
          pts[1]=c4d.Vector(cvH,-cvV,cZ)*cMat #topRight
          pts[2]=c4d.Vector(cvH,cvV,cZ)*cMat #botRight
          pts[3]=c4d.Vector(-cvH,cvV,cZ)*cMat #botLeft
          qd.ResizeObject(4,1)
          qd.SetAllPoints(pts)
          qd.SetPolygon(0,c4d.CPolygon(0,1,2,3))
          return qd
      

      Now i want to convert another object's coordinates relatively to this quad so in resulting coords:

      • X will be 0 if object exactly on the left edge, 1 if on the right, <0 if out of view on the left and >0 if on the right
      • Y will be same as X but relative vertically
      • Z will be 0 if object exactly on the plane formed by the quad points, <0 if it's farther and >0 if closer to camera

      But i don't sure what to do next 😃 When i multiply obj.GetMg().off by pts[0] for example (TopLeft point of view) i get some garbage values, it's definitely not what i wanned lol
      And cuz i have pretty crappy knowledge of trigonometry i'm kinda stuck now =\

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

        On 01/03/2018 at 14:35, xxxxxxxx wrote:

        Well, i found a way to do what i wanted:

        import c4d,math
        # Object Pos related to CamView
          
        def fov(fv) : #get FoV-point
            return math.tan(fv*.5)
          
        def main() :
            cam=op[c4d.ID_USERDATA,1] #Link-field for Camera
            if(not cam)or(cam.GetType()!=c4d.Ocamera) : return None
            obj=op[c4d.ID_USERDATA,2] #Link-field for Object
            if(not obj) : return None
            cMat=cam.GetMg() #camera-matrix
            cZ=cam[c4d.CAMERAOBJECT_TARGETDISTANCE] #z-distance
            cvH=fov(cam[c4d.CAMERAOBJECT_FOV])*cZ #view-Horz
            cvV=fov(cam[c4d.CAMERAOBJECT_FOV_VERTICAL])*cZ #view-Vert
            bd=doc.GetActiveBaseDraw()
            bd.InitializeView(doc, cam, True)
            oMat=obj.GetMg() #object-matrix
            v=bd.WC(oMat.off) #World2Camera
            v[0]=(v[0]+cvH)/cvH*.5
            v[1]=1-(v[1]+cvV)/cvV*.5
            v[2]=(cZ-v[2])/cZ
            op[c4d.ID_USERDATA,3]=str(v) #Output coords into string-field
            return None
        

        But if anyone who's not THAT retarded in 3D math as i am will provide code to do the same without BaseView.WC() via basic matrix/vector equations i will absolutely appreciate it.

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

          On 02/03/2018 at 11:02, xxxxxxxx wrote:

          Hi Markus, thanks for writing us.

          With regard to your request, consider that using the BaseView::WS() and BaseView::GetSafeFrame() are the easiest and fastest way to deliver a world-to-screen representation of the space which, in my opinion, fits better with what you're looking for.

          Slightly modifying the code it should look like:

            
          import c4d  
          # Object Pos related to CamView  
            
          def main() :  
            cam = op[c4d.ID_USERDATA,1] #Link-field for Camera  
            if(not cam)or(cam.GetType()!=c4d.Ocamera) :   
                return None  
              
            obj = op[c4d.ID_USERDATA,2] #Link-field for Object  
            if(not obj) :   
                return None  
              
            cZ = cam[c4d.CAMERAOBJECT_TARGETDISTANCE] #z-distance  
              
            bd = doc.GetActiveBaseDraw()  
            
            objPos = obj.GetMg().off #object global position  
            
            v = bd.WS(objPos) #World2Screen  
            sf = bd.GetSafeFrame() #SafeFrame  
              
            v[0] = (v[0] - sf["cl"])/(sf["cr"]-sf["cl"])  
            v[1] = (v[1] - sf["ct"])/(sf["cb"]-sf["ct"])  
            v[2] = (cZ-v[2])/cZ  
            
            op[c4d.ID_USERDATA,3]=str(v) #Output coords into string-field  
              
            return None  
          

          Best, Riccardo

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