module Geomancy.Vulkan.Projection
( perspective
, infinitePerspective
, orthoOffCenter
) where
import Geomancy.Mat4 (colMajor)
import Geomancy.Transform (Transform(..))
perspective
:: Integral side
=> Float
-> Float -> Float
-> side -> side
-> Transform
perspective :: forall side.
Integral side =>
Float -> Float -> Float -> side -> side -> Transform
perspective Float
fovRads Float
near Float
far side
width side
height = forall a.
Coercible Mat4 a =>
Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
colMajor
Float
x Float
0 Float
0 Float
0
Float
0 Float
y Float
0 Float
0
Float
0 Float
0 Float
z Float
w23
Float
0 Float
0 Float
w32 Float
1
where
x :: Float
x = Float
cotFoV forall a. Num a => a -> a -> a
* Float
aspectX
y :: Float
y = -Float
cotFoV
z :: Float
z = Float
far forall a. Fractional a => a -> a -> a
/ (Float
near forall a. Num a => a -> a -> a
- Float
far)
w23 :: Float
w23 = Float
near forall a. Num a => a -> a -> a
* Float
far forall a. Fractional a => a -> a -> a
/ (Float
near forall a. Num a => a -> a -> a
- Float
far)
w32 :: Float
w32 = -Float
1
cotFoV :: Float
cotFoV = forall a. Fractional a => a -> a
recip forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Floating a => a -> a
tan forall a b. (a -> b) -> a -> b
$ Float
0.5 forall a. Num a => a -> a -> a
* Float
fovRads
aspectX :: Float
aspectX = forall a b. (Integral a, Num b) => a -> b
fromIntegral side
height forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral side
width
infinitePerspective
:: Integral side
=> Float
-> side
-> side
-> Transform
infinitePerspective :: forall side. Integral side => Float -> side -> side -> Transform
infinitePerspective Float
fovRads side
width side
height = forall a.
Coercible Mat4 a =>
Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
colMajor
Float
x Float
0 Float
0 Float
0
Float
0 (-Float
y) Float
0 Float
0
Float
0 Float
0 (-Float
1) Float
w
Float
0 Float
0 (-Float
1) Float
0
where
(Float
x, Float
y) =
if side
width forall a. Ord a => a -> a -> Bool
> side
height then
( Float
cotFoV forall a. Fractional a => a -> a -> a
/ Float
camAspect
, Float
cotFoV
)
else
( Float
cotFoV
, Float
cotFoV forall a. Num a => a -> a -> a
* Float
camAspect
)
camAspect :: Float
camAspect = forall a b. (Integral a, Num b) => a -> b
fromIntegral side
width forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral side
height
cotFoV :: Float
cotFoV = forall a. Fractional a => a -> a
recip forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Floating a => a -> a
tan forall a b. (a -> b) -> a -> b
$ Float
0.5 forall a. Num a => a -> a -> a
* Float
fovRads
w :: Float
w = -Float
2 forall a. Num a => a -> a -> a
* Float
near
near :: Float
near = Float
1forall a. Fractional a => a -> a -> a
/Float
128
orthoOffCenter :: Integral side => Float -> Float -> side -> side -> Transform
orthoOffCenter :: forall side.
Integral side =>
Float -> Float -> side -> side -> Transform
orthoOffCenter Float
near Float
far side
width side
height = forall a.
Coercible Mat4 a =>
Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
colMajor
Float
x Float
0 Float
0 Float
0
Float
0 Float
y Float
0 Float
0
Float
0 Float
0 Float
z Float
w
Float
0 Float
0 Float
0 Float
1
where
x :: Float
x = Float
2 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral side
width
y :: Float
y = Float
2 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral side
height
z :: Float
z = Float
1 forall a. Fractional a => a -> a -> a
/ (Float
far forall a. Num a => a -> a -> a
- Float
near)
w :: Float
w = Float
near forall a. Num a => a -> a -> a
* (Float
near forall a. Num a => a -> a -> a
- Float
far)