{-# OPTIONS_GHC -Wno-missing-methods #-} module Mischief.Math.Transform where import Data.Default (Default) import GHC.Generics (Generic) import Linear.Quaternion qualified as Quaternion import Mischief.ECS (Tick, def) import Mischief.ECS.Components (Component (onAdd)) import Mischief.ECS.Components.HooksDef ( HookContext (HookContext, entity), ) import Mischief.ECS.Exports (Default, Generic) import Mischief.ECS.Hooks (hook) import Mischief.ECS.World.Insert (insert) import Mischief.ECS.World.Query (single) import Mischief.ECS.World.Query.TH (q) import Mischief.Math.Quat (Quat (Quat)) import Mischief.Math.Quat qualified as Quat import Mischief.Math.Vec import Mischief.Math.Vec.Orphans.Default () newtype GlobalTransform = GlobalTransform {GlobalTransform -> Transform transform :: Transform} deriving anyclass (Typeable GlobalTransform [Hook GlobalTransform] [HookRel GlobalTransform] Set DefaultComponentType IsExclusive (IsExclusiveRel GlobalTransform) (Typeable GlobalTransform, IsExclusive (IsExclusiveRel GlobalTransform)) => Set DefaultComponentType -> [Hook GlobalTransform] -> [Hook GlobalTransform] -> [Hook GlobalTransform] -> [HookRel GlobalTransform] -> [HookRel GlobalTransform] -> [HookRel GlobalTransform] -> Component GlobalTransform forall c. (Typeable c, IsExclusive (IsExclusiveRel c)) => Set DefaultComponentType -> [Hook c] -> [Hook c] -> [Hook c] -> [HookRel c] -> [HookRel c] -> [HookRel c] -> Component c $crequired :: Set DefaultComponentType required :: Set DefaultComponentType $conAdd :: [Hook GlobalTransform] onAdd :: [Hook GlobalTransform] $conSet :: [Hook GlobalTransform] onSet :: [Hook GlobalTransform] $conRemove :: [Hook GlobalTransform] onRemove :: [Hook GlobalTransform] $conAddRel :: [HookRel GlobalTransform] onAddRel :: [HookRel GlobalTransform] $conSetRel :: [HookRel GlobalTransform] onSetRel :: [HookRel GlobalTransform] $conRemoveRel :: [HookRel GlobalTransform] onRemoveRel :: [HookRel GlobalTransform] Component, GlobalTransform GlobalTransform -> Default GlobalTransform forall a. a -> Default a $cdef :: GlobalTransform def :: GlobalTransform Default) deriving stock ((forall x. GlobalTransform -> Rep GlobalTransform x) -> (forall x. Rep GlobalTransform x -> GlobalTransform) -> Generic GlobalTransform forall x. Rep GlobalTransform x -> GlobalTransform forall x. GlobalTransform -> Rep GlobalTransform x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cfrom :: forall x. GlobalTransform -> Rep GlobalTransform x from :: forall x. GlobalTransform -> Rep GlobalTransform x $cto :: forall x. Rep GlobalTransform x -> GlobalTransform to :: forall x. Rep GlobalTransform x -> GlobalTransform Generic, Int -> GlobalTransform -> ShowS [GlobalTransform] -> ShowS GlobalTransform -> String (Int -> GlobalTransform -> ShowS) -> (GlobalTransform -> String) -> ([GlobalTransform] -> ShowS) -> Show GlobalTransform forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> GlobalTransform -> ShowS showsPrec :: Int -> GlobalTransform -> ShowS $cshow :: GlobalTransform -> String show :: GlobalTransform -> String $cshowList :: [GlobalTransform] -> ShowS showList :: [GlobalTransform] -> ShowS Show) data Transform = Transform {Transform -> V3 Float translation :: V3 Float, Transform -> Quat rotation :: Quat, Transform -> V3 Float scale :: V3 Float} deriving ((forall x. Transform -> Rep Transform x) -> (forall x. Rep Transform x -> Transform) -> Generic Transform forall x. Rep Transform x -> Transform forall x. Transform -> Rep Transform x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cfrom :: forall x. Transform -> Rep Transform x from :: forall x. Transform -> Rep Transform x $cto :: forall x. Rep Transform x -> Transform to :: forall x. Rep Transform x -> Transform Generic, Int -> Transform -> ShowS [Transform] -> ShowS Transform -> String (Int -> Transform -> ShowS) -> (Transform -> String) -> ([Transform] -> ShowS) -> Show Transform forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> Transform -> ShowS showsPrec :: Int -> Transform -> ShowS $cshow :: Transform -> String show :: Transform -> String $cshowList :: [Transform] -> ShowS showList :: [Transform] -> ShowS Show, Transform -> Transform -> Bool (Transform -> Transform -> Bool) -> (Transform -> Transform -> Bool) -> Eq Transform forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Transform -> Transform -> Bool == :: Transform -> Transform -> Bool $c/= :: Transform -> Transform -> Bool /= :: Transform -> Transform -> Bool Eq) instance Default Transform where def :: Transform def = Transform {translation :: V3 Float translation = Float -> Float -> Float -> V3 Float forall a. a -> a -> a -> V3 a V3 Float 0 Float 0 Float 0, rotation :: Quat rotation = Quat forall a. Default a => a def, scale :: V3 Float scale = Float -> Float -> Float -> V3 Float forall a. a -> a -> a -> V3 a V3 Float 1 Float 1 Float 1} instance Component Transform where onAdd :: [Hook Transform] onAdd = [ (HookContext -> System ()) -> Hook Transform forall {k} (a :: k). (HookContext -> System ()) -> Hook a hook ((HookContext -> System ()) -> Hook Transform) -> (HookContext -> System ()) -> Hook Transform forall a b. (a -> b) -> a -> b $ \HookContext {Entity entity :: HookContext -> Entity entity :: Entity entity} -> do Just transform <- Query System Transform -> System (Maybe Transform) forall w (m :: * -> *) out. MonadSystem w m => Query m out -> m (Maybe out) single [q|entity. Transform|] insert (GlobalTransform transform) entity ] composeTransforms :: Transform -> Transform -> Transform composeTransforms :: Transform -> Transform -> Transform composeTransforms Transform t1 Transform t2 = let Quat Quaternion Float quat1 = Transform t1.rotation in Transform { translation :: V3 Float translation = Transform t1.translation V3 Float -> V3 Float -> V3 Float forall a. Num a => a -> a -> a + (Quaternion Float quat1 Quaternion Float -> V3 Float -> V3 Float forall a. (Conjugate a, RealFloat a) => Quaternion a -> V3 a -> V3 a `Quaternion.rotate` (Transform t1.scale V3 Float -> V3 Float -> V3 Float forall a. Num a => a -> a -> a * Transform t2.translation)), rotation :: Quat rotation = Transform t1.rotation Quat -> Quat -> Quat forall a. Num a => a -> a -> a * Transform t2.rotation, scale :: V3 Float scale = Transform t1.scale V3 Float -> V3 Float -> V3 Float forall a. Num a => a -> a -> a * Transform t2.scale } setRotation :: Quat -> Transform -> Transform setRotation :: Quat -> Transform -> Transform setRotation Quat rotation Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, Quat rotation :: Quat rotation :: Quat rotation, V3 Float scale :: V3 Float scale :: V3 Float scale} setRotationAxis :: Dir3 Float -> Float -> Transform -> Transform setRotationAxis :: Dir3 Float -> Float -> Transform -> Transform setRotationAxis Dir3 Float dir Float angle Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, rotation :: Quat rotation = Dir3 Float -> Float -> Quat Quat.fromAxisAngle Dir3 Float dir Float angle, V3 Float scale :: V3 Float scale :: V3 Float scale} setTranslation :: V3 Float -> Transform -> Transform setTranslation :: V3 Float -> Transform -> Transform setTranslation V3 Float translation Transform {Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, Quat rotation :: Quat rotation :: Quat rotation, V3 Float scale :: V3 Float scale :: V3 Float scale} setScale :: V3 Float -> Transform -> Transform setScale :: V3 Float -> Transform -> Transform setScale V3 Float scale Transform {Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, Quat rotation :: Quat rotation :: Quat rotation, V3 Float scale :: V3 Float scale :: V3 Float scale} move :: V3 Float -> Transform -> Transform move :: V3 Float -> Transform -> Transform move V3 Float trans Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {translation :: V3 Float translation = V3 Float translation V3 Float -> V3 Float -> V3 Float forall a. Num a => a -> a -> a + V3 Float trans, Quat rotation :: Quat rotation :: Quat rotation, V3 Float scale :: V3 Float scale :: V3 Float scale} scale :: V3 Float -> Transform -> Transform scale :: V3 Float -> Transform -> Transform scale V3 Float sc Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, Quat rotation :: Quat rotation :: Quat rotation, scale :: V3 Float scale = V3 Float scale V3 Float -> V3 Float -> V3 Float forall a. Num a => a -> a -> a * V3 Float sc} rotate :: Quat -> Transform -> Transform rotate :: Quat -> Transform -> Transform rotate Quat rot Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, rotation :: Quat rotation = Quat rotation Quat -> Quat -> Quat forall a. Num a => a -> a -> a * Quat rot, V3 Float scale :: V3 Float scale :: V3 Float scale} rotateAxis :: Dir3 Float -> Float -> Transform -> Transform rotateAxis :: Dir3 Float -> Float -> Transform -> Transform rotateAxis Dir3 Float dir Float angle Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, rotation :: Quat rotation = Dir3 Float -> Float -> Quat -> Quat Quat.rotateAxis Dir3 Float dir Float angle Quat rotation, V3 Float scale :: V3 Float scale :: V3 Float scale} rotateX :: Float -> Transform -> Transform rotateX :: Float -> Transform -> Transform rotateX Float angle Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, rotation :: Quat rotation = Float -> Quat -> Quat Quat.rotateX Float angle Quat rotation, V3 Float scale :: V3 Float scale :: V3 Float scale} rotateY :: Float -> Transform -> Transform rotateY :: Float -> Transform -> Transform rotateY Float angle Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, rotation :: Quat rotation = Float -> Quat -> Quat Quat.rotateY Float angle Quat rotation, V3 Float scale :: V3 Float scale :: V3 Float scale} rotateZ :: Float -> Transform -> Transform rotateZ :: Float -> Transform -> Transform rotateZ Float angle Transform {V3 Float translation :: Transform -> V3 Float translation :: V3 Float translation, Quat rotation :: Transform -> Quat rotation :: Quat rotation, V3 Float scale :: Transform -> V3 Float scale :: V3 Float scale} = Transform {V3 Float translation :: V3 Float translation :: V3 Float translation, rotation :: Quat rotation = Float -> Quat -> Quat Quat.rotateZ Float angle Quat rotation, V3 Float scale :: V3 Float scale :: V3 Float scale}