Dimensions of an object in perspective view



  • On 15/01/2013 at 04:36, xxxxxxxx wrote:

    A camera should automatically change its distance to an object in that way, that the object is completely in the viewcone of the camera.
    The calculations are simple as long as the camera is on the coordinatesystem axis. Its getting complicated when the camera is in a solid angle to the object. For example the length between the extreme points of a cube is larger as if the camera is on the coordinate system axis.
    Does Cinema 4D grants the possibilty to get the twodimensional coordinates of an object? So to say the coordinates of the object what the camera sees, whats shown in the render window.
    If not I have to use projection matrices, what I really don't like to do. Is there any other possibility left?

    I hope I made myself understandable enough. Thank you!



  • On 25/01/2013 at 03:00, xxxxxxxx wrote:

    Hi,

    You can retrieve the current BaseDraw and call the methods to convert a point from world space to screen space (BaseView.WS()), screen space to camera space (BaseView.SC()) etc.

    EDIT:

    Here's how we can use BaseView methods (WS(), GetSafeFrame()) to test if the active object will be completely rendered:

    import c4d
      
      
    def TestPointInFrame(pt, frame) :
        return pt.x > frame['cl'] and pt.x < frame['cr'] and \n           pt.y > frame['ct'] and pt.y < frame['cb']
      
    def main() :
        if op is None:
            return
        
        # Get the current BaseDraw
        bd = doc.GetActiveBaseDraw()
        
        # Get the active object bouding box center and radius
      
        rd = op.GetRad()
        mp = op.GetMp()
        
        # Build the active object bouding box
        
        box = [c4d.Vector() for x in xrange(8)]
        box[0] = c4d.Vector()
        box[0].x = mp.x - rd.x
        box[0].y = mp.y - rd.y
        box[0].z = mp.z - rd.z
        box[0] *= op.GetMgn()
        
        box[1] = c4d.Vector()
        box[1].x = mp.x + rd.x
        box[1].y = mp.y - rd.y
        box[1].z = mp.y - rd.z
        box[1] *= op.GetMgn()
        
        box[2] = c4d.Vector()
        box[2].x = mp.x - rd.x
        box[2].y = mp.y + rd.y
        box[2].z = mp.y - rd.z
        box[2] *= op.GetMgn()
        
        box[3] = c4d.Vector()
        box[3].x = mp.x - rd.x
        box[3].y = mp.y - rd.y
        box[3].z = mp.y + rd.z
        box[3] *= op.GetMgn()
        
        box[4] = c4d.Vector()
        box[4].x = mp.x + rd.x
        box[4].y = mp.y + rd.y
        box[4].z = mp.z - rd.z
        box[4] *= op.GetMgn()
        
        box[5] = c4d.Vector()
        box[5].x = mp.x - rd.x
        box[5].y = mp.y + rd.y
        box[5].z = mp.y + rd.z
        box[5] *= op.GetMgn()
        
        box[6] = c4d.Vector()
        box[6].x = mp.x - rd.x
        box[6].y = mp.y - rd.y
        box[6].z = mp.y + rd.z
        box[6] *= op.GetMgn()
        
        box[7] = c4d.Vector()
        box[7].x = mp.x + rd.x
        box[7].y = mp.y + rd.y
        box[7].z = mp.y + rd.z
        box[7] *= op.GetMgn()
        
        # Calculate bouding box coordinates in screen space
        
        points = [c4d.Vector() for x in xrange(8)]
        for i in xrange(len(box)) :
            points[i] = bd.WS(box[i])
        
        # Test if the current object is completely visible in the rendered safe frame
        
        safeFrame = bd.GetSafeFrame()
        
        for i in xrange(len(points)) :
            visible = TestPointInFrame(points[i], safeFrame)
            if not visible:
                break
      
        print "Active Object Completely Visible:", visible
      
      
    if __name__=='__main__':
        main()
    


  • On 28/01/2013 at 01:21, xxxxxxxx wrote:

    Thank you very much! This is exactly what I was looking for. Couldn't find anything in the documentation...


Log in to reply