geomancy-0.3.0.0: src/Geomancy/Vulkan/View.hs
{-# LANGUAGE BlockArguments #-}
module Geomancy.Vulkan.View
( lookAtRH
, lookAtRH_
) where
import Geomancy.Mat4 (colMajor)
import Geomancy.Transform (Transform(..))
import Geomancy.Vec3 (Vec3, cross, dot, normalize, vec3, withVec3)
{- | Construct a right-handed world-to-view transformation.
This will rotate and translate the world around a static camera.
This would produce an identity when looking from @vec3 0 0 0@ to @vec3 0 0 1@ using (-Y up).
The fallback "up" should be used when you're looking close to your UP in either direction.
-}
lookAtRH
:: Vec3 -- ^ Eye position
-> Vec3 -- ^ Target
-> Vec3 -- ^ Up direction
-> Transform
lookAtRH eye target up =
withVec3 rgt \rx ry rz ->
withVec3 up' \ux uy uz ->
withVec3 fwd \fx fy fz ->
colMajor
rx ry rz (-er)
ux uy uz (-eu)
fx fy fz (-ef)
0 0 0 1
where
fwd = normalize (target - eye)
rgt = normalize (cross fwd up)
up' = normalize (cross fwd rgt)
er = dot eye rgt
eu = dot eye up'
ef = dot eye fwd
{- | A shortcut for using the -Y as the up axis.
Looking forward from the origin does nothing.
-}
{-# INLINE lookAtRH_ #-}
lookAtRH_ :: Vec3 -> Vec3 -> Transform
lookAtRH_ eye target = lookAtRH eye target yNeg
where
yNeg = vec3 0 (-1) 0