From 5bdb855e7143d13b05ac836978dd8e67017482df Mon Sep 17 00:00:00 2001
From: Marc Sunet <jeannekamikaze@gmail.com>
Date: Sat, 1 Sep 2012 11:20:12 +0200
Subject: Replaced Rotation for an arbitrary axis

---
 Spear.lkshs               |  6 ++--
 Spear.lkshw               |  4 +--
 Spear/Math/MatrixUtils.hs | 26 ++++++---------
 Spear/Scene/GameObject.hs | 81 +++++++++++++++++++++++------------------------
 Spear/Scene/Loader.hs     | 17 +++-------
 5 files changed, 59 insertions(+), 75 deletions(-)

diff --git a/Spear.lkshs b/Spear.lkshs
index 4b0d469..3e07004 100644
--- a/Spear.lkshs
+++ b/Spear.lkshs
@@ -1,14 +1,14 @@
 Version of session file format:
                1
 Time of storage:
-               "Fri Aug 31 22:25:44 CEST 2012"
-Layout:        VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 1, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [("Browser",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 302) 217),("Debug",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 1, detachedId = Nothing, detachedSize = Nothing}) 256)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 663) 954
+               "Sat Sep  1 10:54:22 CEST 2012"
+Layout:        VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 1, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [("Browser",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 327) 235),("Debug",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 1, detachedId = Nothing, detachedSize = Nothing}) 277)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 714) 954
 Population:    [(Just (BreakpointsSt BreakpointsState),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP BottomP]),(Just (ErrorsSt ErrorsState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Factory.hs" 1205)),[SplitP LeftP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Scene/GameObject.hs" 3114)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject.hs" 1432)),[SplitP LeftP]),(Just (InfoSt (InfoState Nothing)),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Scene/Loader.hs" 17178)),[SplitP LeftP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Math/MatrixUtils.hs" 1235)),[SplitP LeftP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Nothing,Nothing) (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([[0]],[]), packageDExp = ([],[]), packageDExpNoBlack = ([],[]), workspaceExp = ([],[]), workspaceExpNoBlack = ([],[]), workspaceDExp = ([],[]), workspaceDExpNoBlack = ([],[]), systemExp = ([],[]), systemExpNoBlack = ([],[])}))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Player.hs" 2249)),[SplitP LeftP]),(Just (SearchSt (SearchState {searchString = "putStrLn", searchScope = PackageScope False, searchMode = Prefix {caseSense = False}})),[SplitP RightP,SplitP TopP]),(Just (TraceSt TraceState),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Utils.hs" 587)),[SplitP LeftP]),(Just (VariablesSt VariablesState),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP BottomP]),(Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP TopP]),(Just (BufferSt (BufferStateTrans "_Eval.hs" "\n" 0)),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP TopP])]
 Window size:   (1820,944)
 Completion size:
                (750,399)
 Workspace:     Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw"
-Active pane:   Just "GameObject.hs"
+Active pane:   Just "Modules"
 Toolbar visible:
                True
 FindbarState:  (False,FindState {entryStr = "986", entryHist = ["986","drawElements","56","drawArray","drawVA","f","SV","VAO","'VAO'","\170","\\","^"], replaceStr = "V3.", replaceHist = [], caseSensitive = True, entireWord = False, wrapAround = False, regex = False, lineNr = 1})
diff --git a/Spear.lkshw b/Spear.lkshw
index 79c18ef..ff27127 100644
--- a/Spear.lkshw
+++ b/Spear.lkshw
@@ -1,10 +1,10 @@
 Version of workspace file format:
                1
 Time of storage:
-               "Fri Aug 31 20:53:49 CEST 2012"
+               "Sat Sep  1 11:10:35 CEST 2012"
 Name of the workspace:
                "Spear"
 File paths of contained packages:
                ["demos/simple-scene/simple-scene.cabal","Spear.cabal"]
 Maybe file path of an active package:
-               Just "demos/simple-scene/simple-scene.cabal"
\ No newline at end of file
+               Just "Spear.cabal"
\ No newline at end of file
diff --git a/Spear/Math/MatrixUtils.hs b/Spear/Math/MatrixUtils.hs
index 2c1d083..dcc1965 100644
--- a/Spear/Math/MatrixUtils.hs
+++ b/Spear/Math/MatrixUtils.hs
@@ -1,7 +1,6 @@
 module Spear.Math.MatrixUtils
 (
-    Rotation(..)
-,   fastNormalMatrix
+    fastNormalMatrix
 ,   rpgTransform
 ,   pltTransform
 ,   rpgInverse
@@ -16,9 +15,6 @@ import Spear.Math.Vector2 as V2
 import Spear.Math.Vector3 as V3
 
 
-data Rotation = Yaw | Pitch | Roll deriving Eq
-
-
 -- | Compute the normal matrix of the given matrix.
 fastNormalMatrix :: Matrix4 -> Matrix3
 fastNormalMatrix m =
@@ -31,21 +27,17 @@ fastNormalMatrix m =
 
 -- | Maps the given 2D transformation matrix to a 3D transformation matrix.
 rpgTransform
-    :: Float    -- ^ The height above the ground.
-    -> Float    -- ^ Angle of rotation.
-    -> Rotation -- ^ How the 2D rotation should be interpreted in 3D.
+    :: Float    -- ^ The height above the ground
+    -> Float    -- ^ Angle of rotation
+    -> Vector3  -- ^ Axis of rotation
     -> Matrix3
     -> Matrix4
-rpgTransform h a rtype mat =
+rpgTransform h a axis mat =
     {-let r = let r' = M3.right mat in vec3 (V2.x r') (V2.y r') 0
         u = V3.unity
         f = let f' = M3.forward mat in vec3 (V2.x f') 0 (V2.y f')
         t = (vec3 0 h 0) + let t' = M3.position mat in vec3 (V2.x t') 0 (V2.y t')-}
-    let rot = case rtype of
-            Yaw   -> rotY
-            Pitch -> rotX
-            Roll  -> rotZ
-        mat' = rot a
+    let mat' = axisAngle axis a
         r = M4.right mat'
         u = M4.up mat'
         f = M4.forward mat'
@@ -79,9 +71,9 @@ pltTransform mat =
 --
 -- Use this in games such as RPGs and RTSs.
 rpgInverse
-    :: Float    -- ^ The height above the ground.
-    -> Float    -- ^ Angle of rotation.
-    -> Rotation -- ^ How the 2D rotation should be interpreted in 3D.
+    :: Float    -- ^ The height above the ground
+    -> Float    -- ^ Angle of rotation
+    -> Vector3  -- ^ Axis of rotation
     -> Matrix3
     -> Matrix4
 rpgInverse h a rot = M4.inverseTransform . rpgTransform h a rot
diff --git a/Spear/Scene/GameObject.hs b/Spear/Scene/GameObject.hs
index f29ee09..d3b4e9e 100644
--- a/Spear/Scene/GameObject.hs
+++ b/Spear/Scene/GameObject.hs
@@ -3,7 +3,6 @@ module Spear.Scene.GameObject
     GameObject
 ,   GameStyle(..)
 ,   AM.AnimationSpeed
-,   Rotation(..)
     -- * Construction
 ,   goNew
     -- * Accessors
@@ -54,10 +53,10 @@ data GameStyle
 -- | An object in the game scene.
 data GameObject = GameObject
     { gameStyle    :: !GameStyle
-    , rotation     :: !Rotation
     , renderer     :: !(Either StaticModelRenderer AM.AnimatedModelRenderer)
     , collisioners :: ![Collisioner]
     , transform    :: !M3.Matrix3
+    , axis         :: Vector3
     , angle        :: Float
     }
 
@@ -136,17 +135,17 @@ instance S2.Spatial2 GameObject where
 
 -- | Create a new game object.
 goNew :: GameStyle
-      -> Rotation
       -> Either StaticModelResource AM.AnimatedModelResource
       -> [Collisioner]
-      -> M3.Matrix3
+      -> M3.Matrix3 -- ^ Transform
+      -> Vector3 -- ^ Axis of rotation
       -> GameObject
 
-goNew style rtype (Left smr) cols transf =
-    GameObject style rtype (Left $ SM.staticModelRenderer smr) cols transf 0
+goNew style (Left smr) cols transf axis =
+    GameObject style (Left $ SM.staticModelRenderer smr) cols transf axis 0
 
-goNew style rtype (Right amr) cols transf =
-    GameObject style rtype (Right $ AM.animatedModelRenderer 1 amr) cols transf 0
+goNew style (Right amr) cols transf axis =
+    GameObject style (Right $ AM.animatedModelRenderer 1 amr) cols transf axis 0
 
 
 goUpdate :: Float -> GameObject -> GameObject
@@ -160,6 +159,25 @@ goUpdate dt go =
        }
 
 
+-- | Get the game object's ith bounding box.
+goAABB :: Int -> GameObject -> AABB
+goAABB i go = goAABB' $ (collisioners go) !! i
+
+goAABB' col = case col of
+    (AABBCol box) -> box
+    (CircleCol circle) -> aabbFromCircle circle
+
+
+-- | Get the game object's bounding boxes.
+goAABBs :: GameObject -> [AABB]
+goAABBs = fmap goAABB' . collisioners
+
+
+-- | Get the game object's 3D transform.
+go3Dtransform :: GameObject -> M4.Matrix4
+go3Dtransform go = rpgTransform 0 (angle go) (axis go) . S2.transform $ go
+
+
 -- | Get the game object's current animation.
 currentAnimation :: Enum a => GameObject -> a
 currentAnimation go = case renderer go of
@@ -167,6 +185,11 @@ currentAnimation go = case renderer go of
     Right amr -> AM.currentAnimation amr 
 
 
+-- | Return the game object's number of collisioners.
+numCollisioners :: GameObject -> Int
+numCollisioners = length . collisioners
+
+
 -- | Set the game object's current animation.
 setAnimation :: Enum a => a -> GameObject -> GameObject
 setAnimation a go = case renderer go of
@@ -181,38 +204,14 @@ setAnimationSpeed s go = case renderer go of
     Right amr -> go { renderer = Right $ AM.setAnimationSpeed s amr } 
 
 
--- | Return the game object's number of collisioners.
-numCollisioners :: GameObject -> Int
-numCollisioners = length . collisioners
-
-
--- | Manipulate the game object's collisioners.
-withCollisioners :: GameObject -> ([Collisioner] -> [Collisioner]) -> GameObject
-withCollisioners go f = go { collisioners = f $ collisioners go }
-
-
 -- | Set the game object's collisioners.
 setCollisioners :: GameObject -> [Collisioner] -> GameObject
 setCollisioners go cols = go { collisioners = cols }
 
 
--- | Get the game object's ith bounding box.
-goAABB :: Int -> GameObject -> AABB
-goAABB i go = goAABB' $ (collisioners go) !! i
-
-goAABB' col = case col of
-    (AABBCol box) -> box
-    (CircleCol circle) -> aabbFromCircle circle
-
-
--- | Get the game object's bounding boxes.
-goAABBs :: GameObject -> [AABB]
-goAABBs = fmap goAABB' . collisioners
-
-
--- | Get the game object's 3D transform.
-go3Dtransform :: GameObject -> M4.Matrix4
-go3Dtransform go = rpgTransform 0 (angle go) (rotation go) . S2.transform $ go
+-- | Manipulate the game object's collisioners.
+withCollisioners :: GameObject -> ([Collisioner] -> [Collisioner]) -> GameObject
+withCollisioners go f = go { collisioners = f $ collisioners go }
 
 
 -- | Render the game object.
@@ -222,13 +221,13 @@ goRender sprog aprog cam go =
         apu = animatedProgramUniforms aprog
         mat = S2.transform go
         style = gameStyle go
-        rtype = rotation go
+        axis' = axis go
         a   = angle go
     in case renderer go of
         Left smr  ->
-            goRender' style a rtype sprog spu mat cam (SM.bind spu smr) (SM.render spu smr)
+            goRender' style a axis' sprog spu mat cam (SM.bind spu smr) (SM.render spu smr)
         Right amr ->
-            goRender' style a rtype aprog apu mat cam (AM.bind apu amr) (AM.render apu amr)
+            goRender' style a axis' aprog apu mat cam (AM.bind apu amr) (AM.render apu amr)
 
 
 type Bind = IO ()
@@ -239,7 +238,7 @@ type Render = IO ()
 goRender' :: (ProgramUniforms u, Program p)
           => GameStyle
           -> Float
-          -> Rotation
+          -> Vector3
           -> p
           -> u
           -> M3.Matrix3
@@ -247,10 +246,10 @@ goRender' :: (ProgramUniforms u, Program p)
           -> Bind
           -> Render
           -> IO ()
-goRender' style a rtype prog uniforms model cam bindRenderer render =
+goRender' style a axis prog uniforms model cam bindRenderer render =
     let view  = M4.inverseTransform $ Cam.transform cam
         modelview = case style of
-            RPG -> view * rpgTransform 0 a rtype model
+            RPG -> view * rpgTransform 0 a axis model
             PLT -> view * pltTransform model
         normalmat = fastNormalMatrix modelview
     in do
diff --git a/Spear/Scene/Loader.hs b/Spear/Scene/Loader.hs
index ea08385..f5d06a6 100644
--- a/Spear/Scene/Loader.hs
+++ b/Spear/Scene/Loader.hs
@@ -31,7 +31,7 @@ import Spear.Render.AnimatedModel as AM
 import Spear.Render.Material
 import Spear.Render.Program
 import Spear.Render.StaticModel as SM
-import qualified Spear.Scene.GameObject as GO
+import Spear.Scene.GameObject as GO
 import Spear.Scene.Graph
 import Spear.Scene.Light
 import Spear.Scene.SceneResources
@@ -342,18 +342,18 @@ newLight _ = return ()
 -- Object Loading --
 --------------------
 
-loadGO :: GO.GameStyle -> SceneResources -> [Property] -> Matrix3 -> Setup GO.GameObject
+loadGO :: GameStyle -> SceneResources -> [Property] -> Matrix3 -> Setup GameObject
 loadGO style sceneRes props transf = do
     modelName <- asString . mandatory "model"    $ props
-    rtype <- asGORotation . mandatory "rotation" $ props
+    axis <- asVec3 . mandatory "axis" $ props
     let animSpeed = asFloat  . value "animation-speed" $ props
     go <- case getAnimatedModel sceneRes modelName of
         Just model ->
-            return $ GO.goNew style rtype (Right model) [] transf
+            return $ goNew style (Right model) [] transf axis
         Nothing ->
             case getStaticModel sceneRes modelName of
                 Just model ->
-                    return $ GO.goNew style rtype (Left model) [] transf
+                    return $ goNew style (Left model) [] transf axis
                 Nothing ->
                     setupError $ "model " ++ modelName ++ " not found"
     return $ case animSpeed of
@@ -467,13 +467,6 @@ asRotation val = fmap parseRotation val
     where parseRotation (ax:ay:az:order:_) = Rotation (read ax) (read ay) (read az) (readOrder order)
 
 
-asGORotation :: Functor f => f [String] -> f GO.Rotation
-asGORotation val = fmap parseRotation val
-    where parseRotation ["yaw"]   = GO.Yaw
-          parseRotation ["pitch"] = GO.Pitch
-          parseRotation ["roll"]  = GO.Roll
-
-
 data Rotation = Rotation
     { ax    :: Float
     , ay    :: Float
-- 
cgit v1.2.3