From fc802a58cff52083327b343ba04c9e67331d9d5a Mon Sep 17 00:00:00 2001 From: Jeanne-Kamikaze Date: Thu, 21 Feb 2013 19:24:47 +0100 Subject: Added Vector and Vector.Class modules --- Spear.cabal | 6 +- Spear/Collision.hs | 123 ++++++++++++++------------- Spear/GLSL.hs | 22 +++-- Spear/Math/AABB.hs | 2 +- Spear/Math/Camera.hs | 2 +- Spear/Math/Circle.hs | 2 +- Spear/Math/Entity.hs | 2 +- Spear/Math/Matrix3.hs | 48 ++++++----- Spear/Math/Matrix4.hs | 97 +++++++++++----------- Spear/Math/MatrixUtils.hs | 49 ++++++----- Spear/Math/Plane.hs | 2 +- Spear/Math/Quad.hs | 2 +- Spear/Math/QuadTree.hs | 2 +- Spear/Math/Quaternion.hs | 43 +++++----- Spear/Math/Ray.hs | 2 +- Spear/Math/Segment.hs | 2 +- Spear/Math/Spatial2.hs | 2 +- Spear/Math/Spatial3.hs | 4 +- Spear/Math/Triangle.hs | 2 +- Spear/Math/Utils.hs | 11 ++- Spear/Math/Vector.hs | 13 +++ Spear/Math/Vector/Class.hs | 43 ++++++++++ Spear/Math/Vector/Vector2.hs | 120 +++++++++++++++++++++++++++ Spear/Math/Vector/Vector3.hs | 165 +++++++++++++++++++++++++++++++++++++ Spear/Math/Vector/Vector4.hs | 154 ++++++++++++++++++++++++++++++++++ Spear/Math/Vector2.hs | 145 -------------------------------- Spear/Math/Vector3.hs | 187 ------------------------------------------ Spear/Math/Vector4.hs | 176 --------------------------------------- Spear/Physics/Rigid.hs | 22 ++--- Spear/Physics/Types.hs | 2 +- Spear/Render/AnimatedModel.hs | 3 +- Spear/Render/Material.hs | 2 +- Spear/Render/StaticModel.hs | 2 +- Spear/Scene/GameObject.hs | 21 +++-- Spear/Scene/Light.hs | 3 +- Spear/Scene/Loader.hs | 26 +++--- Spear/Scene/SceneResources.hs | 2 +- 37 files changed, 743 insertions(+), 768 deletions(-) create mode 100644 Spear/Math/Vector.hs create mode 100644 Spear/Math/Vector/Class.hs create mode 100644 Spear/Math/Vector/Vector2.hs create mode 100644 Spear/Math/Vector/Vector3.hs create mode 100644 Spear/Math/Vector/Vector4.hs delete mode 100644 Spear/Math/Vector2.hs delete mode 100644 Spear/Math/Vector3.hs delete mode 100644 Spear/Math/Vector4.hs diff --git a/Spear.cabal b/Spear.cabal index 051d955..f7d0536 100644 --- a/Spear.cabal +++ b/Spear.cabal @@ -22,13 +22,15 @@ library Spear.Math.AABB Spear.Math.Circle Spear.Math.Triangle Spear.Game Spear.GLSL Spear.Math.Camera Spear.Math.Entity Spear.Math.Matrix3 Spear.Math.Matrix4 Spear.Math.MatrixUtils Spear.Math.Plane - Spear.Math.Quaternion Spear.Math.Vector3 Spear.Math.Vector4 + Spear.Math.Quaternion Spear.Math.Vector Spear.Math.Vector.Class + Spear.Math.Vector.Vector3 Spear.Math.Vector.Vector4 + Spear.Math.Vector.Vector2 Spear.Physics Spear.Physics.Rigid Spear.Render.AnimatedModel Spear.Render.Material Spear.Render.Model Spear.Render.Program Spear.Render.StaticModel Spear.Scene.Graph Spear.Scene.Light Spear.Scene.Loader Spear.Scene.Scene Spear.Scene.SceneResources Spear.Setup Spear.Sys.Timer Spear.Sys.Store Spear.Sys.Store.ID - Spear.Math.Vector2 Spear.Math.Quad Spear.Math.Ray + Spear.Math.Quad Spear.Math.Ray Spear.Math.Segment Spear.Math.Utils Spear.Math.Spatial2 Spear.Math.Spatial3 exposed: True diff --git a/Spear/Collision.hs b/Spear/Collision.hs index 8c334c1..3b80696 100644 --- a/Spear/Collision.hs +++ b/Spear/Collision.hs @@ -5,13 +5,13 @@ module Spear.Collision , Collisionable(..) -- * Collisioners , Collisioner(..) - -- ** Construction -, aabbCollisioner + -- ** Construction +, aabbCollisioner , circleCollisioner -, boxFromCircle +, boxFromCircle , buildAABB , mkCols - -- ** Collision test + -- ** Collision test , collide -- ** Manipulation , move @@ -26,8 +26,7 @@ import Spear.Math.AABB import Spear.Math.Circle import qualified Spear.Math.Matrix4 as M4 import Spear.Math.Plane -import Spear.Math.Vector2 -import qualified Spear.Math.Vector3 as V3 +import Spear.Math.Vector -- | Encodes several collision situations. @@ -118,54 +117,54 @@ aabbPoints (AABB min max) = [p1,p2,p3,p4,p5,p6,p7,p8] p8 = vec2 (x max) (y max) --- | A collisioner component. -data Collisioner - -- | An axis-aligned bounding box. - = AABBCol {-# UNPACK #-} !AABB - -- | A bounding circle. - | CircleCol {-# UNPACK #-} !Circle - - --- | Create a collisioner from the specified box. -aabbCollisioner :: AABB -> Collisioner -aabbCollisioner = AABBCol - - --- | Create a collisioner from the specified circle. -circleCollisioner :: Circle -> Collisioner +-- | A collisioner component. +data Collisioner + -- | An axis-aligned bounding box. + = AABBCol {-# UNPACK #-} !AABB + -- | A bounding circle. + | CircleCol {-# UNPACK #-} !Circle + + +-- | Create a collisioner from the specified box. +aabbCollisioner :: AABB -> Collisioner +aabbCollisioner = AABBCol + + +-- | Create a collisioner from the specified circle. +circleCollisioner :: Circle -> Collisioner circleCollisioner = CircleCol --- | Create the minimal AABB collisioner fully containing the specified circle. -boxFromCircle :: Circle -> Collisioner -boxFromCircle = AABBCol . aabbFromCircle - - --- | Create the minimal AABB fully containing the specified collisioners. -buildAABB :: [Collisioner] -> AABB +-- | Create the minimal AABB collisioner fully containing the specified circle. +boxFromCircle :: Circle -> Collisioner +boxFromCircle = AABBCol . aabbFromCircle + + +-- | Create the minimal AABB fully containing the specified collisioners. +buildAABB :: [Collisioner] -> AABB buildAABB cols = aabb $ generatePoints cols - - -generatePoints :: [Collisioner] -> [Vector2] -generatePoints = foldr generate [] - where - generate (AABBCol (AABB min max)) acc = p1:p2:p3:p4:p5:p6:p7:p8:acc - where - p1 = vec2 (x min) (y min) - p2 = vec2 (x min) (y min) - p3 = vec2 (x min) (y max) - p4 = vec2 (x min) (y max) - p5 = vec2 (x max) (y min) - p6 = vec2 (x max) (y min) - p7 = vec2 (x max) (y max) - p8 = vec2 (x max) (y max) - - generate (CircleCol (Circle c r)) acc = p1:p2:p3:p4:acc - where - p1 = c + unitx * (vec2 r r) - p2 = c - unitx * (vec2 r r) - p3 = c + unity * (vec2 r r) - p4 = c - unity * (vec2 r r) + + +generatePoints :: [Collisioner] -> [Vector2] +generatePoints = foldr generate [] + where + generate (AABBCol (AABB pmin pmax)) acc = p1:p2:p3:p4:p5:p6:p7:p8:acc + where + p1 = vec2 (x pmin) (y pmin) + p2 = vec2 (x pmin) (y pmin) + p3 = vec2 (x pmin) (y pmax) + p4 = vec2 (x pmin) (y pmax) + p5 = vec2 (x pmax) (y pmin) + p6 = vec2 (x pmax) (y pmin) + p7 = vec2 (x pmax) (y pmax) + p8 = vec2 (x pmax) (y pmax) + + generate (CircleCol (Circle c r)) acc = p1:p2:p3:p4:acc + where + p1 = c + unitx2 * (vec2 r r) + p2 = c - unitx2 * (vec2 r r) + p3 = c + unity2 * (vec2 r r) + p4 = c - unity2 * (vec2 r r) -- | Compute AABB collisioners in view space from the given 3D AABB. @@ -174,22 +173,22 @@ mkCols :: M4.Matrix4 -- ^ Modelview matrix -> [Collisioner] mkCols modelview (Box (Vec3 xmin ymin zmin) (Vec3 xmax ymax zmax)) = let - toVec2 v = vec2 (V3.x v) (V3.y v) - p1 = toVec2 $ modelview `M4.mulp` V3.vec3 xmin ymin zmax - p2 = toVec2 $ modelview `M4.mulp` V3.vec3 xmax ymin zmin - p3 = toVec2 $ modelview `M4.mulp` V3.vec3 xmax ymax zmin + toVec2 v = vec2 (x v) (y v) + p1 = toVec2 $ modelview `M4.mulp` vec3 xmin ymin zmax + p2 = toVec2 $ modelview `M4.mulp` vec3 xmax ymin zmin + p3 = toVec2 $ modelview `M4.mulp` vec3 xmax ymax zmin col1 = AABBCol $ AABB p1 p2 col2 = AABBCol $ AABB p1 p3 in [col1, col2] - - --- | Collide the given collisioners. -collide :: Collisioner -> Collisioner -> CollisionType -collide (AABBCol box1) (AABBCol box2) = collideBox box1 box2 -collide (CircleCol s1) (CircleCol s2) = collideCircle s1 s2 -collide (AABBCol box) (CircleCol circle) = collideBox box circle -collide (CircleCol circle) (AABBCol box) = collideCircle circle box + + +-- | Collide the given collisioners. +collide :: Collisioner -> Collisioner -> CollisionType +collide (AABBCol box1) (AABBCol box2) = collideBox box1 box2 +collide (CircleCol s1) (CircleCol s2) = collideCircle s1 s2 +collide (AABBCol box) (CircleCol circle) = collideBox box circle +collide (CircleCol circle) (AABBCol box) = collideCircle circle box -- | Move the collisioner. diff --git a/Spear/GLSL.hs b/Spear/GLSL.hs index c00582d..2947515 100644 --- a/Spear/GLSL.hs +++ b/Spear/GLSL.hs @@ -93,9 +93,7 @@ where import Spear.Assets.Image import Spear.Math.Matrix3 (Matrix3) import Spear.Math.Matrix4 (Matrix4) -import Spear.Math.Vector2 as V2 -import Spear.Math.Vector3 as V3 -import Spear.Math.Vector4 as V4 +import Spear.Math.Vector import Spear.Setup import Control.Monad @@ -371,25 +369,25 @@ readSource' file = do -- | Load a 2D vector. uniformVec2 :: GLint -> Vector2 -> IO () uniformVec2 loc v = glUniform2f loc x' y' - where x' = unsafeCoerce $ V2.x v - y' = unsafeCoerce $ V2.y v + where x' = unsafeCoerce $ x v + y' = unsafeCoerce $ y v -- | Load a 3D vector. uniformVec3 :: GLint -> Vector3 -> IO () uniformVec3 loc v = glUniform3f loc x' y' z' - where x' = unsafeCoerce $ V3.x v - y' = unsafeCoerce $ V3.y v - z' = unsafeCoerce $ V3.z v + where x' = unsafeCoerce $ x v + y' = unsafeCoerce $ y v + z' = unsafeCoerce $ z v -- | Load a 4D vector. uniformVec4 :: GLint -> Vector4 -> IO () uniformVec4 loc v = glUniform4f loc x' y' z' w' - where x' = unsafeCoerce $ V4.x v - y' = unsafeCoerce $ V4.y v - z' = unsafeCoerce $ V4.z v - w' = unsafeCoerce $ V4.w v + where x' = unsafeCoerce $ x v + y' = unsafeCoerce $ y v + z' = unsafeCoerce $ z v + w' = unsafeCoerce $ w v -- | Load a 3x3 matrix. diff --git a/Spear/Math/AABB.hs b/Spear/Math/AABB.hs index cd945a6..0dacfa4 100644 --- a/Spear/Math/AABB.hs +++ b/Spear/Math/AABB.hs @@ -7,7 +7,7 @@ module Spear.Math.AABB where -import Spear.Math.Vector2 +import Spear.Math.Vector -- | An axis-aligned bounding box. diff --git a/Spear/Math/Camera.hs b/Spear/Math/Camera.hs index acde7d0..e22f3c2 100644 --- a/Spear/Math/Camera.hs +++ b/Spear/Math/Camera.hs @@ -4,7 +4,7 @@ where import qualified Spear.Math.Matrix4 as M import qualified Spear.Math.Spatial3 as S -import Spear.Math.Vector3 +import Spear.Math.Vector data Camera = Camera diff --git a/Spear/Math/Circle.hs b/Spear/Math/Circle.hs index daaafc5..ab256a4 100644 --- a/Spear/Math/Circle.hs +++ b/Spear/Math/Circle.hs @@ -7,7 +7,7 @@ module Spear.Math.Circle where -import Spear.Math.Vector2 +import Spear.Math.Vector -- | A bounding volume. diff --git a/Spear/Math/Entity.hs b/Spear/Math/Entity.hs index 2dc6965..4fc3d87 100644 --- a/Spear/Math/Entity.hs +++ b/Spear/Math/Entity.hs @@ -7,7 +7,7 @@ where import qualified Spear.Math.Matrix3 as M import qualified Spear.Math.Spatial2 as S -import qualified Spear.Math.Vector2 as V +import qualified Spear.Math.Vector as V -- | An entity in 2D space. diff --git a/Spear/Math/Matrix3.hs b/Spear/Math/Matrix3.hs index d5e46e9..497cb4e 100644 --- a/Spear/Math/Matrix3.hs +++ b/Spear/Math/Matrix3.hs @@ -40,8 +40,7 @@ module Spear.Math.Matrix3 where -import Spear.Math.Vector2 as V2 -import Spear.Math.Vector3 as V3 +import Spear.Math.Vector import Foreign.Storable @@ -142,9 +141,9 @@ mat3 = Matrix3 -- | Build a matrix from three vectors in 3D. mat3fromVec :: Vector3 -> Vector3 -> Vector3 -> Matrix3 mat3fromVec v0 v1 v2 = Matrix3 - (V3.x v0) (V3.x v1) (V3.x v2) - (V3.y v0) (V3.y v1) (V3.y v2) - (V3.z v0) (V3.z v1) (V3.z v2) + (x v0) (x v1) (x v2) + (y v0) (y v1) (y v2) + (z v0) (z v1) (z v2) -- | Build a transformation matrix. @@ -154,8 +153,8 @@ transform :: Vector2 -- ^ Right vector -> Matrix3 -- ^ Transform transform r f p = mat3 - (V2.x r) (V2.x f) (V2.x p) - (V2.y r) (V2.y f) (V2.y p) + (x r) (x f) (x p) + (y r) (y f) (y p) 0 0 1 @@ -205,8 +204,8 @@ transl tx ty = mat3 -- | Create a translation matrix. translv :: Vector2 -> Matrix3 translv v = mat3 - 1 0 (V2.x v) - 0 1 (V2.y v) + 1 0 (x v) + 0 1 (y v) 0 0 1 @@ -238,9 +237,9 @@ scalev v = mat3 0 sy 0 0 0 sz where - sx = V3.x v - sy = V3.y v - sz = V3.z v + sx = x v + sy = y v + sz = z v -- | Create an X reflection matrix. @@ -279,9 +278,9 @@ transpose m = mat3 mulp :: Matrix3 -> Vector2 -> Vector2 mulp m v = vec2 x' y' where - v' = vec3 (V2.x v) (V2.y v) 1 - x' = row0 m `V3.dot` v' - y' = row1 m `V3.dot` v' + v' = vec3 (x v) (y v) 1 + x' = row0 m `dot` v' + y' = row1 m `dot` v' @@ -289,19 +288,19 @@ mulp m v = vec2 x' y' muld :: Matrix3 -> Vector2 -> Vector2 muld m v = vec2 x' y' where - v' = vec3 (V2.x v) (V2.y v) 0 - x' = row0 m `V3.dot` v' - y' = row1 m `V3.dot` v' + v' = vec3 (x v) (y v) 0 + x' = row0 m `dot` v' + y' = row1 m `dot` v' -- | Transform the given vector in 3D space with the given matrix. mul :: Matrix3 -> Vector3 -> Vector3 mul m v = vec3 x' y' z' where - v' = vec3 (V3.x v) (V3.y v) (V3.z v) - x' = row0 m `V3.dot` v' - y' = row1 m `V3.dot` v' - z' = row2 m `V3.dot` v' + v' = vec3 (x v) (y v) (z v) + x' = row0 m `dot` v' + y' = row1 m `dot` v' + z' = row2 m `dot` v' -- | Zip two 'Matrix3' together with the specified function. @@ -327,11 +326,10 @@ inverseTransform mat = f = forward mat t = -(position mat) in mat3 - (V2.x r) (V2.y r) (t `V2.dot` r) - (V2.x f) (V2.y f) (t `V2.dot` f) + (x r) (y r) (t `dot` r) + (x f) (y f) (t `dot` f) 0 0 1 fromDeg :: (Floating a) => a -> a fromDeg = (*pi) . (/180) - diff --git a/Spear/Math/Matrix4.hs b/Spear/Math/Matrix4.hs index 41bfadd..1424b28 100644 --- a/Spear/Math/Matrix4.hs +++ b/Spear/Math/Matrix4.hs @@ -51,8 +51,7 @@ module Spear.Math.Matrix4 where -import Spear.Math.Vector3 as V3 -import Spear.Math.Vector4 as V4 +import Spear.Math.Vector import Foreign.Storable @@ -171,10 +170,10 @@ mat4 = Matrix4 -- | Build a matrix from four vectors in 4D. mat4fromVec :: Vector4 -> Vector4 -> Vector4 -> Vector4 -> Matrix4 mat4fromVec v0 v1 v2 v3 = Matrix4 - (V4.x v0) (V4.x v1) (V4.x v2) (V4.x v3) - (V4.y v0) (V4.y v1) (V4.y v2) (V4.y v3) - (V4.z v0) (V4.z v1) (V4.z v2) (V4.z v3) - (V4.w v0) (V4.w v1) (V4.w v2) (V4.w v3) + (x v0) (x v1) (x v2) (x v3) + (y v0) (y v1) (y v2) (y v3) + (z v0) (z v1) (z v2) (z v3) + (w v0) (w v1) (w v2) (w v3) -- | Build a transformation 'Matrix4' from the given vectors. @@ -185,9 +184,9 @@ transform :: Vector3 -- ^ Right vector. -> Matrix4 transform right up fwd pos = mat4 - (V3.x right) (V3.x up) (V3.x fwd) (V3.x pos) - (V3.y right) (V3.y up) (V3.y fwd) (V3.y pos) - (V3.z right) (V3.z up) (V3.z fwd) (V3.z pos) + (x right) (x up) (x fwd) (x pos) + (y right) (y up) (y fwd) (y pos) + (z right) (z up) (z fwd) (z pos) 0 0 0 1 @@ -225,8 +224,8 @@ lookAt :: Vector3 -- ^ Eye position. -> Matrix4 lookAt pos target = - let fwd = V3.normalise $ target - pos - r = fwd `cross` V3.unity + let fwd = normalise $ target - pos + r = fwd `cross` unity3 u = r `cross` fwd in transform r u (-fwd) pos @@ -271,9 +270,9 @@ transl x y z = mat4 -- | Create a translation matrix. translv :: Vector3 -> Matrix4 translv v = mat4 - 1 0 0 (V3.x v) - 0 1 0 (V3.y v) - 0 0 1 (V3.z v) + 1 0 0 (x v) + 0 1 0 (y v) + 0 0 1 (z v) 0 0 0 1 @@ -320,22 +319,22 @@ rotZ angle = mat4 -- The given angle must be in degrees. axisAngle :: Vector3 -> Float -> Matrix4 axisAngle v angle = mat4 - (c + omc*x^2) (omc*xy-sz) (omc*xz+sy) 0 - (omc*xy+sz) (c+omc*y^2) (omc*yz-sx) 0 - (omc*xz-sy) (omc*yz+sx) (c+omc*z^2) 0 - 0 0 0 1 + (c + omc*ax^2) (omc*xy-sz) (omc*xz+sy) 0 + (omc*xy+sz) (c+omc*ay^2) (omc*yz-sx) 0 + (omc*xz-sy) (omc*yz+sx) (c+omc*az^2) 0 + 0 0 0 1 where - x = V3.x v - y = V3.y v - z = V3.z v + ax = x v + ay = y v + az = z v s = sin . toRAD $ angle c = cos . toRAD $ angle - xy = x*y - xz = x*z - yz = y*z - sx = s*x - sy = s*y - sz = s*z + xy = ax*ay + xz = ax*az + yz = ay*az + sx = s*ax + sy = s*ay + sz = s*az omc = 1 - c @@ -356,9 +355,9 @@ scalev v = mat4 0 0 sz 0 0 0 0 1 where - sx = V3.x v - sy = V3.y v - sz = V3.z v + sx = x v + sy = y v + sz = z v -- | Create an X reflection matrix. @@ -430,13 +429,13 @@ planeProj :: Vector3 -- ^ Plane normal -> Vector3 -- ^ Projection direction -> Matrix4 planeProj n d l = - let c = n `V3.dot` l - nx = V3.x n - ny = V3.y n - nz = V3.z n - lx = V3.x l - ly = V3.y l - lz = V3.z l + let c = n `dot` l + nx = x n + ny = y n + nz = z n + lx = x l + ly = y l + lz = z l in mat4 (d + c - nx*lx) (-ny*lx) (-nz*lx) (-lx*d) (-nx*ly) (d + c - ny*ly) (-nz*ly) (-ly*d) @@ -463,9 +462,9 @@ inverseTransform mat = t = position mat in mat4 - (V3.x r) (V3.y r) (V3.z r) (-t `V3.dot` r) - (V3.x u) (V3.y u) (V3.z u) (-t `V3.dot` u) - (V3.x f) (V3.y f) (V3.z f) (-t `V3.dot` f) + (x r) (y r) (z r) (-t `dot` r) + (x u) (y u) (z u) (-t `dot` u) + (x f) (y f) (z f) (-t `dot` f) 0 0 0 1 @@ -618,10 +617,10 @@ inverse mat = mul :: Float -> Matrix4 -> Vector3 -> Vector3 mul w m v = vec3 x' y' z' where - v' = vec4 (V3.x v) (V3.y v) (V3.z v) w - x' = row0 m `V4.dot` v' - y' = row1 m `V4.dot` v' - z' = row2 m `V4.dot` v' + v' = vec4 (x v) (y v) (z v) w + x' = row0 m `dot` v' + y' = row1 m `dot` v' + z' = row2 m `dot` v' -- | Transform the given point vector in 3D space with the given matrix. @@ -641,11 +640,11 @@ muld = mul 0 mul' :: Float -> Matrix4 -> Vector3 -> Vector3 mul' w m v = vec3 (x'/w') (y'/w') (z'/w') where - v' = vec4 (V3.x v) (V3.y v) (V3.z v) w - x' = row0 m `V4.dot` v' - y' = row1 m `V4.dot` v' - z' = row2 m `V4.dot` v' - w' = row3 m `V4.dot` v' + v' = vec4 (x v) (y v) (z v) w + x' = row0 m `dot` v' + y' = row1 m `dot` v' + z' = row2 m `dot` v' + w' = row3 m `dot` v' toRAD = (*pi) . (/180) diff --git a/Spear/Math/MatrixUtils.hs b/Spear/Math/MatrixUtils.hs index 629b73c..79bd049 100644 --- a/Spear/Math/MatrixUtils.hs +++ b/Spear/Math/MatrixUtils.hs @@ -15,8 +15,7 @@ where import Spear.Math.Camera as Cam import Spear.Math.Matrix3 as M3 import Spear.Math.Matrix4 as M4 -import Spear.Math.Vector2 as V2 -import Spear.Math.Vector3 as V3 +import Spear.Math.Vector as V -- | Compute the normal matrix of the given matrix. @@ -39,14 +38,14 @@ unproject :: Matrix4 -- ^ Inverse projection matrix -> Float -- ^ Window x -> Float -- ^ Window y -> Float -- ^ Window z - -> V3.Vector3 + -> Vector3 unproject projI modelviewI vpx vpy w h x y z = let xmouse = 2*(x-vpx)/w - 1 ymouse = 2*(y-vpy)/h - 1 zmouse = 2*z - 1 in - (modelviewI * projI) `M4.mulp` V3.vec3 xmouse ymouse zmouse + (modelviewI * projI) `M4.mulp` vec3 xmouse ymouse zmouse -- | Transform the given point in window coordinates to 2d coordinates. @@ -63,14 +62,14 @@ rpgUnproject -> Float -- ^ Window x -> Float -- ^ Window y -> Vector2 -rpgUnproject projI viewI vpx vpy w h x y = +rpgUnproject projI viewI vpx vpy w h wx wy = let - p1 = unproject projI viewI vpx vpy w h x y 0 - p2 = unproject projI viewI vpx vpy w h x y (-1) - lambda = (V3.y p1 / (V3.y p1 - V3.y p2)) - p' = p1 + V3.scale lambda (p2 - p1) + p1 = unproject projI viewI vpx vpy w h wx wy 0 + p2 = unproject projI viewI vpx vpy w h wx wy (-1) + lambda = (y p1 / (y p1 - y p2)) + p' = p1 + V.scale lambda (p2 - p1) in - vec2 (V3.x p') (-V3.z p') + vec2 (x p') (-(z p')) -- | Map an object's transform in view space to world space. @@ -82,33 +81,33 @@ rpgTransform -> Matrix4 -- ^ Inverse view matrix -> Matrix4 rpgTransform h a axis pos viewI = - let p1 = viewI `M4.mulp` (vec3 (V2.x pos) (V2.y pos) 0) - p2 = viewI `M4.mulp` (vec3 (V2.x pos) (V2.y pos) (-1)) - lambda = (V3.y p1 / (V3.y p1 - V3.y p2)) - p = p1 + V3.scale lambda (p2 - p1) + let p1 = viewI `M4.mulp` (vec3 (x pos) (y pos) 0) + p2 = viewI `M4.mulp` (vec3 (x pos) (y pos) (-1)) + lambda = (y p1 / (y p1 - y p2)) + p = p1 + V.scale lambda (p2 - p1) mat' = axisAngle axis a r = M4.right mat' u = M4.up mat' f = M4.forward mat' t = p + vec3 0 h 0 in mat4 - (V3.x r) (V3.x u) (V3.x f) (V3.x t) - (V3.y r) (V3.y u) (V3.y f) (V3.y t) - (V3.z r) (V3.z u) (V3.z f) (V3.z t) + (x r) (x u) (x f) (x t) + (y r) (y u) (y f) (y t) + (z r) (z u) (z f) (z t) 0 0 0 1 -- | Map an object's transform in view space to world space. pltTransform :: Matrix3 -> Matrix4 pltTransform mat = - let r = let r' = M3.right mat in vec3 (V2.x r') (V2.y r') 0 - u = let u' = M3.up mat in vec3 (V2.x u') (V2.y u') 0 - f = V3.unitz - t = let t' = M3.position mat in vec3 (V2.x t') (V2.y t') 0 + let r = let r' = M3.right mat in vec3 (x r') (y r') 0 + u = let u' = M3.up mat in vec3 (x u') (y u') 0 + f = unitz3 + t = let t' = M3.position mat in vec3 (x t') (y t') 0 in mat4 - (V3.x r) (V3.x u) (V3.x f) (V3.x t) - (V3.y r) (V3.y u) (V3.y f) (V3.y t) - (V3.z r) (V3.z u) (V3.z f) (V3.z t) + (x r) (x u) (x f) (x t) + (y r) (y u) (y f) (y t) + (z r) (z u) (z f) (z t) 0 0 0 1 @@ -147,4 +146,4 @@ objToClip cam model p = proj = Cam.projection cam p' = (proj * view * model) `M4.mulp` p in - vec2 (V3.x p') (V3.y p') + vec2 (x p') (y p') diff --git a/Spear/Math/Plane.hs b/Spear/Math/Plane.hs index 6fabbec..b20740c 100644 --- a/Spear/Math/Plane.hs +++ b/Spear/Math/Plane.hs @@ -7,7 +7,7 @@ module Spear.Math.Plane where -import Spear.Math.Vector3 +import Spear.Math.Vector data PointPlanePos = Front | Back | Contained deriving (Eq, Ord, Show) diff --git a/Spear/Math/Quad.hs b/Spear/Math/Quad.hs index e75607c..6b6215c 100644 --- a/Spear/Math/Quad.hs +++ b/Spear/Math/Quad.hs @@ -8,7 +8,7 @@ where import Spear.Math.Segment import Spear.Math.Utils -import Spear.Math.Vector2 +import Spear.Math.Vector data Quad = Quad diff --git a/Spear/Math/QuadTree.hs b/Spear/Math/QuadTree.hs index e553c88..d6b6353 100644 --- a/Spear/Math/QuadTree.hs +++ b/Spear/Math/QuadTree.hs @@ -11,7 +11,7 @@ where import Spear.Collision import Spear.Math.AABB -import Spear.Math.Vector2 +import Spear.Math.Vector import Control.Applicative ((<*>)) import Data.List diff --git a/Spear/Math/Quaternion.hs b/Spear/Math/Quaternion.hs index 4eb88d7..cfc6cd2 100644 --- a/Spear/Math/Quaternion.hs +++ b/Spear/Math/Quaternion.hs @@ -10,15 +10,14 @@ module Spear.Math.Quaternion , qmul , qconj , qinv -, Spear.Math.Quaternion.normalise -, Spear.Math.Quaternion.norm +, qnormalise +, qnorm , qrot ) where -import qualified Spear.Math.Vector3 as V3 -import Spear.Math.Vector4 as V4 +import Spear.Math.Vector newtype Quaternion = Quaternion { getVec :: Vector4 } @@ -39,23 +38,23 @@ qvec4 = Quaternion -- | Build a 'Quaternion' from the given 'Vector3' and w. -qvec3 :: V3.Vector3 -> Float -> Quaternion -qvec3 v w = Quaternion $ vec4 (V3.x v) (V3.y v) (V3.z v) w +qvec3 :: Vector3 -> Float -> Quaternion +qvec3 v w = Quaternion $ vec4 (x v) (y v) (z v) w -- | Build a 'Quaternion' representing the given rotation. -qAxisAngle :: V3.Vector3 -> Float -> Quaternion +qAxisAngle :: Vector3 -> Float -> Quaternion qAxisAngle axis angle = - let s' = V3.norm axis - s = if s' == 0 then 1 else s' - a = angle * toRAD * 0.5 - sa = sin a - w = cos a - x = V3.x axis * sa * s - y = V3.y axis * sa * s - z = V3.z axis * sa * s + let s' = norm axis + s = if s' == 0 then 1 else s' + a = angle * toRAD * 0.5 + sa = sin a + qw = cos a + qx = x axis * sa * s + qy = y axis * sa * s + qz = z axis * sa * s in - Quaternion $ vec4 x y z w + Quaternion $ vec4 qx qy qz qw -- | Compute the product of the given two quaternions. @@ -90,19 +89,19 @@ qinv (Quaternion q) = -- | Normalise the given 'Quaternion'. -normalise :: Quaternion -> Quaternion -normalise = Quaternion . V4.normalise . getVec +qnormalise :: Quaternion -> Quaternion +qnormalise = Quaternion . normalise . getVec -- | Compute the norm of the given 'Quaternion'. -norm :: Quaternion -> Float -norm = V4.norm . getVec +qnorm :: Quaternion -> Float +qnorm = norm . getVec -- | Rotate the given 'Vector3'. -qrot :: Quaternion -> V3.Vector3 -> V3.Vector3 +qrot :: Quaternion -> Vector3 -> Vector3 qrot q v = toVec3 $ q `qmul` qvec3 v 0 `qmul` qconj q - where toVec3 (Quaternion q) = V3.vec3 (x q) (y q) (z q) + where toVec3 (Quaternion q) = vec3 (x q) (y q) (z q) toRAD = pi / 180 diff --git a/Spear/Math/Ray.hs b/Spear/Math/Ray.hs index 697d609..b0359a1 100644 --- a/Spear/Math/Ray.hs +++ b/Spear/Math/Ray.hs @@ -8,7 +8,7 @@ where import Spear.Math.Utils -import Spear.Math.Vector2 +import Spear.Math.Vector data Ray = Ray diff --git a/Spear/Math/Segment.hs b/Spear/Math/Segment.hs index a89ee05..c632838 100644 --- a/Spear/Math/Segment.hs +++ b/Spear/Math/Segment.hs @@ -7,7 +7,7 @@ where import Spear.Math.Utils -import Spear.Math.Vector2 +import Spear.Math.Vector -- | A line segment in 2D space. diff --git a/Spear/Math/Spatial2.hs b/Spear/Math/Spatial2.hs index 49ff3b7..341282b 100644 --- a/Spear/Math/Spatial2.hs +++ b/Spear/Math/Spatial2.hs @@ -2,7 +2,7 @@ module Spear.Math.Spatial2 where -import Spear.Math.Vector2 +import Spear.Math.Vector import Spear.Math.Matrix3 as M diff --git a/Spear/Math/Spatial3.hs b/Spear/Math/Spatial3.hs index 0ee680f..6db3853 100644 --- a/Spear/Math/Spatial3.hs +++ b/Spear/Math/Spatial3.hs @@ -2,7 +2,7 @@ module Spear.Math.Spatial3 where -import Spear.Math.Vector3 +import Spear.Math.Vector import Spear.Math.Matrix4 as M @@ -57,7 +57,7 @@ class Spatial3 s where lookAt pt s = let position = pos s fwd = normalise $ pt - position - r = fwd `cross` unity + r = fwd `cross` unity3 u = r `cross` fwd in setTransform (M.transform r u (-fwd) position) s diff --git a/Spear/Math/Triangle.hs b/Spear/Math/Triangle.hs index 3c30ea6..96cfa1a 100644 --- a/Spear/Math/Triangle.hs +++ b/Spear/Math/Triangle.hs @@ -5,7 +5,7 @@ module Spear.Math.Triangle where -import Spear.Math.Vector3 +import Spear.Math.Vector import Foreign.C.Types import Foreign.Storable diff --git a/Spear/Math/Utils.hs b/Spear/Math/Utils.hs index 1296f25..90ebda9 100644 --- a/Spear/Math/Utils.hs +++ b/Spear/Math/Utils.hs @@ -9,8 +9,7 @@ where import Spear.Math.Matrix4 as M4 -import Spear.Math.Vector2 as V2 -import qualified Spear.Math.Vector3 as V3 +import Spear.Math.Vector as V data Side = L | R deriving (Eq, Show) @@ -30,10 +29,10 @@ viewToWorld2d :: Vector2 -- ^ Point in view space -> Vector2 -- ^ Projection of the given point viewToWorld2d p viewI = let - p1' = V3.vec3 (V2.x p) (V2.y p) 0 + p1' = vec3 (x p) (y p) 0 p1 = viewI `mulp` p1' p2 = p1 - M4.forward viewI - lambda = (V3.y p1 / (V3.y p1 - V3.y p2)) - p' = p1 + V3.scale lambda (p2 - p1) + lambda = (y p1 / (y p1 - y p2)) + p' = p1 + V.scale lambda (p2 - p1) in - vec2 (V3.x p') (-V3.z p') + vec2 (x p') (-z p') diff --git a/Spear/Math/Vector.hs b/Spear/Math/Vector.hs new file mode 100644 index 0000000..a1cb9e8 --- /dev/null +++ b/Spear/Math/Vector.hs @@ -0,0 +1,13 @@ +module Spear.Math.Vector +( + module Spear.Math.Vector.Vector2 +, module Spear.Math.Vector.Vector3 +, module Spear.Math.Vector.Vector4 +, module Spear.Math.Vector.Class +) +where + +import Spear.Math.Vector.Vector2 +import Spear.Math.Vector.Vector3 +import Spear.Math.Vector.Vector4 +import Spear.Math.Vector.Class diff --git a/Spear/Math/Vector/Class.hs b/Spear/Math/Vector/Class.hs new file mode 100644 index 0000000..05a7206 --- /dev/null +++ b/Spear/Math/Vector/Class.hs @@ -0,0 +1,43 @@ +module Spear.Math.Vector.Class +where + +class (Fractional a, Ord a) => VectorClass a where + -- | Create a vector from the given list. + fromList :: [Float] -> a + + -- | Return the vector's x coordinate. + x :: a -> Float + x _ = 0 + + -- | Return the vector's y coordinate. + y :: a -> Float + y _ = 0 + + -- | Return the vector's z coordinate. + z :: a -> Float + z _ = 0 + + -- | Return the vector's w coordinate. + w :: a -> Float + w _ = 0 + + -- | Return the vector's ith coordinate. + (!) :: a -> Int -> Float + + -- | Compute the given vectors' dot product. + dot :: a -> a -> Float + + -- | Compute the given vector's squared norm. + normSq :: a -> Float + + -- | Compute the given vector's norm. + norm :: a -> Float + + -- | Multiply the given vector with the given scalar. + scale :: Float -> a -> a + + -- | Negate the given vector. + neg :: a -> a + + -- | Normalise the given vector. + normalise :: a -> a \ No newline at end of file diff --git a/Spear/Math/Vector/Vector2.hs b/Spear/Math/Vector/Vector2.hs new file mode 100644 index 0000000..7aaece5 --- /dev/null +++ b/Spear/Math/Vector/Vector2.hs @@ -0,0 +1,120 @@ +module Spear.Math.Vector.Vector2 +( + Vector2 + -- * Construction +, unitx2 +, unity2 +, zero2 +, vec2 + -- * Operations +, perp +) +where + + +import Spear.Math.Vector.Class + + +import Foreign.C.Types (CFloat) +import Foreign.Storable + + +-- | Represents a vector in 2D. +data Vector2 = Vector2 {-# UNPACK #-} !Float {-# UNPACK #-} !Float deriving (Eq, Show) + + +instance Num Vector2 where + Vector2 ax ay + Vector2 bx by = Vector2 (ax + bx) (ay + by) + Vector2 ax ay - Vector2 bx by = Vector2 (ax - bx) (ay - by) + Vector2 ax ay * Vector2 bx by = Vector2 (ax * bx) (ay * by) + abs (Vector2 ax ay) = Vector2 (abs ax) (abs ay) + signum (Vector2 ax ay) = Vector2 (signum ax) (signum ay) + fromInteger i = Vector2 i' i' where i' = fromInteger i + + +instance Fractional Vector2 where + Vector2 ax ay / Vector2 bx by = Vector2 (ax / bx) (ay / by) + fromRational r = Vector2 r' r' where r' = fromRational r + + +instance Ord Vector2 where + Vector2 ax ay <= Vector2 bx by = (ax <= bx) || (ax == bx && ay <= by) + Vector2 ax ay >= Vector2 bx by = (ax >= bx) || (ax == bx && ay >= by) + Vector2 ax ay < Vector2 bx by = (ax < bx) || (ax == bx && ay < by) + Vector2 ax ay > Vector2 bx by = (ax > bx) || (ax == bx && ay > by) + max (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.max ax bx) (Prelude.max ay by) + min (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.min ax bx) (Prelude.min ay by) + + +instance VectorClass Vector2 where + fromList (ax:ay:_) = Vector2 ax ay + + x (Vector2 ax _) = ax + + y (Vector2 _ ay) = ay + + (Vector2 ax _) ! 0 = ax + (Vector2 _ ay) ! 1 = ay + _ ! _ = 0 + + Vector2 ax ay `dot` Vector2 bx by = ax*bx + ay*by + + normSq (Vector2 ax ay) = ax*ax + ay*ay + + norm = sqrt . normSq + + scale s (Vector2 ax ay) = Vector2 (s*ax) (s*ay) + + neg (Vector2 ax ay) = Vector2 (-ax) (-ay) + + normalise v = + let n' = norm v + n = if n' == 0 then 1 else n' + in scale (1.0 / n) v + + +sizeFloat = sizeOf (undefined :: CFloat) + + +instance Storable Vector2 where + sizeOf _ = 2*sizeFloat + alignment _ = alignment (undefined :: CFloat) + + peek ptr = do + ax <- peekByteOff ptr 0 + ay <- peekByteOff ptr $ sizeFloat + return (Vector2 ax ay) + + poke ptr (Vector2 ax ay) = do + pokeByteOff ptr 0 ax + pokeByteOff ptr sizeFloat ay + + +-- | Get the vector's x coordinate. + + + +-- | Unit vector along the X axis. +unitx2 = Vector2 1 0 + + +-- | Unit vector along the Y axis. +unity2 = Vector2 0 1 + + +-- | Zero vector. +zero2 = Vector2 0 0 + + +-- | Create a vector from the given values. +vec2 :: Float -> Float -> Vector2 +vec2 ax ay = Vector2 ax ay + + +-- | Compute a vector perpendicular to the given one, satisfying: +-- +-- perp (Vector2 0 1) = Vector2 1 0 +-- +-- perp (Vector2 1 0) = Vector2 0 (-1) +perp :: Vector2 -> Vector2 +perp (Vector2 x y) = Vector2 y (-x) diff --git a/Spear/Math/Vector/Vector3.hs b/Spear/Math/Vector/Vector3.hs new file mode 100644 index 0000000..c19b7c7 --- /dev/null +++ b/Spear/Math/Vector/Vector3.hs @@ -0,0 +1,165 @@ +module Spear.Math.Vector.Vector3 +( + Vector3 + -- * Construction +, unitx3 +, unity3 +, unitz3 +, zero3 +, vec3 +, orbit + -- * Operations +, cross +) +where + + +import Spear.Math.Vector.Class + +import Foreign.C.Types (CFloat) +import Foreign.Storable + + +-- | Represents a vector in 3D. +data Vector3 = Vector3 + {-# UNPACK #-} !Float + {-# UNPACK #-} !Float + {-# UNPACK #-} !Float + deriving (Eq, Show) + + +instance Num Vector3 where + Vector3 ax ay az + Vector3 bx by bz = Vector3 (ax + bx) (ay + by) (az + bz) + Vector3 ax ay az - Vector3 bx by bz = Vector3 (ax - bx) (ay - by) (az - bz) + Vector3 ax ay az * Vector3 bx by bz = Vector3 (ax * bx) (ay * by) (az * bz) + abs (Vector3 ax ay az) = Vector3 (abs ax) (abs ay) (abs az) + signum (Vector3 ax ay az) = Vector3 (signum ax) (signum ay) (signum az) + fromInteger i = Vector3 i' i' i' where i' = fromInteger i + + +instance Fractional Vector3 where + Vector3 ax ay az / Vector3 bx by bz = Vector3 (ax / bx) (ay / by) (az / bz) + fromRational r = Vector3 r' r' r' where r' = fromRational r + + +instance Ord Vector3 where + Vector3 ax ay az <= Vector3 bx by bz + = (ax <= bx) + || (az == bx && ay <= by) + || (ax == bx && ay == by && az <= bz) + + Vector3 ax ay az >= Vector3 bx by bz + = (ax >= bx) + || (ax == bx && ay >= by) + || (ax == bx && ay == by && az >= bz) + + Vector3 ax ay az < Vector3 bx by bz + = (ax < bx) + || (az == bx && ay < by) + || (ax == bx && ay == by && az < bz) + + Vector3 ax ay az > Vector3 bx by bz + = (ax > bx) + || (ax == bx && ay > by) + || (ax == bx && ay == by && az > bz) + + max (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) + + min (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) + + +instance VectorClass Vector3 where + fromList (ax:ay:az:_) = Vector3 ax ay az + + x (Vector3 ax _ _ ) = ax + + y (Vector3 _ ay _ ) = ay + + z (Vector3 _ _ az) = az + + (Vector3 ax _ _) ! 0 = ax + (Vector3 _ ay _) ! 1 = ay + (Vector3 _ _ az) ! 2 = az + _ ! _ = 0 + + Vector3 ax ay az `dot` Vector3 bx by bz = ax*bx + ay*by + az*bz + + normSq (Vector3 ax ay az) = ax*ax + ay*ay + az*az + + norm = sqrt . normSq + + scale s (Vector3 ax ay az) = Vector3 (s*ax) (s*ay) (s*az) + + neg (Vector3 ax ay az) = Vector3 (-ax) (-ay) (-az) + + normalise v = + let n' = norm v + n = if n' == 0 then 1 else n' + in scale (1.0 / n) v + + +sizeFloat = sizeOf (undefined :: CFloat) + + +instance Storable Vector3 where + sizeOf _ = 3*sizeFloat + alignment _ = alignment (undefined :: CFloat) + + peek ptr = do + ax <- peekByteOff ptr 0 + ay <- peekByteOff ptr $ 1*sizeFloat + az <- peekByteOff ptr $ 2*sizeFloat + return (Vector3 ax ay az) + + poke ptr (Vector3 ax ay az) = do + pokeByteOff ptr 0 ax + pokeByteOff ptr (1*sizeFloat) ay + pokeByteOff ptr (2*sizeFloat) az + + +-- | Unit vector along the X axis. +unitx3 = Vector3 1 0 0 + + +-- | Unit vector along the Y axis. +unity3 = Vector3 0 1 0 + + +-- | Unit vector along the Z axis. +unitz3 = Vector3 0 0 1 + + +-- | Zero vector. +zero3 = Vector3 0 0 0 + + +-- | Create a 3D vector from the given values. +vec3 :: Float -> Float -> Float -> Vector3 +vec3 ax ay az = Vector3 ax ay az + + +-- | Create a 3D vector as a point on a sphere. +orbit :: Vector3 -- ^ Sphere center. + -> Float -- ^ Sphere radius + -> Float -- ^ Azimuth angle. + -> Float -- ^ Zenith angle. + -> Vector3 + +orbit center radius anglex angley = + let ax = anglex * pi / 180 + ay = angley * pi / 180 + sx = sin ax + sy = sin ay + cx = cos ax + cy = cos ay + px = x center + radius*cy*sx + py = y center + radius*sy + pz = z center + radius*cx*cy + in + vec3 px py pz + + +-- | Compute the given vectors' cross product. +cross :: Vector3 -> Vector3 -> Vector3 +(Vector3 ax ay az) `cross` (Vector3 bx by bz) = + Vector3 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) diff --git a/Spear/Math/Vector/Vector4.hs b/Spear/Math/Vector/Vector4.hs new file mode 100644 index 0000000..1f5494d --- /dev/null +++ b/Spear/Math/Vector/Vector4.hs @@ -0,0 +1,154 @@ +module Spear.Math.Vector.Vector4 +( + Vector4 + -- * Construction +, unitx4 +, unity4 +, unitz4 +, vec4 + -- * Operations +, cross' +) +where + + +import Spear.Math.Vector.Class + +import Foreign.C.Types (CFloat) +import Foreign.Storable + + +-- | Represents a vector in 3D. +data Vector4 = Vector4 + {-# UNPACK #-} !Float + {-# UNPACK #-} !Float + {-# UNPACK #-} !Float + {-# UNPACK #-} !Float + deriving (Eq, Show) + + +instance Num Vector4 where + Vector4 ax ay az aw + Vector4 bx by bz bw = Vector4 (ax + bx) (ay + by) (az + bz) (aw + bw) + Vector4 ax ay az aw - Vector4 bx by bz bw = Vector4 (ax - bx) (ay - by) (az - bz) (aw - bw) + Vector4 ax ay az aw * Vector4 bx by bz bw = Vector4 (ax * bx) (ay * by) (az * bz) (aw * bw) + abs (Vector4 ax ay az aw) = Vector4 (abs ax) (abs ay) (abs az) (abs aw) + signum (Vector4 ax ay az aw) = Vector4 (signum ax) (signum ay) (signum az) (signum aw) + fromInteger i = Vector4 i' i' i' i' where i' = fromInteger i + + +instance Fractional Vector4 where + Vector4 ax ay az aw / Vector4 bx by bz bw = Vector4 (ax / bx) (ay / by) (az / bz) (aw / bw) + fromRational r = Vector4 r' r' r' r' where r' = fromRational r + + +instance Ord Vector4 where + Vector4 ax ay az aw <= Vector4 bx by bz bw + = (ax <= bx) + || (az == bx && ay <= by) + || (ax == bx && ay == by && az <= bz) + || (ax == bx && ay == by && az == bz && aw <= bw) + + Vector4 ax ay az aw >= Vector4 bx by bz bw + = (ax >= bx) + || (ax == bx && ay >= by) + || (ax == bx && ay == by && az >= bz) + || (ax == bx && ay == by && az == bz && aw >= bw) + + Vector4 ax ay az aw < Vector4 bx by bz bw + = (ax < bx) + || (az == bx && ay < by) + || (ax == bx && ay == by && az < bz) + || (ax == bx && ay == by && az == bz && aw < bw) + + Vector4 ax ay az aw > Vector4 bx by bz bw + = (ax > bx) + || (ax == bx && ay > by) + || (ax == bx && ay == by && az > bz) + || (ax == bx && ay == by && az == bz && aw > bw) + + min (Vector4 ax ay az aw) (Vector4 bx by bz bw) = + Vector4 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) (Prelude.min aw bw) + + max (Vector4 ax ay az aw) (Vector4 bx by bz bw) = + Vector4 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) (Prelude.min aw bw) + + +instance VectorClass Vector4 where + fromList (ax:ay:az:aw:_) = Vector4 ax ay az aw + + x (Vector4 ax _ _ _ ) = ax + + y (Vector4 _ ay _ _ ) = ay + + z (Vector4 _ _ az _ ) = az + + w (Vector4 _ _ _ aw) = aw + + (Vector4 ax _ _ _) ! 0 = ax + (Vector4 _ ay _ _) ! 1 = ay + (Vector4 _ _ az _) ! 2 = az + (Vector4 _ _ _ aw) ! 3 = aw + _ ! _ = 0 + + Vector4 ax ay az aw `dot` Vector4 bx by bz bw = ax*bx + ay*by + az*bz + aw*bw + + normSq (Vector4 ax ay az aw) = ax*ax + ay*ay + az*az + aw*aw + + norm = sqrt . normSq + + scale s (Vector4 ax ay az aw) = Vector4 (s*ax) (s*ay) (s*az) (s*aw) + + neg (Vector4 ax ay az aw) = Vector4 (-ax) (-ay) (-az) (-aw) + + normalise v = + let n' = norm v + n = if n' == 0 then 1 else n' + in scale (1.0 / n) v + + +sizeFloat = sizeOf (undefined :: CFloat) + + +instance Storable Vector4 where + sizeOf _ = 4*sizeFloat + alignment _ = alignment (undefined :: CFloat) + + peek ptr = do + ax <- peekByteOff ptr 0 + ay <- peekByteOff ptr $ 1 * sizeFloat + az <- peekByteOff ptr $ 2 * sizeFloat + aw <- peekByteOff ptr $ 3 * sizeFloat + return (Vector4 ax ay az aw) + + poke ptr (Vector4 ax ay az aw) = do + pokeByteOff ptr 0 ax + pokeByteOff ptr (1 * sizeFloat) ay + pokeByteOff ptr (2 * sizeFloat) az + pokeByteOff ptr (3 * sizeFloat) aw + + +-- | Unit vector along the X axis. +unitx4 = Vector4 1 0 0 0 + + +-- | Unit vector along the Y axis. +unity4 = Vector4 0 1 0 0 + + +-- | Unit vector along the Z axis. +unitz4 = Vector4 0 0 1 0 + +-- | Unit vector along the W axis. +unitw4 = Vector4 0 0 0 1 + + +-- | Create a 4D vector from the given values. +vec4 :: Float -> Float -> Float -> Float -> Vector4 +vec4 ax ay az aw = Vector4 ax ay az aw + + +-- | Compute the given vectors' cross product. +-- The vectors are projected to 3D space. The resulting vector is the cross product of the vectors' projections with w=0. +cross' :: Vector4 -> Vector4 -> Vector4 +(Vector4 ax ay az _) `cross'` (Vector4 bx by bz _) = + Vector4 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) 0 diff --git a/Spear/Math/Vector2.hs b/Spear/Math/Vector2.hs deleted file mode 100644 index 581a64f..0000000 --- a/Spear/Math/Vector2.hs +++ /dev/null @@ -1,145 +0,0 @@ -module Spear.Math.Vector2 -( - Vector2 - -- * Accessors -, x -, y - -- * Construction -, unitx -, unity -, zero -, fromList -, vec2 - -- * Operations -, perp -, dot -, normSq -, norm -, scale -, neg -, normalise -) -where - - -import Foreign.C.Types (CFloat) -import Foreign.Storable - - --- | Represents a vector in 2D. -data Vector2 = Vector2 {-# UNPACK #-} !Float {-# UNPACK #-} !Float deriving (Eq, Show) - - -instance Num Vector2 where - Vector2 ax ay + Vector2 bx by = Vector2 (ax + bx) (ay + by) - Vector2 ax ay - Vector2 bx by = Vector2 (ax - bx) (ay - by) - Vector2 ax ay * Vector2 bx by = Vector2 (ax * bx) (ay * by) - abs (Vector2 ax ay) = Vector2 (abs ax) (abs ay) - signum (Vector2 ax ay) = Vector2 (signum ax) (signum ay) - fromInteger i = Vector2 i' i' where i' = fromInteger i - - -instance Fractional Vector2 where - Vector2 ax ay / Vector2 bx by = Vector2 (ax / bx) (ay / by) - fromRational r = Vector2 r' r' where r' = fromRational r - - -instance Ord Vector2 where - Vector2 ax ay <= Vector2 bx by = (ax <= bx) || (ax == bx && ay <= by) - Vector2 ax ay >= Vector2 bx by = (ax >= bx) || (ax == bx && ay >= by) - Vector2 ax ay < Vector2 bx by = (ax < bx) || (ax == bx && ay < by) - Vector2 ax ay > Vector2 bx by = (ax > bx) || (ax == bx && ay > by) - max (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.max ax bx) (Prelude.max ay by) - min (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.min ax bx) (Prelude.min ay by) - - -sizeFloat = sizeOf (undefined :: CFloat) - - -instance Storable Vector2 where - sizeOf _ = 2*sizeFloat - alignment _ = alignment (undefined :: CFloat) - - peek ptr = do - ax <- peekByteOff ptr 0 - ay <- peekByteOff ptr $ sizeFloat - return (Vector2 ax ay) - - poke ptr (Vector2 ax ay) = do - pokeByteOff ptr 0 ax - pokeByteOff ptr sizeFloat ay - - --- | Get the vector's x coordinate. -x (Vector2 ax _) = ax - - --- | Get the vector's y coordinate. -y (Vector2 _ ay) = ay - - --- | Unit vector along the X axis. -unitx :: Vector2 -unitx = Vector2 1 0 - - --- | Unit vector along the Y axis. -unity :: Vector2 -unity = Vector2 0 1 - - --- | Zero vector. -zero :: Vector2 -zero = Vector2 0 0 - - --- | Create a vector from the given list. -fromList :: [Float] -> Vector2 -fromList (ax:ay:_) = Vector2 ax ay - - --- | Create a vector from the given values. -vec2 :: Float -> Float -> Vector2 -vec2 ax ay = Vector2 ax ay - - --- | Compute a vector perpendicular to the given one, satisfying: --- --- perp (Vector2 0 1) = Vector2 1 0 --- --- perp (Vector2 1 0) = Vector2 0 (-1) -perp :: Vector2 -> Vector2 -perp (Vector2 x y) = Vector2 y (-x) - - --- | Compute the given vectors' dot product. -dot :: Vector2 -> Vector2 -> Float -Vector2 ax ay `dot` Vector2 bx by = ax*bx + ay*by - - --- | Compute the given vector's squared norm. -normSq :: Vector2 -> Float -normSq (Vector2 ax ay) = ax*ax + ay*ay - - --- | Compute the given vector's norm. -norm :: Vector2 -> Float -norm = sqrt . normSq - - --- | Multiply the given vector with the given scalar. -scale :: Float -> Vector2 -> Vector2 -scale s (Vector2 ax ay) = Vector2 (s*ax) (s*ay) - - --- | Negate the given vector. -neg :: Vector2 -> Vector2 -neg (Vector2 ax ay) = Vector2 (-ax) (-ay) - - --- | Normalise the given vector. -normalise :: Vector2 -> Vector2 -normalise v = - let n' = norm v - n = if n' == 0 then 1 else n' - in scale (1.0 / n) v diff --git a/Spear/Math/Vector3.hs b/Spear/Math/Vector3.hs deleted file mode 100644 index d280811..0000000 --- a/Spear/Math/Vector3.hs +++ /dev/null @@ -1,187 +0,0 @@ -module Spear.Math.Vector3 -( - Vector3 - -- * Accessors -, x -, y -, z - -- * Construction -, unitx -, unity -, unitz -, zero -, fromList -, vec3 -, orbit - -- * Operations -, dot -, cross -, normSq -, norm -, scale -, neg -, normalise -) -where - - -import Foreign.C.Types (CFloat) -import Foreign.Storable - - --- | Represents a vector in 3D. -data Vector3 = Vector3 - {-# UNPACK #-} !Float - {-# UNPACK #-} !Float - {-# UNPACK #-} !Float - deriving (Eq, Show) - - -instance Num Vector3 where - Vector3 ax ay az + Vector3 bx by bz = Vector3 (ax + bx) (ay + by) (az + bz) - Vector3 ax ay az - Vector3 bx by bz = Vector3 (ax - bx) (ay - by) (az - bz) - Vector3 ax ay az * Vector3 bx by bz = Vector3 (ax * bx) (ay * by) (az * bz) - abs (Vector3 ax ay az) = Vector3 (abs ax) (abs ay) (abs az) - signum (Vector3 ax ay az) = Vector3 (signum ax) (signum ay) (signum az) - fromInteger i = Vector3 i' i' i' where i' = fromInteger i - - -instance Fractional Vector3 where - Vector3 ax ay az / Vector3 bx by bz = Vector3 (ax / bx) (ay / by) (az / bz) - fromRational r = Vector3 r' r' r' where r' = fromRational r - - -instance Ord Vector3 where - Vector3 ax ay az <= Vector3 bx by bz - = (ax <= bx) - || (az == bx && ay <= by) - || (ax == bx && ay == by && az <= bz) - - Vector3 ax ay az >= Vector3 bx by bz - = (ax >= bx) - || (ax == bx && ay >= by) - || (ax == bx && ay == by && az >= bz) - - Vector3 ax ay az < Vector3 bx by bz - = (ax < bx) - || (az == bx && ay < by) - || (ax == bx && ay == by && az < bz) - - Vector3 ax ay az > Vector3 bx by bz - = (ax > bx) - || (ax == bx && ay > by) - || (ax == bx && ay == by && az > bz) - - max (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) - - min (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) - - -sizeFloat = sizeOf (undefined :: CFloat) - - -instance Storable Vector3 where - sizeOf _ = 3*sizeFloat - alignment _ = alignment (undefined :: CFloat) - - peek ptr = do - ax <- peekByteOff ptr 0 - ay <- peekByteOff ptr $ 1*sizeFloat - az <- peekByteOff ptr $ 2*sizeFloat - return (Vector3 ax ay az) - - poke ptr (Vector3 ax ay az) = do - pokeByteOff ptr 0 ax - pokeByteOff ptr (1*sizeFloat) ay - pokeByteOff ptr (2*sizeFloat) az - - -x (Vector3 ax _ _ ) = ax -y (Vector3 _ ay _ ) = ay -z (Vector3 _ _ az) = az - - --- | Unit vector along the X axis. -unitx :: Vector3 -unitx = Vector3 1 0 0 - - --- | Unit vector along the Y axis. -unity :: Vector3 -unity = Vector3 0 1 0 - - --- | Unit vector along the Z axis. -unitz :: Vector3 -unitz = Vector3 0 0 1 - - --- | Zero vector. -zero :: Vector3 -zero = Vector3 0 0 0 - - --- | Create a vector from the given list. -fromList :: [Float] -> Vector3 -fromList (ax:ay:az:_) = Vector3 ax ay az - - --- | Create a 3D vector from the given values. -vec3 :: Float -> Float -> Float -> Vector3 -vec3 ax ay az = Vector3 ax ay az - - --- | Create a 3D vector as a point on a sphere. -orbit :: Vector3 -- ^ Sphere center. - -> Float -- ^ Sphere radius - -> Float -- ^ Azimuth angle. - -> Float -- ^ Zenith angle. - -> Vector3 - -orbit center radius anglex angley = - let ax = anglex * pi / 180 - ay = angley * pi / 180 - sx = sin ax - sy = sin ay - cx = cos ax - cy = cos ay - px = x center + radius*cy*sx - py = y center + radius*sy - pz = z center + radius*cx*cy - in - vec3 px py pz - - --- | Compute the given vectors' dot product. -dot :: Vector3 -> Vector3 -> Float -Vector3 ax ay az `dot` Vector3 bx by bz = ax*bx + ay*by + az*bz - - --- | Compute the given vectors' cross product. -cross :: Vector3 -> Vector3 -> Vector3 -(Vector3 ax ay az) `cross` (Vector3 bx by bz) = - Vector3 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) - - --- | Compute the given vector's squared norm. -normSq (Vector3 ax ay az) = ax*ax + ay*ay + az*az - - --- | Compute the given vector's norm. -norm = sqrt . normSq - - --- | Multiply the given vector with the given scalar. -scale s (Vector3 ax ay az) = Vector3 (s*ax) (s*ay) (s*az) - - --- | Negate the given vector. -neg (Vector3 ax ay az) = Vector3 (-ax) (-ay) (-az) - - --- | Normalise the given vector. -normalise v = - let n' = norm v - n = if n' == 0 then 1 else n' - in scale (1.0 / n) v - diff --git a/Spear/Math/Vector4.hs b/Spear/Math/Vector4.hs deleted file mode 100644 index 554fb27..0000000 --- a/Spear/Math/Vector4.hs +++ /dev/null @@ -1,176 +0,0 @@ -module Spear.Math.Vector4 -( - Vector4 - -- * Accessors -, x -, y -, z -, w - -- * Construction -, unitX -, unitY -, unitZ -, fromList -, vec4 - -- * Operations -, dot -, normSq -, norm -, scale -, neg -, normalise -) -where - - -import Foreign.C.Types (CFloat) -import Foreign.Storable - - --- | Represents a vector in 3D. -data Vector4 = Vector4 - {-# UNPACK #-} !Float - {-# UNPACK #-} !Float - {-# UNPACK #-} !Float - {-# UNPACK #-} !Float - deriving (Eq, Show) - - -instance Num Vector4 where - Vector4 ax ay az aw + Vector4 bx by bz bw = Vector4 (ax + bx) (ay + by) (az + bz) (aw + bw) - Vector4 ax ay az aw - Vector4 bx by bz bw = Vector4 (ax - bx) (ay - by) (az - bz) (aw - bw) - Vector4 ax ay az aw * Vector4 bx by bz bw = Vector4 (ax * bx) (ay * by) (az * bz) (aw * bw) - abs (Vector4 ax ay az aw) = Vector4 (abs ax) (abs ay) (abs az) (abs aw) - signum (Vector4 ax ay az aw) = Vector4 (signum ax) (signum ay) (signum az) (signum aw) - fromInteger i = Vector4 i' i' i' i' where i' = fromInteger i - - -instance Fractional Vector4 where - Vector4 ax ay az aw / Vector4 bx by bz bw = Vector4 (ax / bx) (ay / by) (az / bz) (aw / bw) - fromRational r = Vector4 r' r' r' r' where r' = fromRational r - - -instance Ord Vector4 where - Vector4 ax ay az aw <= Vector4 bx by bz bw - = (ax <= bx) - || (az == bx && ay <= by) - || (ax == bx && ay == by && az <= bz) - || (ax == bx && ay == by && az == bz && aw <= bw) - - Vector4 ax ay az aw >= Vector4 bx by bz bw - = (ax >= bx) - || (ax == bx && ay >= by) - || (ax == bx && ay == by && az >= bz) - || (ax == bx && ay == by && az == bz && aw >= bw) - - Vector4 ax ay az aw < Vector4 bx by bz bw - = (ax < bx) - || (az == bx && ay < by) - || (ax == bx && ay == by && az < bz) - || (ax == bx && ay == by && az == bz && aw < bw) - - Vector4 ax ay az aw > Vector4 bx by bz bw - = (ax > bx) - || (ax == bx && ay > by) - || (ax == bx && ay == by && az > bz) - || (ax == bx && ay == by && az == bz && aw > bw) - - min (Vector4 ax ay az aw) (Vector4 bx by bz bw) = - Vector4 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) (Prelude.min aw bw) - - max (Vector4 ax ay az aw) (Vector4 bx by bz bw) = - Vector4 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) (Prelude.min aw bw) - - -sizeFloat = sizeOf (undefined :: CFloat) - - -instance Storable Vector4 where - sizeOf _ = 4*sizeFloat - alignment _ = alignment (undefined :: CFloat) - - peek ptr = do - ax <- peekByteOff ptr 0 - ay <- peekByteOff ptr $ 1 * sizeFloat - az <- peekByteOff ptr $ 2 * sizeFloat - aw <- peekByteOff ptr $ 3 * sizeFloat - return (Vector4 ax ay az aw) - - poke ptr (Vector4 ax ay az aw) = do - pokeByteOff ptr 0 ax - pokeByteOff ptr (1 * sizeFloat) ay - pokeByteOff ptr (2 * sizeFloat) az - pokeByteOff ptr (3 * sizeFloat) aw - - -x (Vector4 ax _ _ _ ) = ax -y (Vector4 _ ay _ _ ) = ay -z (Vector4 _ _ az _ ) = az -w (Vector4 _ _ _ aw) = aw - - --- | Unit vector along the X axis. -unitX :: Vector4 -unitX = Vector4 1 0 0 0 - - --- | Unit vector along the Y axis. -unitY :: Vector4 -unitY = Vector4 0 1 0 0 - - --- | Unit vector along the Z axis. -unitZ :: Vector4 -unitZ = Vector4 0 0 1 0 - - --- | Create a vector from the given list. -fromList :: [Float] -> Vector4 -fromList (ax:ay:az:aw:_) = Vector4 ax ay az aw - - --- | Create a 4D vector from the given values. -vec4 :: Float -> Float -> Float -> Float -> Vector4 -vec4 ax ay az aw = Vector4 ax ay az aw - - --- | Compute the given vectors' dot product. -dot :: Vector4 -> Vector4 -> Float -Vector4 ax ay az aw `dot` Vector4 bx by bz bw = ax*bx + ay*by + az*bz + aw*bw - - --- | Compute the given vectors' cross product. --- The vectors are projected to 3D space. The resulting vector is the cross product of the vectors' projections with w=0. -cross :: Vector4 -> Vector4 -> Vector4 -(Vector4 ax ay az _) `cross` (Vector4 bx by bz _) = - Vector4 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) 0 - - --- | Compute the given vector's squared norm. -normSq :: Vector4 -> Float -normSq (Vector4 ax ay az aw) = ax*ax + ay*ay + az*az + aw*aw - - --- | Compute the given vector's norm. -norm :: Vector4 -> Float -norm = sqrt . normSq - - --- | Multiply the given vector with the given scalar. -scale :: Float -> Vector4 -> Vector4 -scale s (Vector4 ax ay az aw) = Vector4 (s*ax) (s*ay) (s*az) (s*aw) - - --- | Negate the given vector. -neg :: Vector4 -> Vector4 -neg (Vector4 ax ay az aw) = Vector4 (-ax) (-ay) (-az) (-aw) - - --- | Normalise the given vector. -normalise :: Vector4 -> Vector4 -normalise v = - let n' = norm v - n = if n' == 0 then 1 else n' - in - scale (1.0 / n) v - diff --git a/Spear/Physics/Rigid.hs b/Spear/Physics/Rigid.hs index 9147553..99a9d5a 100644 --- a/Spear/Physics/Rigid.hs +++ b/Spear/Physics/Rigid.hs @@ -12,7 +12,7 @@ where import qualified Spear.Math.Matrix3 as M3 import Spear.Math.Spatial2 -import Spear.Math.Vector2 +import Spear.Math.Vector import Spear.Physics.Types import Data.List (foldl') @@ -31,13 +31,13 @@ instance Spatial2 RigidBody where move v body = body { position = v + position body } - moveFwd speed body = body { position = position body + scale speed unity } + moveFwd speed body = body { position = position body + scale speed unity2 } - moveBack speed body = body { position = position body + scale (-speed) unity } + moveBack speed body = body { position = position body + scale (-speed) unity2 } - strafeLeft speed body = body { position = position body + scale (-speed) unitx } + strafeLeft speed body = body { position = position body + scale (-speed) unitx2 } - strafeRight speed body = body { position = position body + scale speed unitx } + strafeRight speed body = body { position = position body + scale speed unitx2 } rotate angle = id @@ -45,13 +45,13 @@ instance Spatial2 RigidBody where pos = position - fwd _ = unity + fwd _ = unity2 - up _ = unity + up _ = unity2 - right _ = unitx + right _ = unitx2 - transform body = M3.transform unitx unity $ position body + transform body = M3.transform unitx2 unity2 $ position body setTransform transf body = body { position = M3.position transf } @@ -60,13 +60,13 @@ instance Spatial2 RigidBody where -- | Build a 'RigidBody'. rigidBody :: Mass -> Position -> RigidBody -rigidBody m x = RigidBody m x zero zero +rigidBody m x = RigidBody m x zero2 zero2 -- | Update the given 'RigidBody'. update :: [Force] -> Dt -> RigidBody -> RigidBody update forces dt body = - let netforce = foldl' (+) zero forces + let netforce = foldl' (+) zero2 forces m = mass body r1 = position body v1 = velocity body diff --git a/Spear/Physics/Types.hs b/Spear/Physics/Types.hs index de889ee..62e0c04 100644 --- a/Spear/Physics/Types.hs +++ b/Spear/Physics/Types.hs @@ -2,7 +2,7 @@ module Spear.Physics.Types where -import Spear.Math.Vector2 +import Spear.Math.Vector type Dt = Float diff --git a/Spear/Render/AnimatedModel.hs b/Spear/Render/AnimatedModel.hs index 76e9e7f..dfaadfd 100644 --- a/Spear/Render/AnimatedModel.hs +++ b/Spear/Render/AnimatedModel.hs @@ -34,8 +34,7 @@ import Spear.Collision import Spear.GLSL import Spear.Math.AABB import Spear.Math.Matrix4 (Matrix4) -import Spear.Math.Vector2 (vec2) -import Spear.Math.Vector3 (vec3, x, y, z, scale) +import Spear.Math.Vector import Spear.Render.Material import Spear.Render.Model import Spear.Render.Program diff --git a/Spear/Render/Material.hs b/Spear/Render/Material.hs index f504036..83d8742 100644 --- a/Spear/Render/Material.hs +++ b/Spear/Render/Material.hs @@ -4,7 +4,7 @@ module Spear.Render.Material where -import Spear.Math.Vector4 +import Spear.Math.Vector data Material = Material diff --git a/Spear/Render/StaticModel.hs b/Spear/Render/StaticModel.hs index c67405a..ed8d065 100644 --- a/Spear/Render/StaticModel.hs +++ b/Spear/Render/StaticModel.hs @@ -24,7 +24,7 @@ import Spear.Collision import Spear.GLSL import Spear.Math.AABB import Spear.Math.Matrix4 (Matrix4) -import Spear.Math.Vector2 (vec2) +import Spear.Math.Vector import Spear.Render.Material import Spear.Render.Model import Spear.Render.Program diff --git a/Spear/Scene/GameObject.hs b/Spear/Scene/GameObject.hs index d98299c..37f9260 100644 --- a/Spear/Scene/GameObject.hs +++ b/Spear/Scene/GameObject.hs @@ -40,8 +40,7 @@ import qualified Spear.Math.Matrix4 as M4 import Spear.Math.MatrixUtils import qualified Spear.Math.Spatial2 as S2 import Spear.Math.Utils -import Spear.Math.Vector2 as V2 -import Spear.Math.Vector3 as V3 +import Spear.Math.Vector import qualified Spear.Render.AnimatedModel as AM import Spear.Render.Program import Spear.Render.StaticModel as SM @@ -90,7 +89,7 @@ instance S2.Spatial2 GameObject where moveFwd s go = let m = transform go - v = V2.scale s $ M3.forward m + v = scale s $ M3.forward m in go { collisioners = fmap (Col.move v) $ collisioners go , transform = M3.translv v * m @@ -98,7 +97,7 @@ instance S2.Spatial2 GameObject where moveBack s go = let m = transform go - v = V2.scale (-s) $ M3.forward m + v = scale (-s) $ M3.forward m in go { collisioners = fmap (Col.move v) $ collisioners go , transform = M3.translv v * m @@ -106,7 +105,7 @@ instance S2.Spatial2 GameObject where strafeLeft s go = let m = transform go - v = V2.scale (-s) $ M3.right m + v = scale (-s) $ M3.right m in go { collisioners = fmap (Col.move v) $ collisioners go , transform = M3.translv v * m @@ -114,7 +113,7 @@ instance S2.Spatial2 GameObject where strafeRight s go = let m = transform go - v = V2.scale s $ M3.right m + v = scale s $ M3.right m in go { collisioners = fmap (Col.move v) $ collisioners go , transform = M3.translv v * m @@ -150,20 +149,20 @@ instance S2.Spatial2 GameObject where lookAt p go = let position = S2.pos go - fwd = V2.normalise $ p - position + fwd = normalise $ p - position r = perp fwd toDeg = (*(180/pi)) viewI = viewInv . window $ go p1 = viewToWorld2d position viewI p2 = viewToWorld2d (position + fwd) viewI - f = V2.normalise $ p2 - p1 + f = normalise $ p2 - p1 in go { transform = M3.transform r fwd position , angle = 180 - - if V2.x f > 0 - then toDeg . acos $ f `V2.dot` V2.unity - else (+180) . toDeg . acos $ f `V2.dot` (-V2.unity) + if x f > 0 + then toDeg . acos $ f `dot` unity2 + else (+180) . toDeg . acos $ f `dot` (-unity2) } diff --git a/Spear/Scene/Light.hs b/Spear/Scene/Light.hs index f482560..5f43b19 100644 --- a/Spear/Scene/Light.hs +++ b/Spear/Scene/Light.hs @@ -7,8 +7,7 @@ where import qualified Spear.Math.Matrix4 as M import qualified Spear.Math.Spatial3 as S -import Spear.Math.Vector3 -import qualified Spear.Math.Vector4 as V4 +import Spear.Math.Vector data Light diff --git a/Spear/Scene/Loader.hs b/Spear/Scene/Loader.hs index 3bc29fa..07d4f05 100644 --- a/Spear/Scene/Loader.hs +++ b/Spear/Scene/Loader.hs @@ -24,9 +24,7 @@ import qualified Spear.GLSL as GLSL import Spear.Math.Matrix3 as M3 import Spear.Math.Matrix4 as M4 import Spear.Math.MatrixUtils (fastNormalMatrix) -import Spear.Math.Vector2 as V2 -import Spear.Math.Vector3 as V3 -import Spear.Math.Vector4 as V4 +import Spear.Math.Vector import Spear.Render.AnimatedModel as AM import Spear.Render.Material import Spear.Render.Program @@ -204,27 +202,27 @@ loadModel' file rotation scale = do (case scale of Nothing -> Prelude.id Just s -> flip Model.transformVerts $ - \(Vec3 x' y' z') -> Vec3 (V3.x s * x') (V3.y s * y') (V3.z s * z')) + \(Vec3 x' y' z') -> Vec3 (x s * x') (y s * y') (z s * z')) (fmap transform $ Model.loadModel file) >>= setupIO . toGround rotateModel :: Rotation -> Model -> Model -rotateModel (Rotation x y z order) model = +rotateModel (Rotation ax ay az order) model = let mat = case order of - XYZ -> rotZ z * rotY y * rotX x - XZY -> rotY y * rotZ z * rotX x - YXZ -> rotZ z * rotX x * rotY y - YZX -> rotX x * rotZ z * rotY y - ZXY -> rotY y * rotX x * rotZ z - ZYX -> rotX x * rotY y * rotZ z + XYZ -> rotZ az * rotY ay * rotX ax + XZY -> rotY ay * rotZ az * rotX ax + YXZ -> rotZ az * rotX ax * rotY ay + YZX -> rotX ax * rotZ az * rotY ay + ZXY -> rotY ay * rotX ax * rotZ az + ZYX -> rotX ax * rotY ay * rotZ az normalMat = fastNormalMatrix mat vTransform (Vec3 x' y' z') = - let v = mat `M4.mulp` (vec3 x' y' z') in Vec3 (V3.x v) (V3.y v) (V3.z v) + let v = mat `M4.mulp` (vec3 x' y' z') in Vec3 (x v) (y v) (z v) nTransform (Vec3 x' y' z') = - let v = normalMat `M3.mul` (vec3 x' y' z') in Vec3 (V3.x v) (V3.y v) (V3.z v) + let v = normalMat `M3.mul` (vec3 x' y' z') in Vec3 (x v) (y v) (z v) in flip Model.transformVerts vTransform . flip Model.transformNormals nTransform $ model @@ -404,7 +402,7 @@ newObject' newGO sceneRes nid props = do vectors :: Maybe Vector2 -> (Vector2, Vector2) vectors up = case up of - Nothing -> (V2.unitx, V2.unity) + Nothing -> (unitx2, unity2) Just u -> (perp u, u) diff --git a/Spear/Scene/SceneResources.hs b/Spear/Scene/SceneResources.hs index ab96dc6..c2dabcf 100644 --- a/Spear/Scene/SceneResources.hs +++ b/Spear/Scene/SceneResources.hs @@ -20,7 +20,7 @@ where import Spear.Assets.Model as Model import Spear.GLSL as GLSL -import Spear.Math.Vector3 +import Spear.Math.Vector import Spear.Render.AnimatedModel import Spear.Render.Material import Spear.Render.Program -- cgit v1.2.3