module Graphics.FieldTrip.Transform3
(
Transform3(..)
, translate3, rotate3, scale3, uscale3
, tweakMatrix3, tweakError3
) where
import Data.Monoid
import Data.VectorSpace (AdditiveGroup,negateV)
import Graphics.Rendering.OpenGL
import Graphics.FieldTrip.Vector3
import Graphics.FieldTrip.Render (ErrorBound)
import Graphics.FieldTrip.Transform
data Transform3 s =
Identity3
| Translate3 (Vector3 s)
| Rotate3 s (Vector3 s)
| Scale3 s s s
| Compose3 (Transform3 s) (Transform3 s)
deriving (Eq,Show)
instance (Fractional s, AdditiveGroup s) => Invertible (Transform3 s) where
inverse Identity3 = Identity3
inverse (Translate3 v) = Translate3 (negateV v)
inverse (Rotate3 a axis) = Rotate3 (a) axis
inverse (Scale3 r s t) = Scale3 (recip r) (recip s) (recip t)
inverse (Compose3 outer inner) =
Compose3 (inverse inner) (inverse outer)
translate3 :: Vector3 s -> Transform3 s
translate3 = Translate3
rotate3 :: s -> Vector3 s -> Transform3 s
rotate3 = Rotate3
scale3 :: s -> s -> s -> Transform3 s
scale3 = Scale3
uscale3 :: s -> Transform3 s
uscale3 s = scale3 s s s
instance Monoid (Transform3 s) where
mempty = Identity3
mappend = Compose3
tweakMatrix3 :: (Floating s, MatrixComponent s) => Transform3 s -> IO ()
tweakMatrix3 Identity3 = return ()
tweakMatrix3 (Translate3 vec) = translate vec
tweakMatrix3 (Rotate3 r vec ) = rotate (r * (180/pi)) vec
tweakMatrix3 (Scale3 x y z ) = scale x y z
tweakMatrix3 (Compose3 o i) = tweakMatrix3 o >> tweakMatrix3 i
tweakError3 :: (Real s, Fractional s) => Transform3 s -> ErrorBound -> ErrorBound
tweakError3 (Scale3 x y z ) = (/ toBound (abs x `max` abs y `max` abs z))
tweakError3 (Compose3 o i) = tweakError3 o . tweakError3 i
tweakError3 _ = id
toBound :: (Real s, Fractional s) => s -> ErrorBound
toBound = fromRational . toRational