 # 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?