VRayPhysicalCamera: Transformation from world to screen-space and screen to world-space with floating point precision


#1

Hey everyone,

in my ventures into the world of max script with VRay I stumbled upon a challenge that - despite my best efforts - I am unable to solve. Maybe you can help me with the following problems:
Given a VRayPhysicalCamera, how to:

  1. Transform a 3D floating point (x,y,z) in world space coordinates to a 3D floating point screen space point where x, y are floating point screen space values and z is the depth in view space.
  2. Transform a 3D floating point screen space point where x, y are floating point screen space values and z is the depth in view space to a floating point world space point.

My solution thus far worked with the following code - until the introduction of the vertical and horizontal tilt properties of the VRayPhysicalCamera as described in VRayPhysicalCamera.

	fn transformViewToScreenPoint p =
	(
		-- Get extreme points in view space mapped from screen space with a viewport size of [RenderWidth, RenderHeight]:
		startView = mapScreenToView [0,0] (p.z) [RenderWidth, RenderHeight]
		endView = mapScreenToView [RenderWidth, RenderHeight] (p.z) [RenderWidth, RenderHeight]
		
		-- Calculate world size
		worldSize = startView - endView
		
		-- Calculate aspect ratios:
		xAspect = RenderWidth / (abs worldSize.x)
		yAspect = RenderHeight / (abs worldSize.y)
		
		-- Compute the screen point:
		screenPoint = point3 (xAspect * (p.x - startView.x)) (- (yAspect * (p.y - startView.y))) (p.z)
		
		-- Return screen point:
		screenPoint
	)

	fn transformWorldToScreenPoint cam p =
	(
		viewPoint = p * (inverse cam.objecttransform)
		transformViewToScreenPoint viewPoint
	)

	fn transformScreenToViewPoint p =
	(
		-- Get extreme points in view space mapped from screen space with a viewport size of [RenderWidth, RenderHeight]:
		startView = mapScreenToView [0,0] (p.z) [RenderWidth, RenderHeight]
		endView = mapScreenToView [RenderWidth, RenderHeight] (p.z) [RenderWidth, RenderHeight]
		
		-- Calculate world size
		worldSize = startView - endView
		
		-- Calculate inverted aspect ratios:
		xAspectInv = (abs worldSize.x) / RenderWidth
		yAspectInv = (abs worldSize.y) / RenderHeight
		
		viewPoint = point3 (xAspectInv * p.x + startView.x) (- yAspectInv * p.y + startView.y) (p.z)
		viewPoint
	)

	fn transformScreenToWorldPoint cam p =
	(
		viewPoint = transformScreenToViewPoint p
		(viewPoint * cam.objecttransform)
	)

According to the maxscript documentation the function gw.transPoint <point3> transforms the given point from world-space to screen-space coordinates. However I can’t find a function to transform from screen-space to world-space with floating point precision such that transformWorldToScreenPoint(transformScreenToWorldPoint(p)) = p.

Am I missing an existing function or a matrix property that contains the tilt?