module Linear.Perspective
( lookAt
, perspective
, infinitePerspective
, ortho
) where
import Control.Lens hiding (index)
import Linear.V3
import Linear.V4
import Linear.Matrix
import Linear.Epsilon
import Linear.Metric
lookAt
:: (Epsilon a, Floating a)
=> V3 a
-> V3 a
-> V3 a
-> M44 a
lookAt eye center up =
V4 (V4 (xa^._x) (xa^._y) (xa^._z) xd)
(V4 (ya^._x) (ya^._y) (ya^._z) yd)
(V4 (za^._x) (za^._y) (za^._z) zd)
(V4 0 0 0 1)
where za = normalize $ center eye
xa = normalize $ cross za up
ya = cross xa za
xd = dot xa eye
yd = dot ya eye
zd = dot za eye
perspective
:: Floating a
=> a
-> a
-> a
-> a
-> M44 a
perspective fovy aspect near far =
V4 (V4 x 0 0 0)
(V4 0 y 0 0)
(V4 0 0 z w)
(V4 0 0 (1) 0)
where tanHalfFovy = tan $ fovy / 2
x = 1 / (aspect * tanHalfFovy)
y = 1 / tanHalfFovy
z = (far + near) / (far near)
w = (2 * far * near) / (far near)
infinitePerspective
:: Floating a
=> a
-> a
-> a
-> M44 a
infinitePerspective fovy aspect near =
V4 (V4 x 0 0 0)
(V4 0 y 0 0)
(V4 0 0 (1) w)
(V4 0 0 (1) 0)
where range = tan (fovy / 2) * near
left = range * aspect
right = range * aspect
bottom = range
top = range
x = (2 * near) / (right left)
y = (2 * near) / (top bottom)
w = 2 * near
ortho
:: Floating a
=> a
-> a
-> a
-> a
-> a
-> a
-> M44 a
ortho left right bottom top near far =
V4 (V4 (2 / a) 0 0 (negate (right + left) / a))
(V4 0 (2 / b) 0 (negate (top + bottom) / b))
(V4 0 0 (2 / c) (negate (far + near) / c))
(V4 0 0 0 1)
where a = right left
b = top bottom
c = far near