module RSAGL.Math.Orthogonal
(up,down,left,right,forward,backward,
orthogonalFrame,
modelLookAt,
FUR)
where
import RSAGL.Math.Affine
import RSAGL.Math.Vector
import RSAGL.Math.Matrix
data FURAxis = ForwardAxis | UpAxis | RightAxis | DownAxis | LeftAxis | BackwardAxis
data FUR a = FUR FURAxis a
instance Functor FUR where
fmap f (FUR a x) = FUR a $ f x
up :: a -> FUR a
up = FUR UpAxis
down :: a -> FUR a
down = FUR DownAxis
left :: a -> FUR a
left = FUR LeftAxis
right :: a -> FUR a
right = FUR RightAxis
forward :: a -> FUR a
forward = FUR ForwardAxis
backward :: a -> FUR a
backward = FUR BackwardAxis
orthogonalFrame :: (AffineTransformable a) => FUR Vector3D -> FUR Vector3D -> a -> a
orthogonalFrame (FUR ForwardAxis f) (FUR RightAxis r) =
let (r',u') = fixOrtho2 f r in transform (xyzMatrix r' u' (vectorNormalize f))
orthogonalFrame (FUR UpAxis u) (FUR ForwardAxis f) =
let (f',r') = fixOrtho2 u f in transform (xyzMatrix r' (vectorNormalize u) f')
orthogonalFrame (FUR RightAxis r) (FUR UpAxis u) =
let (u',f') = fixOrtho2 r u in transform (xyzMatrix (vectorNormalize r) u' f')
orthogonalFrame (FUR RightAxis r) (FUR ForwardAxis f) =
let (f',u') = fixOrtho2Left r f in transform (xyzMatrix (vectorNormalize r) u' f')
orthogonalFrame (FUR ForwardAxis f) (FUR UpAxis u) =
let (u',r') = fixOrtho2Left f u in transform (xyzMatrix r' u' (vectorNormalize f))
orthogonalFrame (FUR UpAxis u) (FUR RightAxis r) =
let (r',f') = fixOrtho2Left u r in transform (xyzMatrix r' (vectorNormalize u) f')
orthogonalFrame (FUR ForwardAxis _) (FUR ForwardAxis _) =
error "orthogonalFrame: two forward vectors"
orthogonalFrame (FUR UpAxis _) (FUR UpAxis _) =
error "orthogonalFrame: two up vectors"
orthogonalFrame (FUR RightAxis _) (FUR RightAxis _) =
error "orthogonalFrame: two right vectors"
orthogonalFrame x y = orthogonalFrame (furCorrect x) (furCorrect y)
furCorrect :: FUR Vector3D -> FUR Vector3D
furCorrect (FUR ForwardAxis f) = FUR ForwardAxis f
furCorrect (FUR UpAxis u) = FUR UpAxis u
furCorrect (FUR RightAxis r) = FUR RightAxis r
furCorrect (FUR DownAxis d) = FUR UpAxis $ vectorScale (1) d
furCorrect (FUR LeftAxis l) = FUR RightAxis $ vectorScale (1) l
furCorrect (FUR BackwardAxis b) = FUR ForwardAxis $ vectorScale (1) b
modelLookAt :: (AffineTransformable a) =>
Point3D ->
FUR (Either Point3D Vector3D) ->
FUR (Either Point3D Vector3D) ->
a -> a
modelLookAt pos primaryish secondaryish =
RSAGL.Math.Affine.translate (vectorToFrom pos origin_point_3d) .
orthogonalFrame primary secondary
where primary = fmap (either (`vectorToFrom` pos) id) primaryish
secondary = fmap (either (`vectorToFrom` pos) id) secondaryish