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:
- 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.
- 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?