diff options
| -rw-r--r-- | Spear/Math/AABB.hs | 4 | ||||
| -rw-r--r-- | Spear/Math/Circle.hs | 8 | ||||
| -rw-r--r-- | Spear/Math/Matrix3.hs | 480 | ||||
| -rw-r--r-- | Spear/Math/Matrix4.hs | 838 | ||||
| -rw-r--r-- | Spear/Math/Plane.hs | 2 | ||||
| -rw-r--r-- | Spear/Math/Vector2.hs | 278 | ||||
| -rw-r--r-- | Spear/Math/Vector3.hs | 40 | ||||
| -rw-r--r-- | Spear/Math/Vector4.hs | 349 |
8 files changed, 985 insertions, 1014 deletions
diff --git a/Spear/Math/AABB.hs b/Spear/Math/AABB.hs index 55e3083..cd945a6 100644 --- a/Spear/Math/AABB.hs +++ b/Spear/Math/AABB.hs | |||
| @@ -20,9 +20,9 @@ aabb :: [Vector2] -> AABB | |||
| 20 | aabb [] = error "Attempting to build a BoundingVolume from an empty list!" | 20 | aabb [] = error "Attempting to build a BoundingVolume from an empty list!" |
| 21 | 21 | ||
| 22 | aabb (x:xs) = foldr update (AABB x x) xs | 22 | aabb (x:xs) = foldr update (AABB x x) xs |
| 23 | where update p (AABB min max) = AABB (v2min p min) (v2max p max) | 23 | where update p (AABB pmin pmax) = AABB (min p pmin) (max p pmax) |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | -- | Return 'True' if the given 'AABB' contains the given point, 'False' otherwise. | 26 | -- | Return 'True' if the given 'AABB' contains the given point, 'False' otherwise. |
| 27 | aabbpt :: AABB -> Vector2 -> Bool | 27 | aabbpt :: AABB -> Vector2 -> Bool |
| 28 | aabbpt (AABB min max) v = v >= min && v <= max | 28 | aabbpt (AABB pmin pmax) v = v >= pmin && v <= pmax |
diff --git a/Spear/Math/Circle.hs b/Spear/Math/Circle.hs index a34de0b..daaafc5 100644 --- a/Spear/Math/Circle.hs +++ b/Spear/Math/Circle.hs | |||
| @@ -22,10 +22,10 @@ circle :: [Vector2] -> Circle | |||
| 22 | circle [] = error "Attempting to build a Circle from an empty list!" | 22 | circle [] = error "Attempting to build a Circle from an empty list!" |
| 23 | circle (x:xs) = Circle c r | 23 | circle (x:xs) = Circle c r |
| 24 | where | 24 | where |
| 25 | c = min + (max-min)/2 | 25 | c = pmin + (pmax-pmin)/2 |
| 26 | r = norm $ max - c | 26 | r = norm $ pmax - c |
| 27 | (min,max) = foldr update (x,x) xs | 27 | (pmin,pmax) = foldr update (x,x) xs |
| 28 | update p (min,max) = (v2min p min, v2max p max) | 28 | update p (pmin,pmax) = (min p pmin, max p pmax) |
| 29 | 29 | ||
| 30 | 30 | ||
| 31 | -- | Return 'True' if the given 'Sphere' contains the given point, 'False' otherwise. | 31 | -- | Return 'True' if the given 'Sphere' contains the given point, 'False' otherwise. |
diff --git a/Spear/Math/Matrix3.hs b/Spear/Math/Matrix3.hs index adc4449..d5e46e9 100644 --- a/Spear/Math/Matrix3.hs +++ b/Spear/Math/Matrix3.hs | |||
| @@ -1,162 +1,162 @@ | |||
| 1 | module Spear.Math.Matrix3 | 1 | module Spear.Math.Matrix3 |
| 2 | ( | 2 | ( |
| 3 | Matrix3 | 3 | Matrix3 |
| 4 | -- * Accessors | 4 | -- * Accessors |
| 5 | , m00, m01, m02 | 5 | , m00, m01, m02 |
| 6 | , m10, m11, m12 | 6 | , m10, m11, m12 |
| 7 | , m20, m21, m22 | 7 | , m20, m21, m22 |
| 8 | , col0, col1, col2 | 8 | , col0, col1, col2 |
| 9 | , row0, row1, row2 | 9 | , row0, row1, row2 |
| 10 | , right, up, forward, position | 10 | , right, up, forward, position |
| 11 | -- * Construction | 11 | -- * Construction |
| 12 | , mat3 | 12 | , mat3 |
| 13 | , mat3fromVec | 13 | , mat3fromVec |
| 14 | , transform | 14 | , transform |
| 15 | , translation | 15 | , translation |
| 16 | , rotation | 16 | , rotation |
| 17 | , Spear.Math.Matrix3.id | 17 | , Spear.Math.Matrix3.id |
| 18 | -- * Transformations | 18 | -- * Transformations |
| 19 | -- ** Translation | 19 | -- ** Translation |
| 20 | , transl | 20 | , transl |
| 21 | , translv | 21 | , translv |
| 22 | -- ** Rotation | 22 | -- ** Rotation |
| 23 | , rot | 23 | , rot |
| 24 | -- ** Scale | 24 | -- ** Scale |
| 25 | , Spear.Math.Matrix3.scale | 25 | , Spear.Math.Matrix3.scale |
| 26 | , scalev | 26 | , scalev |
| 27 | -- ** Reflection | 27 | -- ** Reflection |
| 28 | , reflectX | 28 | , reflectX |
| 29 | , reflectY | 29 | , reflectY |
| 30 | , reflectZ | 30 | , reflectZ |
| 31 | -- * Operations | 31 | -- * Operations |
| 32 | , transpose | 32 | , transpose |
| 33 | , mulp | 33 | , mulp |
| 34 | , muld | 34 | , muld |
| 35 | , mul | 35 | , mul |
| 36 | , inverseTransform | 36 | , inverseTransform |
| 37 | , Spear.Math.Matrix3.zipWith | 37 | , Spear.Math.Matrix3.zipWith |
| 38 | , Spear.Math.Matrix3.map | 38 | , Spear.Math.Matrix3.map |
| 39 | ) | 39 | ) |
| 40 | where | 40 | where |
| 41 | 41 | ||
| 42 | 42 | ||
| 43 | import Spear.Math.Vector2 as V2 | 43 | import Spear.Math.Vector2 as V2 |
| 44 | import Spear.Math.Vector3 as V3 | 44 | import Spear.Math.Vector3 as V3 |
| 45 | 45 | ||
| 46 | import Foreign.Storable | 46 | import Foreign.Storable |
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | -- | Represents a 3x3 column major matrix. | 49 | -- | Represents a 3x3 column major matrix. |
| 50 | data Matrix3 = Matrix3 | 50 | data Matrix3 = Matrix3 |
| 51 | { m00 :: {-# UNPACK #-} !Float, m10 :: {-# UNPACK #-} !Float, m20 :: {-# UNPACK #-} !Float | 51 | { m00 :: {-# UNPACK #-} !Float, m10 :: {-# UNPACK #-} !Float, m20 :: {-# UNPACK #-} !Float |
| 52 | , m01 :: {-# UNPACK #-} !Float, m11 :: {-# UNPACK #-} !Float, m21 :: {-# UNPACK #-} !Float | 52 | , m01 :: {-# UNPACK #-} !Float, m11 :: {-# UNPACK #-} !Float, m21 :: {-# UNPACK #-} !Float |
| 53 | , m02 :: {-# UNPACK #-} !Float, m12 :: {-# UNPACK #-} !Float, m22 :: {-# UNPACK #-} !Float | 53 | , m02 :: {-# UNPACK #-} !Float, m12 :: {-# UNPACK #-} !Float, m22 :: {-# UNPACK #-} !Float |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | 56 | ||
| 57 | instance Show Matrix3 where | 57 | instance Show Matrix3 where |
| 58 | 58 | ||
| 59 | show (Matrix3 m00 m10 m20 m01 m11 m21 m02 m12 m22) = | 59 | show (Matrix3 m00 m10 m20 m01 m11 m21 m02 m12 m22) = |
| 60 | show' m00 ++ ", " ++ show' m10 ++ ", " ++ show' m20 ++ "\n" ++ | 60 | show' m00 ++ ", " ++ show' m10 ++ ", " ++ show' m20 ++ "\n" ++ |
| 61 | show' m01 ++ ", " ++ show' m11 ++ ", " ++ show' m21 ++ "\n" ++ | 61 | show' m01 ++ ", " ++ show' m11 ++ ", " ++ show' m21 ++ "\n" ++ |
| 62 | show' m02 ++ ", " ++ show' m12 ++ ", " ++ show' m22 ++ "\n" | 62 | show' m02 ++ ", " ++ show' m12 ++ ", " ++ show' m22 ++ "\n" |
| 63 | where | 63 | where |
| 64 | show' f = if abs f < 0.0000001 then "0" else show f | 64 | show' f = if abs f < 0.0000001 then "0" else show f |
| 65 | 65 | ||
| 66 | 66 | ||
| 67 | instance Num Matrix3 where | 67 | instance Num Matrix3 where |
| 68 | (Matrix3 a00 a01 a02 a03 a04 a05 a06 a07 a08) | 68 | (Matrix3 a00 a01 a02 a03 a04 a05 a06 a07 a08) |
| 69 | + (Matrix3 b00 b01 b02 b03 b04 b05 b06 b07 b08) | 69 | + (Matrix3 b00 b01 b02 b03 b04 b05 b06 b07 b08) |
| 70 | = Matrix3 (a00 + b00) (a01 + b01) (a02 + b02) | 70 | = Matrix3 (a00 + b00) (a01 + b01) (a02 + b02) |
| 71 | (a03 + b03) (a04 + b04) (a05 + b05) | 71 | (a03 + b03) (a04 + b04) (a05 + b05) |
| 72 | (a06 + b06) (a07 + b07) (a08 + b08) | 72 | (a06 + b06) (a07 + b07) (a08 + b08) |
| 73 | 73 | ||
| 74 | (Matrix3 a00 a01 a02 a03 a04 a05 a06 a07 a08) | 74 | (Matrix3 a00 a01 a02 a03 a04 a05 a06 a07 a08) |
| 75 | - (Matrix3 b00 b01 b02 b03 b04 b05 b06 b07 b08) | 75 | - (Matrix3 b00 b01 b02 b03 b04 b05 b06 b07 b08) |
| 76 | = Matrix3 (a00 - b00) (a01 - b01) (a02 - b02) | 76 | = Matrix3 (a00 - b00) (a01 - b01) (a02 - b02) |
| 77 | (a03 - b03) (a04 - b04) (a05 - b05) | 77 | (a03 - b03) (a04 - b04) (a05 - b05) |
| 78 | (a06 - b06) (a07 - b07) (a08 - b08) | 78 | (a06 - b06) (a07 - b07) (a08 - b08) |
| 79 | 79 | ||
| 80 | (Matrix3 a00 a10 a20 a01 a11 a21 a02 a12 a22) | 80 | (Matrix3 a00 a10 a20 a01 a11 a21 a02 a12 a22) |
| 81 | * (Matrix3 b00 b10 b20 b01 b11 b21 b02 b12 b22) | 81 | * (Matrix3 b00 b10 b20 b01 b11 b21 b02 b12 b22) |
| 82 | = Matrix3 (a00 * b00 + a10 * b01 + a20 * b02) | 82 | = Matrix3 (a00 * b00 + a10 * b01 + a20 * b02) |
| 83 | (a00 * b10 + a10 * b11 + a20 * b12) | 83 | (a00 * b10 + a10 * b11 + a20 * b12) |
| 84 | (a00 * b20 + a10 * b21 + a20 * b22) | 84 | (a00 * b20 + a10 * b21 + a20 * b22) |
| 85 | 85 | ||
| 86 | (a01 * b00 + a11 * b01 + a21 * b02) | 86 | (a01 * b00 + a11 * b01 + a21 * b02) |
| 87 | (a01 * b10 + a11 * b11 + a21 * b12) | 87 | (a01 * b10 + a11 * b11 + a21 * b12) |
| 88 | (a01 * b20 + a11 * b21 + a21 * b22) | 88 | (a01 * b20 + a11 * b21 + a21 * b22) |
| 89 | 89 | ||
| 90 | (a02 * b00 + a12 * b01 + a22 * b02) | 90 | (a02 * b00 + a12 * b01 + a22 * b02) |
| 91 | (a02 * b10 + a12 * b11 + a22 * b12) | 91 | (a02 * b10 + a12 * b11 + a22 * b12) |
| 92 | (a02 * b20 + a12 * b21 + a22 * b22) | 92 | (a02 * b20 + a12 * b21 + a22 * b22) |
| 93 | 93 | ||
| 94 | abs = Spear.Math.Matrix3.map abs | 94 | abs = Spear.Math.Matrix3.map abs |
| 95 | 95 | ||
| 96 | signum = Spear.Math.Matrix3.map signum | 96 | signum = Spear.Math.Matrix3.map signum |
| 97 | 97 | ||
| 98 | fromInteger i = mat3 i' i' i' i' i' i' i' i' i' where i' = fromInteger i | 98 | fromInteger i = mat3 i' i' i' i' i' i' i' i' i' where i' = fromInteger i |
| 99 | 99 | ||
| 100 | 100 | ||
| 101 | instance Storable Matrix3 where | 101 | instance Storable Matrix3 where |
| 102 | sizeOf _ = 36 | 102 | sizeOf _ = 36 |
| 103 | alignment _ = 4 | 103 | alignment _ = 4 |
| 104 | 104 | ||
| 105 | peek ptr = do | 105 | peek ptr = do |
| 106 | a00 <- peekByteOff ptr 0; a01 <- peekByteOff ptr 4; a02 <- peekByteOff ptr 8; | 106 | a00 <- peekByteOff ptr 0; a01 <- peekByteOff ptr 4; a02 <- peekByteOff ptr 8; |
| 107 | a10 <- peekByteOff ptr 12; a11 <- peekByteOff ptr 16; a12 <- peekByteOff ptr 20; | 107 | a10 <- peekByteOff ptr 12; a11 <- peekByteOff ptr 16; a12 <- peekByteOff ptr 20; |
| 108 | a20 <- peekByteOff ptr 24; a21 <- peekByteOff ptr 28; a22 <- peekByteOff ptr 32; | 108 | a20 <- peekByteOff ptr 24; a21 <- peekByteOff ptr 28; a22 <- peekByteOff ptr 32; |
| 109 | 109 | ||
| 110 | return $ Matrix3 a00 a10 a20 | 110 | return $ Matrix3 a00 a10 a20 |
| 111 | a01 a11 a21 | 111 | a01 a11 a21 |
| 112 | a02 a12 a22 | 112 | a02 a12 a22 |
| 113 | 113 | ||
| 114 | poke ptr (Matrix3 a00 a01 a02 | 114 | poke ptr (Matrix3 a00 a01 a02 |
| 115 | a10 a11 a12 | 115 | a10 a11 a12 |
| 116 | a20 a21 a22) = do | 116 | a20 a21 a22) = do |
| 117 | pokeByteOff ptr 0 a00; pokeByteOff ptr 4 a01; pokeByteOff ptr 8 a02; | 117 | pokeByteOff ptr 0 a00; pokeByteOff ptr 4 a01; pokeByteOff ptr 8 a02; |
| 118 | pokeByteOff ptr 12 a10; pokeByteOff ptr 16 a11; pokeByteOff ptr 20 a12; | 118 | pokeByteOff ptr 12 a10; pokeByteOff ptr 16 a11; pokeByteOff ptr 20 a12; |
| 119 | pokeByteOff ptr 24 a20; pokeByteOff ptr 28 a21; pokeByteOff ptr 32 a22; | 119 | pokeByteOff ptr 24 a20; pokeByteOff ptr 28 a21; pokeByteOff ptr 32 a22; |
| 120 | 120 | ||
| 121 | 121 | ||
| 122 | col0 (Matrix3 a00 _ _ a01 _ _ a02 _ _ ) = vec3 a00 a01 a02 | 122 | col0 (Matrix3 a00 _ _ a01 _ _ a02 _ _ ) = vec3 a00 a01 a02 |
| 123 | col1 (Matrix3 _ a10 _ _ a11 _ _ a12 _ ) = vec3 a10 a11 a12 | 123 | col1 (Matrix3 _ a10 _ _ a11 _ _ a12 _ ) = vec3 a10 a11 a12 |
| 124 | col2 (Matrix3 _ _ a20 _ _ a21 _ _ a22) = vec3 a20 a21 a22 | 124 | col2 (Matrix3 _ _ a20 _ _ a21 _ _ a22) = vec3 a20 a21 a22 |
| 125 | 125 | ||
| 126 | 126 | ||
| 127 | row0 (Matrix3 a00 a10 a20 _ _ _ _ _ _ ) = vec3 a00 a10 a20 | 127 | row0 (Matrix3 a00 a10 a20 _ _ _ _ _ _ ) = vec3 a00 a10 a20 |
| 128 | row1 (Matrix3 _ _ _ a01 a11 a21 _ _ _ ) = vec3 a01 a11 a21 | 128 | row1 (Matrix3 _ _ _ a01 a11 a21 _ _ _ ) = vec3 a01 a11 a21 |
| 129 | row2 (Matrix3 _ _ _ _ _ _ a02 a12 a22) = vec3 a02 a12 a22 | 129 | row2 (Matrix3 _ _ _ _ _ _ a02 a12 a22) = vec3 a02 a12 a22 |
| 130 | 130 | ||
| 131 | 131 | ||
| 132 | right (Matrix3 a00 _ _ a01 _ _ _ _ _) = vec2 a00 a01 | 132 | right (Matrix3 a00 _ _ a01 _ _ _ _ _) = vec2 a00 a01 |
| 133 | up (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11 | 133 | up (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11 |
| 134 | forward (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11 | 134 | forward (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11 |
| 135 | position (Matrix3 _ _ a20 _ _ a21 _ _ _) = vec2 a20 a21 | 135 | position (Matrix3 _ _ a20 _ _ a21 _ _ _) = vec2 a20 a21 |
| 136 | 136 | ||
| 137 | 137 | ||
| 138 | -- | Build a matrix from the specified values. | 138 | -- | Build a matrix from the specified values. |
| 139 | mat3 = Matrix3 | 139 | mat3 = Matrix3 |
| 140 | 140 | ||
| 141 | 141 | ||
| 142 | -- | Build a matrix from three vectors in 3D. | 142 | -- | Build a matrix from three vectors in 3D. |
| 143 | mat3fromVec :: Vector3 -> Vector3 -> Vector3 -> Matrix3 | 143 | mat3fromVec :: Vector3 -> Vector3 -> Vector3 -> Matrix3 |
| 144 | mat3fromVec v0 v1 v2 = Matrix3 | 144 | mat3fromVec v0 v1 v2 = Matrix3 |
| 145 | (V3.x v0) (V3.x v1) (V3.x v2) | 145 | (V3.x v0) (V3.x v1) (V3.x v2) |
| 146 | (V3.y v0) (V3.y v1) (V3.y v2) | 146 | (V3.y v0) (V3.y v1) (V3.y v2) |
| 147 | (V3.z v0) (V3.z v1) (V3.z v2) | 147 | (V3.z v0) (V3.z v1) (V3.z v2) |
| 148 | 148 | ||
| 149 | 149 | ||
| 150 | -- | Build a transformation matrix. | 150 | -- | Build a transformation matrix. |
| 151 | transform :: Vector2 -- ^ Right vector | 151 | transform :: Vector2 -- ^ Right vector |
| 152 | -> Vector2 -- ^ Forward vector | 152 | -> Vector2 -- ^ Forward vector |
| 153 | -> Vector2 -- ^ Position | 153 | -> Vector2 -- ^ Position |
| 154 | -> Matrix3 -- ^ Transform | 154 | -> Matrix3 -- ^ Transform |
| 155 | 155 | ||
| 156 | transform r f p = mat3 | 156 | transform r f p = mat3 |
| 157 | (V2.x r) (V2.x f) (V2.x p) | 157 | (V2.x r) (V2.x f) (V2.x p) |
| 158 | (V2.y r) (V2.y f) (V2.y p) | 158 | (V2.y r) (V2.y f) (V2.y p) |
| 159 | 0 0 1 | 159 | 0 0 1 |
| 160 | 160 | ||
| 161 | 161 | ||
| 162 | -- | Get the translation part of the given transformation matrix. | 162 | -- | Get the translation part of the given transformation matrix. |
| @@ -181,14 +181,14 @@ rotation (Matrix3 | |||
| 181 | a00 a10 0 | 181 | a00 a10 0 |
| 182 | a01 a11 0 | 182 | a01 a11 0 |
| 183 | a02 a12 1 | 183 | a02 a12 1 |
| 184 | 184 | ||
| 185 | 185 | ||
| 186 | -- | Return the identity matrix. | 186 | -- | Return the identity matrix. |
| 187 | id :: Matrix3 | 187 | id :: Matrix3 |
| 188 | id = mat3 | 188 | id = mat3 |
| 189 | 1 0 0 | 189 | 1 0 0 |
| 190 | 0 1 0 | 190 | 0 1 0 |
| 191 | 0 0 1 | 191 | 0 0 1 |
| 192 | 192 | ||
| 193 | 193 | ||
| 194 | -- | Create a translation matrix. | 194 | -- | Create a translation matrix. |
| @@ -208,71 +208,71 @@ translv v = mat3 | |||
| 208 | 1 0 (V2.x v) | 208 | 1 0 (V2.x v) |
| 209 | 0 1 (V2.y v) | 209 | 0 1 (V2.y v) |
| 210 | 0 0 1 | 210 | 0 0 1 |
| 211 | 211 | ||
| 212 | 212 | ||
| 213 | -- | Create a rotation matrix rotating counter-clockwise about the Z axis. | 213 | -- | Create a rotation matrix rotating counter-clockwise about the Z axis. |
| 214 | -- | 214 | -- |
| 215 | -- The given angle must be in degrees. | 215 | -- The given angle must be in degrees. |
| 216 | rot :: Float -> Matrix3 | 216 | rot :: Float -> Matrix3 |
| 217 | rot angle = mat3 | 217 | rot angle = mat3 |
| 218 | c (-s) 0 | 218 | c (-s) 0 |
| 219 | s c 0 | 219 | s c 0 |
| 220 | 0 0 1 | 220 | 0 0 1 |
| 221 | where | 221 | where |
| 222 | s = sin . fromDeg $ angle | 222 | s = sin . fromDeg $ angle |
| 223 | c = cos . fromDeg $ angle | 223 | c = cos . fromDeg $ angle |
| 224 | 224 | ||
| 225 | 225 | ||
| 226 | -- | Create a scale matrix. | 226 | -- | Create a scale matrix. |
| 227 | scale :: Float -> Float -> Float -> Matrix3 | 227 | scale :: Float -> Float -> Float -> Matrix3 |
| 228 | scale sx sy sz = mat3 | 228 | scale sx sy sz = mat3 |
| 229 | sx 0 0 | 229 | sx 0 0 |
| 230 | 0 sy 0 | 230 | 0 sy 0 |
| 231 | 0 0 sz | 231 | 0 0 sz |
| 232 | 232 | ||
| 233 | 233 | ||
| 234 | -- | Create a scale matrix. | 234 | -- | Create a scale matrix. |
| 235 | scalev :: Vector3 -> Matrix3 | 235 | scalev :: Vector3 -> Matrix3 |
| 236 | scalev v = mat3 | 236 | scalev v = mat3 |
| 237 | sx 0 0 | 237 | sx 0 0 |
| 238 | 0 sy 0 | 238 | 0 sy 0 |
| 239 | 0 0 sz | 239 | 0 0 sz |
| 240 | where | 240 | where |
| 241 | sx = V3.x v | 241 | sx = V3.x v |
| 242 | sy = V3.y v | 242 | sy = V3.y v |
| 243 | sz = V3.z v | 243 | sz = V3.z v |
| 244 | 244 | ||
| 245 | 245 | ||
| 246 | -- | Create an X reflection matrix. | 246 | -- | Create an X reflection matrix. |
| 247 | reflectX :: Matrix3 | 247 | reflectX :: Matrix3 |
| 248 | reflectX = mat3 | 248 | reflectX = mat3 |
| 249 | (-1) 0 0 | 249 | (-1) 0 0 |
| 250 | 0 1 0 | 250 | 0 1 0 |
| 251 | 0 0 1 | 251 | 0 0 1 |
| 252 | 252 | ||
| 253 | 253 | ||
| 254 | -- | Create a Y reflection matrix. | 254 | -- | Create a Y reflection matrix. |
| 255 | reflectY :: Matrix3 | 255 | reflectY :: Matrix3 |
| 256 | reflectY = mat3 | 256 | reflectY = mat3 |
| 257 | 1 0 0 | 257 | 1 0 0 |
| 258 | 0 (-1) 0 | 258 | 0 (-1) 0 |
| 259 | 0 0 1 | 259 | 0 0 1 |
| 260 | 260 | ||
| 261 | 261 | ||
| 262 | -- | Create a Z reflection matrix. | 262 | -- | Create a Z reflection matrix. |
| 263 | reflectZ :: Matrix3 | 263 | reflectZ :: Matrix3 |
| 264 | reflectZ = mat3 | 264 | reflectZ = mat3 |
| 265 | 1 0 0 | 265 | 1 0 0 |
| 266 | 0 1 0 | 266 | 0 1 0 |
| 267 | 0 0 (-1) | 267 | 0 0 (-1) |
| 268 | 268 | ||
| 269 | 269 | ||
| 270 | -- | Transpose the specified matrix. | 270 | -- | Transpose the specified matrix. |
| 271 | transpose :: Matrix3 -> Matrix3 | 271 | transpose :: Matrix3 -> Matrix3 |
| 272 | transpose m = mat3 | 272 | transpose m = mat3 |
| 273 | (m00 m) (m01 m) (m02 m) | 273 | (m00 m) (m01 m) (m02 m) |
| 274 | (m10 m) (m11 m) (m12 m) | 274 | (m10 m) (m11 m) (m12 m) |
| 275 | (m20 m) (m21 m) (m22 m) | 275 | (m20 m) (m21 m) (m22 m) |
| 276 | 276 | ||
| 277 | 277 | ||
| 278 | -- | Transform the given point vector in 2D space with the given matrix. | 278 | -- | Transform the given point vector in 2D space with the given matrix. |
| @@ -292,36 +292,36 @@ muld m v = vec2 x' y' | |||
| 292 | v' = vec3 (V2.x v) (V2.y v) 0 | 292 | v' = vec3 (V2.x v) (V2.y v) 0 |
| 293 | x' = row0 m `V3.dot` v' | 293 | x' = row0 m `V3.dot` v' |
| 294 | y' = row1 m `V3.dot` v' | 294 | y' = row1 m `V3.dot` v' |
| 295 | 295 | ||
| 296 | 296 | ||
| 297 | -- | Transform the given vector in 3D space with the given matrix. | 297 | -- | Transform the given vector in 3D space with the given matrix. |
| 298 | mul :: Matrix3 -> Vector3 -> Vector3 | 298 | mul :: Matrix3 -> Vector3 -> Vector3 |
| 299 | mul m v = vec3 x' y' z' | 299 | mul m v = vec3 x' y' z' |
| 300 | where | 300 | where |
| 301 | v' = vec3 (V3.x v) (V3.y v) (V3.z v) | 301 | v' = vec3 (V3.x v) (V3.y v) (V3.z v) |
| 302 | x' = row0 m `V3.dot` v' | 302 | x' = row0 m `V3.dot` v' |
| 303 | y' = row1 m `V3.dot` v' | 303 | y' = row1 m `V3.dot` v' |
| 304 | z' = row2 m `V3.dot` v' | 304 | z' = row2 m `V3.dot` v' |
| 305 | 305 | ||
| 306 | 306 | ||
| 307 | -- | Zip two 'Matrix3' together with the specified function. | 307 | -- | Zip two 'Matrix3' together with the specified function. |
| 308 | zipWith :: (Float -> Float -> Float) -> Matrix3 -> Matrix3 -> Matrix3 | 308 | zipWith :: (Float -> Float -> Float) -> Matrix3 -> Matrix3 -> Matrix3 |
| 309 | zipWith f a b = Matrix3 | 309 | zipWith f a b = Matrix3 |
| 310 | (f (m00 a) (m00 b)) (f (m10 a) (m10 b)) (f (m20 a) (m20 b)) | 310 | (f (m00 a) (m00 b)) (f (m10 a) (m10 b)) (f (m20 a) (m20 b)) |
| 311 | (f (m01 a) (m01 b)) (f (m11 a) (m11 b)) (f (m21 a) (m21 b)) | 311 | (f (m01 a) (m01 b)) (f (m11 a) (m11 b)) (f (m21 a) (m21 b)) |
| 312 | (f (m02 a) (m02 b)) (f (m12 a) (m12 b)) (f (m22 a) (m22 b)) | 312 | (f (m02 a) (m02 b)) (f (m12 a) (m12 b)) (f (m22 a) (m22 b)) |
| 313 | 313 | ||
| 314 | 314 | ||
| 315 | -- | Map the specified function to the specified 'Matrix3'. | 315 | -- | Map the specified function to the specified 'Matrix3'. |
| 316 | map :: (Float -> Float) -> Matrix3 -> Matrix3 | 316 | map :: (Float -> Float) -> Matrix3 -> Matrix3 |
| 317 | map f m = Matrix3 | 317 | map f m = Matrix3 |
| 318 | (f . m00 $ m) (f . m10 $ m) (f . m20 $ m) | 318 | (f . m00 $ m) (f . m10 $ m) (f . m20 $ m) |
| 319 | (f . m01 $ m) (f . m11 $ m) (f . m21 $ m) | 319 | (f . m01 $ m) (f . m11 $ m) (f . m21 $ m) |
| 320 | (f . m02 $ m) (f . m12 $ m) (f . m22 $ m) | 320 | (f . m02 $ m) (f . m12 $ m) (f . m22 $ m) |
| 321 | 321 | ||
| 322 | 322 | ||
| 323 | -- | Compute the inverse transform of the given transformation matrix. | 323 | -- | Compute the inverse transform of the given transformation matrix. |
| 324 | inverseTransform :: Matrix3 -> Matrix3 | 324 | inverseTransform :: Matrix3 -> Matrix3 |
| 325 | inverseTransform mat = | 325 | inverseTransform mat = |
| 326 | let r = right mat | 326 | let r = right mat |
| 327 | f = forward mat | 327 | f = forward mat |
| @@ -330,8 +330,8 @@ inverseTransform mat = | |||
| 330 | (V2.x r) (V2.y r) (t `V2.dot` r) | 330 | (V2.x r) (V2.y r) (t `V2.dot` r) |
| 331 | (V2.x f) (V2.y f) (t `V2.dot` f) | 331 | (V2.x f) (V2.y f) (t `V2.dot` f) |
| 332 | 0 0 1 | 332 | 0 0 1 |
| 333 | 333 | ||
| 334 | 334 | ||
| 335 | fromDeg :: (Floating a) => a -> a | 335 | fromDeg :: (Floating a) => a -> a |
| 336 | fromDeg = (*pi) . (/180) | 336 | fromDeg = (*pi) . (/180) |
| 337 | 337 | ||
diff --git a/Spear/Math/Matrix4.hs b/Spear/Math/Matrix4.hs index a4ad651..41bfadd 100644 --- a/Spear/Math/Matrix4.hs +++ b/Spear/Math/Matrix4.hs | |||
| @@ -1,194 +1,194 @@ | |||
| 1 | module Spear.Math.Matrix4 | 1 | module Spear.Math.Matrix4 |
| 2 | ( | 2 | ( |
| 3 | Matrix4 | 3 | Matrix4 |
| 4 | -- * Accessors | 4 | -- * Accessors |
| 5 | , m00, m01, m02, m03 | 5 | , m00, m01, m02, m03 |
| 6 | , m10, m11, m12, m13 | 6 | , m10, m11, m12, m13 |
| 7 | , m20, m21, m22, m23 | 7 | , m20, m21, m22, m23 |
| 8 | , m30, m31, m32, m33 | 8 | , m30, m31, m32, m33 |
| 9 | , col0, col1, col2, col3 | 9 | , col0, col1, col2, col3 |
| 10 | , row0, row1, row2, row3 | 10 | , row0, row1, row2, row3 |
| 11 | , right, up, forward, position | 11 | , right, up, forward, position |
| 12 | -- * Construction | 12 | -- * Construction |
| 13 | , mat4 | 13 | , mat4 |
| 14 | , mat4fromVec | 14 | , mat4fromVec |
| 15 | , transform | 15 | , transform |
| 16 | , translation | 16 | , translation |
| 17 | , rotation | 17 | , rotation |
| 18 | , lookAt | 18 | , lookAt |
| 19 | , Spear.Math.Matrix4.id | 19 | , Spear.Math.Matrix4.id |
| 20 | -- * Transformations | 20 | -- * Transformations |
| 21 | -- ** Translation | 21 | -- ** Translation |
| 22 | , transl | 22 | , transl |
| 23 | , translv | 23 | , translv |
| 24 | -- ** Rotation | 24 | -- ** Rotation |
| 25 | , rotX | 25 | , rotX |
| 26 | , rotY | 26 | , rotY |
| 27 | , rotZ | 27 | , rotZ |
| 28 | , axisAngle | 28 | , axisAngle |
| 29 | -- ** Scale | 29 | -- ** Scale |
| 30 | , Spear.Math.Matrix4.scale | 30 | , Spear.Math.Matrix4.scale |
| 31 | , scalev | 31 | , scalev |
| 32 | -- ** Reflection | 32 | -- ** Reflection |
| 33 | , reflectX | 33 | , reflectX |
| 34 | , reflectY | 34 | , reflectY |
| 35 | , reflectZ | 35 | , reflectZ |
| 36 | -- ** Projection | 36 | -- ** Projection |
| 37 | , ortho | 37 | , ortho |
| 38 | , perspective | 38 | , perspective |
| 39 | , planeProj | 39 | , planeProj |
| 40 | -- * Operations | 40 | -- * Operations |
| 41 | , Spear.Math.Matrix4.zipWith | 41 | , Spear.Math.Matrix4.zipWith |
| 42 | , Spear.Math.Matrix4.map | 42 | , Spear.Math.Matrix4.map |
| 43 | , transpose | 43 | , transpose |
| 44 | , inverseTransform | 44 | , inverseTransform |
| 45 | , inverse | 45 | , inverse |
| 46 | , mul | 46 | , mul |
| 47 | , mulp | 47 | , mulp |
| 48 | , muld | 48 | , muld |
| 49 | , mul' | 49 | , mul' |
| 50 | ) | 50 | ) |
| 51 | where | 51 | where |
| 52 | 52 | ||
| 53 | 53 | ||
| 54 | import Spear.Math.Vector3 as V3 | 54 | import Spear.Math.Vector3 as V3 |
| 55 | import Spear.Math.Vector4 as V4 | 55 | import Spear.Math.Vector4 as V4 |
| 56 | 56 | ||
| 57 | import Foreign.Storable | 57 | import Foreign.Storable |
| 58 | 58 | ||
| 59 | 59 | ||
| 60 | -- | Represents a 4x4 column major matrix. | 60 | -- | Represents a 4x4 column major matrix. |
| 61 | data Matrix4 = Matrix4 | 61 | data Matrix4 = Matrix4 |
| 62 | { m00 :: {-# UNPACK #-} !Float, m10 :: {-# UNPACK #-} !Float, m20 :: {-# UNPACK #-} !Float, m30 :: {-# UNPACK #-} !Float | 62 | { m00 :: {-# UNPACK #-} !Float, m10 :: {-# UNPACK #-} !Float, m20 :: {-# UNPACK #-} !Float, m30 :: {-# UNPACK #-} !Float |
| 63 | , m01 :: {-# UNPACK #-} !Float, m11 :: {-# UNPACK #-} !Float, m21 :: {-# UNPACK #-} !Float, m31 :: {-# UNPACK #-} !Float | 63 | , m01 :: {-# UNPACK #-} !Float, m11 :: {-# UNPACK #-} !Float, m21 :: {-# UNPACK #-} !Float, m31 :: {-# UNPACK #-} !Float |
| 64 | , m02 :: {-# UNPACK #-} !Float, m12 :: {-# UNPACK #-} !Float, m22 :: {-# UNPACK #-} !Float, m32 :: {-# UNPACK #-} !Float | 64 | , m02 :: {-# UNPACK #-} !Float, m12 :: {-# UNPACK #-} !Float, m22 :: {-# UNPACK #-} !Float, m32 :: {-# UNPACK #-} !Float |
| 65 | , m03 :: {-# UNPACK #-} !Float, m13 :: {-# UNPACK #-} !Float, m23 :: {-# UNPACK #-} !Float, m33 :: {-# UNPACK #-} !Float | 65 | , m03 :: {-# UNPACK #-} !Float, m13 :: {-# UNPACK #-} !Float, m23 :: {-# UNPACK #-} !Float, m33 :: {-# UNPACK #-} !Float |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | 68 | ||
| 69 | instance Show Matrix4 where | 69 | instance Show Matrix4 where |
| 70 | 70 | ||
| 71 | show (Matrix4 m00 m10 m20 m30 m01 m11 m21 m31 m02 m12 m22 m32 m03 m13 m23 m33) = | 71 | show (Matrix4 m00 m10 m20 m30 m01 m11 m21 m31 m02 m12 m22 m32 m03 m13 m23 m33) = |
| 72 | show' m00 ++ ", " ++ show' m10 ++ ", " ++ show' m20 ++ ", " ++ show' m30 ++ "\n" ++ | 72 | show' m00 ++ ", " ++ show' m10 ++ ", " ++ show' m20 ++ ", " ++ show' m30 ++ "\n" ++ |
| 73 | show' m01 ++ ", " ++ show' m11 ++ ", " ++ show' m21 ++ ", " ++ show' m31 ++ "\n" ++ | 73 | show' m01 ++ ", " ++ show' m11 ++ ", " ++ show' m21 ++ ", " ++ show' m31 ++ "\n" ++ |
| 74 | show' m02 ++ ", " ++ show' m12 ++ ", " ++ show' m22 ++ ", " ++ show' m32 ++ "\n" ++ | 74 | show' m02 ++ ", " ++ show' m12 ++ ", " ++ show' m22 ++ ", " ++ show' m32 ++ "\n" ++ |
| 75 | show' m03 ++ ", " ++ show' m13 ++ ", " ++ show' m23 ++ ", " ++ show' m33 ++ "\n" | 75 | show' m03 ++ ", " ++ show' m13 ++ ", " ++ show' m23 ++ ", " ++ show' m33 ++ "\n" |
| 76 | where | 76 | where |
| 77 | show' f = if abs f < 0.0000001 then "0" else show f | 77 | show' f = if abs f < 0.0000001 then "0" else show f |
| 78 | 78 | ||
| 79 | 79 | ||
| 80 | instance Num Matrix4 where | 80 | instance Num Matrix4 where |
| 81 | (Matrix4 a00 a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15) | 81 | (Matrix4 a00 a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15) |
| 82 | + (Matrix4 b00 b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15) | 82 | + (Matrix4 b00 b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15) |
| 83 | = Matrix4 (a00 + b00) (a01 + b01) (a02 + b02) (a03 + b03) | 83 | = Matrix4 (a00 + b00) (a01 + b01) (a02 + b02) (a03 + b03) |
| 84 | (a04 + b04) (a05 + b05) (a06 + b06) (a07 + b07) | 84 | (a04 + b04) (a05 + b05) (a06 + b06) (a07 + b07) |
| 85 | (a08 + b08) (a09 + b09) (a10 + b10) (a11 + b11) | 85 | (a08 + b08) (a09 + b09) (a10 + b10) (a11 + b11) |
| 86 | (a12 + b12) (a13 + b13) (a14 + b14) (a15 + b15) | 86 | (a12 + b12) (a13 + b13) (a14 + b14) (a15 + b15) |
| 87 | 87 | ||
| 88 | (Matrix4 a00 a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15) | 88 | (Matrix4 a00 a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15) |
| 89 | - (Matrix4 b00 b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15) | 89 | - (Matrix4 b00 b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15) |
| 90 | = Matrix4 (a00 - b00) (a01 - b01) (a02 - b02) (a03 - b03) | 90 | = Matrix4 (a00 - b00) (a01 - b01) (a02 - b02) (a03 - b03) |
| 91 | (a04 - b04) (a05 - b05) (a06 - b06) (a07 - b07) | 91 | (a04 - b04) (a05 - b05) (a06 - b06) (a07 - b07) |
| 92 | (a08 - b08) (a09 - b09) (a10 - b10) (a11 - b11) | 92 | (a08 - b08) (a09 - b09) (a10 - b10) (a11 - b11) |
| 93 | (a12 - b12) (a13 - b13) (a14 - b14) (a15 - b15) | 93 | (a12 - b12) (a13 - b13) (a14 - b14) (a15 - b15) |
| 94 | 94 | ||
| 95 | (Matrix4 a00 a10 a20 a30 a01 a11 a21 a31 a02 a12 a22 a32 a03 a13 a23 a33) | 95 | (Matrix4 a00 a10 a20 a30 a01 a11 a21 a31 a02 a12 a22 a32 a03 a13 a23 a33) |
| 96 | * (Matrix4 b00 b10 b20 b30 b01 b11 b21 b31 b02 b12 b22 b32 b03 b13 b23 b33) | 96 | * (Matrix4 b00 b10 b20 b30 b01 b11 b21 b31 b02 b12 b22 b32 b03 b13 b23 b33) |
| 97 | = Matrix4 (a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03) | 97 | = Matrix4 (a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03) |
| 98 | (a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13) | 98 | (a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13) |
| 99 | (a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23) | 99 | (a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23) |
| 100 | (a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33) | 100 | (a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33) |
| 101 | 101 | ||
| 102 | (a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03) | 102 | (a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03) |
| 103 | (a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13) | 103 | (a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13) |
| 104 | (a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23) | 104 | (a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23) |
| 105 | (a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33) | 105 | (a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33) |
| 106 | 106 | ||
| 107 | (a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03) | 107 | (a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03) |
| 108 | (a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13) | 108 | (a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13) |
| 109 | (a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23) | 109 | (a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23) |
| 110 | (a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33) | 110 | (a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33) |
| 111 | 111 | ||
| 112 | (a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03) | 112 | (a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03) |
| 113 | (a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13) | 113 | (a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13) |
| 114 | (a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23) | 114 | (a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23) |
| 115 | (a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33) | 115 | (a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33) |
| 116 | 116 | ||
| 117 | abs = Spear.Math.Matrix4.map abs | 117 | abs = Spear.Math.Matrix4.map abs |
| 118 | 118 | ||
| 119 | signum = Spear.Math.Matrix4.map signum | 119 | signum = Spear.Math.Matrix4.map signum |
| 120 | 120 | ||
| 121 | fromInteger i = mat4 i' i' i' i' i' i' i' i' i' i' i' i' i' i' i' i' where i' = fromInteger i | 121 | fromInteger i = mat4 i' i' i' i' i' i' i' i' i' i' i' i' i' i' i' i' where i' = fromInteger i |
| 122 | 122 | ||
| 123 | 123 | ||
| 124 | instance Storable Matrix4 where | 124 | instance Storable Matrix4 where |
| 125 | sizeOf _ = 64 | 125 | sizeOf _ = 64 |
| 126 | alignment _ = 4 | 126 | alignment _ = 4 |
| 127 | 127 | ||
| 128 | peek ptr = do | 128 | peek ptr = do |
| 129 | a00 <- peekByteOff ptr 0; a01 <- peekByteOff ptr 4; a02 <- peekByteOff ptr 8; a03 <- peekByteOff ptr 12; | 129 | a00 <- peekByteOff ptr 0; a01 <- peekByteOff ptr 4; a02 <- peekByteOff ptr 8; a03 <- peekByteOff ptr 12; |
| 130 | a10 <- peekByteOff ptr 16; a11 <- peekByteOff ptr 20; a12 <- peekByteOff ptr 24; a13 <- peekByteOff ptr 28; | 130 | a10 <- peekByteOff ptr 16; a11 <- peekByteOff ptr 20; a12 <- peekByteOff ptr 24; a13 <- peekByteOff ptr 28; |
| 131 | a20 <- peekByteOff ptr 32; a21 <- peekByteOff ptr 36; a22 <- peekByteOff ptr 40; a23 <- peekByteOff ptr 44; | 131 | a20 <- peekByteOff ptr 32; a21 <- peekByteOff ptr 36; a22 <- peekByteOff ptr 40; a23 <- peekByteOff ptr 44; |
| 132 | a30 <- peekByteOff ptr 48; a31 <- peekByteOff ptr 52; a32 <- peekByteOff ptr 56; a33 <- peekByteOff ptr 60; | 132 | a30 <- peekByteOff ptr 48; a31 <- peekByteOff ptr 52; a32 <- peekByteOff ptr 56; a33 <- peekByteOff ptr 60; |
| 133 | 133 | ||
| 134 | return $ Matrix4 a00 a10 a20 a30 | 134 | return $ Matrix4 a00 a10 a20 a30 |
| 135 | a01 a11 a21 a31 | 135 | a01 a11 a21 a31 |
| 136 | a02 a12 a22 a32 | 136 | a02 a12 a22 a32 |
| 137 | a03 a13 a23 a33 | 137 | a03 a13 a23 a33 |
| 138 | 138 | ||
| 139 | poke ptr (Matrix4 a00 a10 a20 a30 | 139 | poke ptr (Matrix4 a00 a10 a20 a30 |
| 140 | a01 a11 a21 a31 | 140 | a01 a11 a21 a31 |
| 141 | a02 a12 a22 a32 | 141 | a02 a12 a22 a32 |
| 142 | a03 a13 a23 a33) = do | 142 | a03 a13 a23 a33) = do |
| 143 | pokeByteOff ptr 0 a00; pokeByteOff ptr 4 a01; pokeByteOff ptr 8 a02; pokeByteOff ptr 12 a03; | 143 | pokeByteOff ptr 0 a00; pokeByteOff ptr 4 a01; pokeByteOff ptr 8 a02; pokeByteOff ptr 12 a03; |
| 144 | pokeByteOff ptr 16 a10; pokeByteOff ptr 20 a11; pokeByteOff ptr 24 a12; pokeByteOff ptr 28 a13; | 144 | pokeByteOff ptr 16 a10; pokeByteOff ptr 20 a11; pokeByteOff ptr 24 a12; pokeByteOff ptr 28 a13; |
| 145 | pokeByteOff ptr 32 a20; pokeByteOff ptr 36 a21; pokeByteOff ptr 40 a22; pokeByteOff ptr 44 a23; | 145 | pokeByteOff ptr 32 a20; pokeByteOff ptr 36 a21; pokeByteOff ptr 40 a22; pokeByteOff ptr 44 a23; |
| 146 | pokeByteOff ptr 48 a30; pokeByteOff ptr 52 a31; pokeByteOff ptr 56 a32; pokeByteOff ptr 60 a33; | 146 | pokeByteOff ptr 48 a30; pokeByteOff ptr 52 a31; pokeByteOff ptr 56 a32; pokeByteOff ptr 60 a33; |
| 147 | 147 | ||
| 148 | 148 | ||
| 149 | col0 (Matrix4 a00 _ _ _ a01 _ _ _ a02 _ _ _ a03 _ _ _ ) = vec4 a00 a01 a02 a03 | 149 | col0 (Matrix4 a00 _ _ _ a01 _ _ _ a02 _ _ _ a03 _ _ _ ) = vec4 a00 a01 a02 a03 |
| 150 | col1 (Matrix4 _ a10 _ _ _ a11 _ _ _ a12 _ _ _ a13 _ _ ) = vec4 a10 a11 a12 a13 | 150 | col1 (Matrix4 _ a10 _ _ _ a11 _ _ _ a12 _ _ _ a13 _ _ ) = vec4 a10 a11 a12 a13 |
| 151 | col2 (Matrix4 _ _ a20 _ _ _ a21 _ _ _ a22 _ _ _ a23 _ ) = vec4 a20 a21 a22 a23 | 151 | col2 (Matrix4 _ _ a20 _ _ _ a21 _ _ _ a22 _ _ _ a23 _ ) = vec4 a20 a21 a22 a23 |
| 152 | col3 (Matrix4 _ _ _ a30 _ _ _ a31 _ _ _ a32 _ _ _ a33) = vec4 a30 a31 a32 a33 | 152 | col3 (Matrix4 _ _ _ a30 _ _ _ a31 _ _ _ a32 _ _ _ a33) = vec4 a30 a31 a32 a33 |
| 153 | 153 | ||
| 154 | 154 | ||
| 155 | row0 (Matrix4 a00 a01 a02 a03 _ _ _ _ _ _ _ _ _ _ _ _ ) = vec4 a00 a01 a02 a03 | 155 | row0 (Matrix4 a00 a01 a02 a03 _ _ _ _ _ _ _ _ _ _ _ _ ) = vec4 a00 a01 a02 a03 |
| 156 | row1 (Matrix4 _ _ _ _ a10 a11 a12 a13 _ _ _ _ _ _ _ _ ) = vec4 a10 a11 a12 a13 | 156 | row1 (Matrix4 _ _ _ _ a10 a11 a12 a13 _ _ _ _ _ _ _ _ ) = vec4 a10 a11 a12 a13 |
| 157 | row2 (Matrix4 _ _ _ _ _ _ _ _ a20 a21 a22 a23 _ _ _ _ ) = vec4 a20 a21 a22 a23 | 157 | row2 (Matrix4 _ _ _ _ _ _ _ _ a20 a21 a22 a23 _ _ _ _ ) = vec4 a20 a21 a22 a23 |
| 158 | row3 (Matrix4 _ _ _ _ _ _ _ _ _ _ _ _ a30 a31 a32 a33) = vec4 a30 a31 a32 a33 | 158 | row3 (Matrix4 _ _ _ _ _ _ _ _ _ _ _ _ a30 a31 a32 a33) = vec4 a30 a31 a32 a33 |
| 159 | 159 | ||
| 160 | 160 | ||
| 161 | right (Matrix4 a00 _ _ _ a01 _ _ _ a02 _ _ _ _ _ _ _) = vec3 a00 a01 a02 | 161 | right (Matrix4 a00 _ _ _ a01 _ _ _ a02 _ _ _ _ _ _ _) = vec3 a00 a01 a02 |
| 162 | up (Matrix4 _ a10 _ _ _ a11 _ _ _ a12 _ _ _ _ _ _) = vec3 a10 a11 a12 | 162 | up (Matrix4 _ a10 _ _ _ a11 _ _ _ a12 _ _ _ _ _ _) = vec3 a10 a11 a12 |
| 163 | forward (Matrix4 _ _ a20 _ _ _ a21 _ _ _ a22 _ _ _ _ _) = vec3 a20 a21 a22 | 163 | forward (Matrix4 _ _ a20 _ _ _ a21 _ _ _ a22 _ _ _ _ _) = vec3 a20 a21 a22 |
| 164 | position (Matrix4 _ _ _ a30 _ _ _ a31 _ _ _ a32 _ _ _ _) = vec3 a30 a31 a32 | 164 | position (Matrix4 _ _ _ a30 _ _ _ a31 _ _ _ a32 _ _ _ _) = vec3 a30 a31 a32 |
| 165 | 165 | ||
| 166 | 166 | ||
| 167 | -- | Build a matrix from the specified values. | 167 | -- | Build a matrix from the specified values. |
| 168 | mat4 = Matrix4 | 168 | mat4 = Matrix4 |
| 169 | 169 | ||
| 170 | 170 | ||
| 171 | -- | Build a matrix from four vectors in 4D. | 171 | -- | Build a matrix from four vectors in 4D. |
| 172 | mat4fromVec :: Vector4 -> Vector4 -> Vector4 -> Vector4 -> Matrix4 | 172 | mat4fromVec :: Vector4 -> Vector4 -> Vector4 -> Vector4 -> Matrix4 |
| 173 | mat4fromVec v0 v1 v2 v3 = Matrix4 | 173 | mat4fromVec v0 v1 v2 v3 = Matrix4 |
| 174 | (V4.x v0) (V4.x v1) (V4.x v2) (V4.x v3) | 174 | (V4.x v0) (V4.x v1) (V4.x v2) (V4.x v3) |
| 175 | (V4.y v0) (V4.y v1) (V4.y v2) (V4.y v3) | 175 | (V4.y v0) (V4.y v1) (V4.y v2) (V4.y v3) |
| 176 | (V4.z v0) (V4.z v1) (V4.z v2) (V4.z v3) | 176 | (V4.z v0) (V4.z v1) (V4.z v2) (V4.z v3) |
| 177 | (V4.w v0) (V4.w v1) (V4.w v2) (V4.w v3) | 177 | (V4.w v0) (V4.w v1) (V4.w v2) (V4.w v3) |
| 178 | 178 | ||
| 179 | 179 | ||
| 180 | -- | Build a transformation 'Matrix4' from the given vectors. | 180 | -- | Build a transformation 'Matrix4' from the given vectors. |
| 181 | transform :: Vector3 -- ^ Right vector. | 181 | transform :: Vector3 -- ^ Right vector. |
| 182 | -> Vector3 -- ^ Up vector. | 182 | -> Vector3 -- ^ Up vector. |
| 183 | -> Vector3 -- ^ Forward vector. | 183 | -> Vector3 -- ^ Forward vector. |
| 184 | -> Vector3 -- ^ Position. | 184 | -> Vector3 -- ^ Position. |
| 185 | -> Matrix4 | 185 | -> Matrix4 |
| 186 | 186 | ||
| 187 | transform right up fwd pos = mat4 | 187 | transform right up fwd pos = mat4 |
| 188 | (V3.x right) (V3.x up) (V3.x fwd) (V3.x pos) | 188 | (V3.x right) (V3.x up) (V3.x fwd) (V3.x pos) |
| 189 | (V3.y right) (V3.y up) (V3.y fwd) (V3.y pos) | 189 | (V3.y right) (V3.y up) (V3.y fwd) (V3.y pos) |
| 190 | (V3.z right) (V3.z up) (V3.z fwd) (V3.z pos) | 190 | (V3.z right) (V3.z up) (V3.z fwd) (V3.z pos) |
| 191 | 0 0 0 1 | 191 | 0 0 0 1 |
| 192 | 192 | ||
| 193 | 193 | ||
| 194 | -- | Get the translation part of the given transformation matrix. | 194 | -- | Get the translation part of the given transformation matrix. |
| @@ -230,198 +230,198 @@ lookAt pos target = | |||
| 230 | u = r `cross` fwd | 230 | u = r `cross` fwd |
| 231 | in | 231 | in |
| 232 | transform r u (-fwd) pos | 232 | transform r u (-fwd) pos |
| 233 | 233 | ||
| 234 | 234 | ||
| 235 | -- | Zip two matrices together with the specified function. | 235 | -- | Zip two matrices together with the specified function. |
| 236 | zipWith :: (Float -> Float -> Float) -> Matrix4 -> Matrix4 -> Matrix4 | 236 | zipWith :: (Float -> Float -> Float) -> Matrix4 -> Matrix4 -> Matrix4 |
| 237 | zipWith f a b = Matrix4 | 237 | zipWith f a b = Matrix4 |
| 238 | (f (m00 a) (m00 b)) (f (m10 a) (m10 b)) (f (m20 a) (m20 b)) (f (m30 a) (m30 b)) | 238 | (f (m00 a) (m00 b)) (f (m10 a) (m10 b)) (f (m20 a) (m20 b)) (f (m30 a) (m30 b)) |
| 239 | (f (m01 a) (m01 b)) (f (m11 a) (m11 b)) (f (m21 a) (m21 b)) (f (m31 a) (m31 b)) | 239 | (f (m01 a) (m01 b)) (f (m11 a) (m11 b)) (f (m21 a) (m21 b)) (f (m31 a) (m31 b)) |
| 240 | (f (m02 a) (m02 b)) (f (m12 a) (m12 b)) (f (m22 a) (m22 b)) (f (m32 a) (m32 b)) | 240 | (f (m02 a) (m02 b)) (f (m12 a) (m12 b)) (f (m22 a) (m22 b)) (f (m32 a) (m32 b)) |
| 241 | (f (m03 a) (m03 b)) (f (m13 a) (m13 b)) (f (m23 a) (m23 b)) (f (m33 a) (m33 b)) | 241 | (f (m03 a) (m03 b)) (f (m13 a) (m13 b)) (f (m23 a) (m23 b)) (f (m33 a) (m33 b)) |
| 242 | 242 | ||
| 243 | 243 | ||
| 244 | -- | Map the specified function to the specified matrix. | 244 | -- | Map the specified function to the specified matrix. |
| 245 | map :: (Float -> Float) -> Matrix4 -> Matrix4 | 245 | map :: (Float -> Float) -> Matrix4 -> Matrix4 |
| 246 | map f m = Matrix4 | 246 | map f m = Matrix4 |
| 247 | (f . m00 $ m) (f . m10 $ m) (f . m20 $ m) (f . m30 $ m) | 247 | (f . m00 $ m) (f . m10 $ m) (f . m20 $ m) (f . m30 $ m) |
| 248 | (f . m01 $ m) (f . m11 $ m) (f . m21 $ m) (f . m31 $ m) | 248 | (f . m01 $ m) (f . m11 $ m) (f . m21 $ m) (f . m31 $ m) |
| 249 | (f . m02 $ m) (f . m12 $ m) (f . m22 $ m) (f . m32 $ m) | 249 | (f . m02 $ m) (f . m12 $ m) (f . m22 $ m) (f . m32 $ m) |
| 250 | (f . m03 $ m) (f . m13 $ m) (f . m23 $ m) (f . m33 $ m) | 250 | (f . m03 $ m) (f . m13 $ m) (f . m23 $ m) (f . m33 $ m) |
| 251 | 251 | ||
| 252 | 252 | ||
| 253 | -- | Return the identity matrix. | 253 | -- | Return the identity matrix. |
| 254 | id :: Matrix4 | 254 | id :: Matrix4 |
| 255 | id = mat4 | 255 | id = mat4 |
| 256 | 1 0 0 0 | 256 | 1 0 0 0 |
| 257 | 0 1 0 0 | 257 | 0 1 0 0 |
| 258 | 0 0 1 0 | 258 | 0 0 1 0 |
| 259 | 0 0 0 1 | 259 | 0 0 0 1 |
| 260 | 260 | ||
| 261 | 261 | ||
| 262 | -- | Create a translation matrix. | 262 | -- | Create a translation matrix. |
| 263 | transl :: Float -> Float -> Float -> Matrix4 | 263 | transl :: Float -> Float -> Float -> Matrix4 |
| 264 | transl x y z = mat4 | 264 | transl x y z = mat4 |
| 265 | 1 0 0 x | 265 | 1 0 0 x |
| 266 | 0 1 0 y | 266 | 0 1 0 y |
| 267 | 0 0 1 z | 267 | 0 0 1 z |
| 268 | 0 0 0 1 | 268 | 0 0 0 1 |
| 269 | 269 | ||
| 270 | 270 | ||
| 271 | -- | Create a translation matrix. | 271 | -- | Create a translation matrix. |
| 272 | translv :: Vector3 -> Matrix4 | 272 | translv :: Vector3 -> Matrix4 |
| 273 | translv v = mat4 | 273 | translv v = mat4 |
| 274 | 1 0 0 (V3.x v) | 274 | 1 0 0 (V3.x v) |
| 275 | 0 1 0 (V3.y v) | 275 | 0 1 0 (V3.y v) |
| 276 | 0 0 1 (V3.z v) | 276 | 0 0 1 (V3.z v) |
| 277 | 0 0 0 1 | 277 | 0 0 0 1 |
| 278 | 278 | ||
| 279 | 279 | ||
| 280 | -- | Create a rotation matrix rotating about the X axis. | 280 | -- | Create a rotation matrix rotating about the X axis. |
| 281 | -- The given angle must be in degrees. | 281 | -- The given angle must be in degrees. |
| 282 | rotX :: Float -> Matrix4 | 282 | rotX :: Float -> Matrix4 |
| 283 | rotX angle = mat4 | 283 | rotX angle = mat4 |
| 284 | 1 0 0 0 | 284 | 1 0 0 0 |
| 285 | 0 c (-s) 0 | 285 | 0 c (-s) 0 |
| 286 | 0 s c 0 | 286 | 0 s c 0 |
| 287 | 0 0 0 1 | 287 | 0 0 0 1 |
| 288 | where | 288 | where |
| 289 | s = sin . toRAD $ angle | 289 | s = sin . toRAD $ angle |
| 290 | c = cos . toRAD $ angle | 290 | c = cos . toRAD $ angle |
| 291 | 291 | ||
| 292 | 292 | ||
| 293 | -- | Create a rotation matrix rotating about the Y axis. | 293 | -- | Create a rotation matrix rotating about the Y axis. |
| 294 | -- The given angle must be in degrees. | 294 | -- The given angle must be in degrees. |
| 295 | rotY :: Float -> Matrix4 | 295 | rotY :: Float -> Matrix4 |
| 296 | rotY angle = mat4 | 296 | rotY angle = mat4 |
| 297 | c 0 s 0 | 297 | c 0 s 0 |
| 298 | 0 1 0 0 | 298 | 0 1 0 0 |
| 299 | (-s) 0 c 0 | 299 | (-s) 0 c 0 |
| 300 | 0 0 0 1 | 300 | 0 0 0 1 |
| 301 | where | 301 | where |
| 302 | s = sin . toRAD $ angle | 302 | s = sin . toRAD $ angle |
| 303 | c = cos . toRAD $ angle | 303 | c = cos . toRAD $ angle |
| 304 | 304 | ||
| 305 | 305 | ||
| 306 | -- | Create a rotation matrix rotating about the Z axis. | 306 | -- | Create a rotation matrix rotating about the Z axis. |
| 307 | -- The given angle must be in degrees. | 307 | -- The given angle must be in degrees. |
| 308 | rotZ :: Float -> Matrix4 | 308 | rotZ :: Float -> Matrix4 |
| 309 | rotZ angle = mat4 | 309 | rotZ angle = mat4 |
| 310 | c (-s) 0 0 | 310 | c (-s) 0 0 |
| 311 | s c 0 0 | 311 | s c 0 0 |
| 312 | 0 0 1 0 | 312 | 0 0 1 0 |
| 313 | 0 0 0 1 | 313 | 0 0 0 1 |
| 314 | where | 314 | where |
| 315 | s = sin . toRAD $ angle | 315 | s = sin . toRAD $ angle |
| 316 | c = cos . toRAD $ angle | 316 | c = cos . toRAD $ angle |
| 317 | 317 | ||
| 318 | 318 | ||
| 319 | -- | Create a rotation matrix rotating about the specified axis. | 319 | -- | Create a rotation matrix rotating about the specified axis. |
| 320 | -- The given angle must be in degrees. | 320 | -- The given angle must be in degrees. |
| 321 | axisAngle :: Vector3 -> Float -> Matrix4 | 321 | axisAngle :: Vector3 -> Float -> Matrix4 |
| 322 | axisAngle v angle = mat4 | 322 | axisAngle v angle = mat4 |
| 323 | (c + omc*x^2) (omc*xy-sz) (omc*xz+sy) 0 | 323 | (c + omc*x^2) (omc*xy-sz) (omc*xz+sy) 0 |
| 324 | (omc*xy+sz) (c+omc*y^2) (omc*yz-sx) 0 | 324 | (omc*xy+sz) (c+omc*y^2) (omc*yz-sx) 0 |
| 325 | (omc*xz-sy) (omc*yz+sx) (c+omc*z^2) 0 | 325 | (omc*xz-sy) (omc*yz+sx) (c+omc*z^2) 0 |
| 326 | 0 0 0 1 | 326 | 0 0 0 1 |
| 327 | where | 327 | where |
| 328 | x = V3.x v | 328 | x = V3.x v |
| 329 | y = V3.y v | 329 | y = V3.y v |
| 330 | z = V3.z v | 330 | z = V3.z v |
| 331 | s = sin . toRAD $ angle | 331 | s = sin . toRAD $ angle |
| 332 | c = cos . toRAD $ angle | 332 | c = cos . toRAD $ angle |
| 333 | xy = x*y | 333 | xy = x*y |
| 334 | xz = x*z | 334 | xz = x*z |
| 335 | yz = y*z | 335 | yz = y*z |
| 336 | sx = s*x | 336 | sx = s*x |
| 337 | sy = s*y | 337 | sy = s*y |
| 338 | sz = s*z | 338 | sz = s*z |
| 339 | omc = 1 - c | 339 | omc = 1 - c |
| 340 | 340 | ||
| 341 | 341 | ||
| 342 | -- | Create a scale matrix. | 342 | -- | Create a scale matrix. |
| 343 | scale :: Float -> Float -> Float -> Matrix4 | 343 | scale :: Float -> Float -> Float -> Matrix4 |
| 344 | scale sx sy sz = mat4 | 344 | scale sx sy sz = mat4 |
| 345 | sx 0 0 0 | 345 | sx 0 0 0 |
| 346 | 0 sy 0 0 | 346 | 0 sy 0 0 |
| 347 | 0 0 sz 0 | 347 | 0 0 sz 0 |
| 348 | 0 0 0 1 | 348 | 0 0 0 1 |
| 349 | 349 | ||
| 350 | 350 | ||
| 351 | -- | Create a scale matrix. | 351 | -- | Create a scale matrix. |
| 352 | scalev :: Vector3 -> Matrix4 | 352 | scalev :: Vector3 -> Matrix4 |
| 353 | scalev v = mat4 | 353 | scalev v = mat4 |
| 354 | sx 0 0 0 | 354 | sx 0 0 0 |
| 355 | 0 sy 0 0 | 355 | 0 sy 0 0 |
| 356 | 0 0 sz 0 | 356 | 0 0 sz 0 |
| 357 | 0 0 0 1 | 357 | 0 0 0 1 |
| 358 | where | 358 | where |
| 359 | sx = V3.x v | 359 | sx = V3.x v |
| 360 | sy = V3.y v | 360 | sy = V3.y v |
| 361 | sz = V3.z v | 361 | sz = V3.z v |
| 362 | 362 | ||
| 363 | 363 | ||
| 364 | -- | Create an X reflection matrix. | 364 | -- | Create an X reflection matrix. |
| 365 | reflectX :: Matrix4 | 365 | reflectX :: Matrix4 |
| 366 | reflectX = mat4 | 366 | reflectX = mat4 |
| 367 | (-1) 0 0 0 | 367 | (-1) 0 0 0 |
| 368 | 0 1 0 0 | 368 | 0 1 0 0 |
| 369 | 0 0 1 0 | 369 | 0 0 1 0 |
| 370 | 0 0 0 1 | 370 | 0 0 0 1 |
| 371 | 371 | ||
| 372 | 372 | ||
| 373 | -- | Create a Y reflection matrix. | 373 | -- | Create a Y reflection matrix. |
| 374 | reflectY :: Matrix4 | 374 | reflectY :: Matrix4 |
| 375 | reflectY = mat4 | 375 | reflectY = mat4 |
| 376 | 1 0 0 0 | 376 | 1 0 0 0 |
| 377 | 0 (-1) 0 0 | 377 | 0 (-1) 0 0 |
| 378 | 0 0 1 0 | 378 | 0 0 1 0 |
| 379 | 0 0 0 1 | 379 | 0 0 0 1 |
| 380 | 380 | ||
| 381 | 381 | ||
| 382 | -- | Create a Z reflection matrix. | 382 | -- | Create a Z reflection matrix. |
| 383 | reflectZ :: Matrix4 | 383 | reflectZ :: Matrix4 |
| 384 | reflectZ = mat4 | 384 | reflectZ = mat4 |
| 385 | 1 0 0 0 | 385 | 1 0 0 0 |
| 386 | 0 1 0 0 | 386 | 0 1 0 0 |
| 387 | 0 0 (-1) 0 | 387 | 0 0 (-1) 0 |
| 388 | 0 0 0 1 | 388 | 0 0 0 1 |
| 389 | 389 | ||
| 390 | 390 | ||
| 391 | -- | Create an orthogonal projection matrix. | 391 | -- | Create an orthogonal projection matrix. |
| 392 | ortho :: Float -- ^ Left. | 392 | ortho :: Float -- ^ Left. |
| 393 | -> Float -- ^ Right. | 393 | -> Float -- ^ Right. |
| 394 | -> Float -- ^ Bottom. | 394 | -> Float -- ^ Bottom. |
| 395 | -> Float -- ^ Top. | 395 | -> Float -- ^ Top. |
| 396 | -> Float -- ^ Near clip. | 396 | -> Float -- ^ Near clip. |
| 397 | -> Float -- ^ Far clip. | 397 | -> Float -- ^ Far clip. |
| 398 | -> Matrix4 | 398 | -> Matrix4 |
| 399 | 399 | ||
| 400 | ortho l r b t n f = | 400 | ortho l r b t n f = |
| 401 | let tx = (-(r+l)/(r-l)) | 401 | let tx = (-(r+l)/(r-l)) |
| 402 | ty = (-(t+b)/(t-b)) | 402 | ty = (-(t+b)/(t-b)) |
| 403 | tz = (-(f+n)/(f-n)) | 403 | tz = (-(f+n)/(f-n)) |
| 404 | in mat4 | 404 | in mat4 |
| 405 | (2/(r-l)) 0 0 tx | 405 | (2/(r-l)) 0 0 tx |
| 406 | 0 (2/(t-b)) 0 ty | 406 | 0 (2/(t-b)) 0 ty |
| 407 | 0 0 ((-2)/(f-n)) tz | 407 | 0 0 ((-2)/(f-n)) tz |
| 408 | 0 0 0 1 | 408 | 0 0 0 1 |
| 409 | 409 | ||
| 410 | 410 | ||
| 411 | -- | Create a perspective projection matrix. | 411 | -- | Create a perspective projection matrix. |
| 412 | perspective :: Float -- ^ Fovy - Vertical field of view angle in degrees. | 412 | perspective :: Float -- ^ Fovy - Vertical field of view angle in degrees. |
| 413 | -> Float -- ^ Aspect ratio. | 413 | -> Float -- ^ Aspect ratio. |
| 414 | -> Float -- ^ Near clip distance. | 414 | -> Float -- ^ Near clip distance. |
| 415 | -> Float -- ^ Far clip distance | 415 | -> Float -- ^ Far clip distance |
| 416 | -> Matrix4 | 416 | -> Matrix4 |
| 417 | perspective fovy r near far = | 417 | perspective fovy r near far = |
| 418 | let f = 1 / tan (toRAD fovy / 2) | 418 | let f = 1 / tan (toRAD fovy / 2) |
| 419 | a = near - far | 419 | a = near - far |
| 420 | in mat4 | 420 | in mat4 |
| 421 | (f/r) 0 0 0 | 421 | (f/r) 0 0 0 |
| 422 | 0 f 0 0 | 422 | 0 f 0 0 |
| 423 | 0 0 ((near+far)/a) (2*near*far/a) | 423 | 0 0 ((near+far)/a) (2*near*far/a) |
| 424 | 0 0 (-1) 0 | 424 | 0 0 (-1) 0 |
| 425 | 425 | ||
| 426 | 426 | ||
| 427 | -- | Create a plane projection matrix. | 427 | -- | Create a plane projection matrix. |
| @@ -442,19 +442,19 @@ planeProj n d l = | |||
| 442 | (-nx*ly) (d + c - ny*ly) (-nz*ly) (-ly*d) | 442 | (-nx*ly) (d + c - ny*ly) (-nz*ly) (-ly*d) |
| 443 | (-nx*lz) (-ny*lz) (d + c - nz*lz) (-lz*d) | 443 | (-nx*lz) (-ny*lz) (d + c - nz*lz) (-lz*d) |
| 444 | (-nx) (-ny) (-nz) c | 444 | (-nx) (-ny) (-nz) c |
| 445 | 445 | ||
| 446 | 446 | ||
| 447 | -- | Transpose the specified matrix. | 447 | -- | Transpose the specified matrix. |
| 448 | transpose :: Matrix4 -> Matrix4 | 448 | transpose :: Matrix4 -> Matrix4 |
| 449 | transpose m = mat4 | 449 | transpose m = mat4 |
| 450 | (m00 m) (m01 m) (m02 m) (m03 m) | 450 | (m00 m) (m01 m) (m02 m) (m03 m) |
| 451 | (m10 m) (m11 m) (m12 m) (m13 m) | 451 | (m10 m) (m11 m) (m12 m) (m13 m) |
| 452 | (m20 m) (m21 m) (m22 m) (m23 m) | 452 | (m20 m) (m21 m) (m22 m) (m23 m) |
| 453 | (m30 m) (m31 m) (m32 m) (m33 m) | 453 | (m30 m) (m31 m) (m32 m) (m33 m) |
| 454 | 454 | ||
| 455 | 455 | ||
| 456 | -- | Invert the given transformation matrix. | 456 | -- | Invert the given transformation matrix. |
| 457 | inverseTransform :: Matrix4 -> Matrix4 | 457 | inverseTransform :: Matrix4 -> Matrix4 |
| 458 | inverseTransform mat = | 458 | inverseTransform mat = |
| 459 | let | 459 | let |
| 460 | r = right mat | 460 | r = right mat |
| @@ -611,26 +611,26 @@ inverse mat = | |||
| 611 | (m00' * det) (m04' * det) (m08' * det) (m12' * det) | 611 | (m00' * det) (m04' * det) (m08' * det) (m12' * det) |
| 612 | (m01' * det) (m05' * det) (m09' * det) (m13' * det) | 612 | (m01' * det) (m05' * det) (m09' * det) (m13' * det) |
| 613 | (m02' * det) (m06' * det) (m10' * det) (m14' * det) | 613 | (m02' * det) (m06' * det) (m10' * det) (m14' * det) |
| 614 | (m03' * det) (m07' * det) (m11' * det) (m15' * det) | 614 | (m03' * det) (m07' * det) (m11' * det) (m15' * det) |
| 615 | 615 | ||
| 616 | 616 | ||
| 617 | -- | Transform the given vector in 3D space with the given matrix. | 617 | -- | Transform the given vector in 3D space with the given matrix. |
| 618 | mul :: Float -> Matrix4 -> Vector3 -> Vector3 | 618 | mul :: Float -> Matrix4 -> Vector3 -> Vector3 |
| 619 | mul w m v = vec3 x' y' z' | 619 | mul w m v = vec3 x' y' z' |
| 620 | where | 620 | where |
| 621 | v' = vec4 (V3.x v) (V3.y v) (V3.z v) w | 621 | v' = vec4 (V3.x v) (V3.y v) (V3.z v) w |
| 622 | x' = row0 m `V4.dot` v' | 622 | x' = row0 m `V4.dot` v' |
| 623 | y' = row1 m `V4.dot` v' | 623 | y' = row1 m `V4.dot` v' |
| 624 | z' = row2 m `V4.dot` v' | 624 | z' = row2 m `V4.dot` v' |
| 625 | 625 | ||
| 626 | 626 | ||
| 627 | -- | Transform the given point vector in 3D space with the given matrix. | 627 | -- | Transform the given point vector in 3D space with the given matrix. |
| 628 | mulp :: Matrix4 -> Vector3 -> Vector3 | 628 | mulp :: Matrix4 -> Vector3 -> Vector3 |
| 629 | mulp = mul 1 | 629 | mulp = mul 1 |
| 630 | 630 | ||
| 631 | 631 | ||
| 632 | -- | Transform the given directional vector in 3D space with the given matrix. | 632 | -- | Transform the given directional vector in 3D space with the given matrix. |
| 633 | muld :: Matrix4 -> Vector3 -> Vector3 | 633 | muld :: Matrix4 -> Vector3 -> Vector3 |
| 634 | muld = mul 0 | 634 | muld = mul 0 |
| 635 | 635 | ||
| 636 | 636 | ||
| @@ -639,13 +639,13 @@ muld = mul 0 | |||
| 639 | -- The vector is brought from homogeneous space to 3D space by performing a | 639 | -- The vector is brought from homogeneous space to 3D space by performing a |
| 640 | -- perspective divide. | 640 | -- perspective divide. |
| 641 | mul' :: Float -> Matrix4 -> Vector3 -> Vector3 | 641 | mul' :: Float -> Matrix4 -> Vector3 -> Vector3 |
| 642 | mul' w m v = vec3 (x'/w') (y'/w') (z'/w') | 642 | mul' w m v = vec3 (x'/w') (y'/w') (z'/w') |
| 643 | where | 643 | where |
| 644 | v' = vec4 (V3.x v) (V3.y v) (V3.z v) w | 644 | v' = vec4 (V3.x v) (V3.y v) (V3.z v) w |
| 645 | x' = row0 m `V4.dot` v' | 645 | x' = row0 m `V4.dot` v' |
| 646 | y' = row1 m `V4.dot` v' | 646 | y' = row1 m `V4.dot` v' |
| 647 | z' = row2 m `V4.dot` v' | 647 | z' = row2 m `V4.dot` v' |
| 648 | w' = row3 m `V4.dot` v' | 648 | w' = row3 m `V4.dot` v' |
| 649 | 649 | ||
| 650 | 650 | ||
| 651 | toRAD = (*pi) . (/180) | 651 | toRAD = (*pi) . (/180) |
diff --git a/Spear/Math/Plane.hs b/Spear/Math/Plane.hs index 8772a42..6fabbec 100644 --- a/Spear/Math/Plane.hs +++ b/Spear/Math/Plane.hs | |||
| @@ -7,7 +7,7 @@ module Spear.Math.Plane | |||
| 7 | where | 7 | where |
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | import Spear.Math.Vector3 as Vector | 10 | import Spear.Math.Vector3 |
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | data PointPlanePos = Front | Back | Contained deriving (Eq, Ord, Show) | 13 | data PointPlanePos = Front | Back | Contained deriving (Eq, Ord, Show) |
diff --git a/Spear/Math/Vector2.hs b/Spear/Math/Vector2.hs index ace86fe..581a64f 100644 --- a/Spear/Math/Vector2.hs +++ b/Spear/Math/Vector2.hs | |||
| @@ -1,155 +1,145 @@ | |||
| 1 | module Spear.Math.Vector2 | 1 | module Spear.Math.Vector2 |
| 2 | ( | 2 | ( |
| 3 | Vector2 | 3 | Vector2 |
| 4 | -- * Accessors | 4 | -- * Accessors |
| 5 | , x | 5 | , x |
| 6 | , y | 6 | , y |
| 7 | -- * Construction | 7 | -- * Construction |
| 8 | , unitx | 8 | , unitx |
| 9 | , unity | 9 | , unity |
| 10 | , zero | 10 | , zero |
| 11 | , fromList | 11 | , fromList |
| 12 | , vec2 | 12 | , vec2 |
| 13 | -- * Operations | 13 | -- * Operations |
| 14 | , v2min | 14 | , perp |
| 15 | , v2max | 15 | , dot |
| 16 | , dot | 16 | , normSq |
| 17 | , normSq | 17 | , norm |
| 18 | , norm | 18 | , scale |
| 19 | , scale | ||
| 20 | , normalise | ||
| 21 | , neg | 19 | , neg |
| 22 | , perp | 20 | , normalise |
| 23 | ) | 21 | ) |
| 24 | where | 22 | where |
| 25 | 23 | ||
| 26 | import Foreign.C.Types (CFloat) | 24 | |
| 27 | import Foreign.Storable | 25 | import Foreign.C.Types (CFloat) |
| 28 | 26 | import Foreign.Storable | |
| 29 | 27 | ||
| 30 | -- | Represents a vector in 2D. | 28 | |
| 31 | data Vector2 = Vector2 {-# UNPACK #-} !Float {-# UNPACK #-} !Float deriving (Eq, Show) | 29 | -- | Represents a vector in 2D. |
| 32 | 30 | data Vector2 = Vector2 {-# UNPACK #-} !Float {-# UNPACK #-} !Float deriving (Eq, Show) | |
| 33 | 31 | ||
| 34 | instance Num Vector2 where | 32 | |
| 35 | Vector2 ax ay + Vector2 bx by = Vector2 (ax + bx) (ay + by) | 33 | instance Num Vector2 where |
| 36 | Vector2 ax ay - Vector2 bx by = Vector2 (ax - bx) (ay - by) | 34 | Vector2 ax ay + Vector2 bx by = Vector2 (ax + bx) (ay + by) |
| 37 | Vector2 ax ay * Vector2 bx by = Vector2 (ax * bx) (ay * by) | 35 | Vector2 ax ay - Vector2 bx by = Vector2 (ax - bx) (ay - by) |
| 38 | abs (Vector2 ax ay) = Vector2 (abs ax) (abs ay) | 36 | Vector2 ax ay * Vector2 bx by = Vector2 (ax * bx) (ay * by) |
| 39 | signum (Vector2 ax ay) = Vector2 (signum ax) (signum ay) | 37 | abs (Vector2 ax ay) = Vector2 (abs ax) (abs ay) |
| 40 | fromInteger i = Vector2 i' i' where i' = fromInteger i | 38 | signum (Vector2 ax ay) = Vector2 (signum ax) (signum ay) |
| 41 | 39 | fromInteger i = Vector2 i' i' where i' = fromInteger i | |
| 42 | 40 | ||
| 43 | instance Fractional Vector2 where | 41 | |
| 44 | Vector2 ax ay / Vector2 bx by = Vector2 (ax / bx) (ay / by) | 42 | instance Fractional Vector2 where |
| 45 | fromRational r = Vector2 r' r' where r' = fromRational r | 43 | Vector2 ax ay / Vector2 bx by = Vector2 (ax / bx) (ay / by) |
| 46 | 44 | fromRational r = Vector2 r' r' where r' = fromRational r | |
| 47 | 45 | ||
| 48 | instance Ord Vector2 where | 46 | |
| 49 | Vector2 ax ay <= Vector2 bx by = (ax <= bx) || (ax == bx && ay <= by) | 47 | instance Ord Vector2 where |
| 50 | Vector2 ax ay >= Vector2 bx by = (ax >= bx) || (ax == bx && ay >= by) | 48 | Vector2 ax ay <= Vector2 bx by = (ax <= bx) || (ax == bx && ay <= by) |
| 51 | Vector2 ax ay < Vector2 bx by = (ax < bx) || (ax == bx && ay < by) | 49 | Vector2 ax ay >= Vector2 bx by = (ax >= bx) || (ax == bx && ay >= by) |
| 52 | Vector2 ax ay > Vector2 bx by = (ax > bx) || (ax == bx && ay > by) | 50 | Vector2 ax ay < Vector2 bx by = (ax < bx) || (ax == bx && ay < by) |
| 53 | 51 | Vector2 ax ay > Vector2 bx by = (ax > bx) || (ax == bx && ay > by) | |
| 54 | 52 | max (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.max ax bx) (Prelude.max ay by) | |
| 55 | sizeFloat = sizeOf (undefined :: CFloat) | 53 | min (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.min ax bx) (Prelude.min ay by) |
| 56 | 54 | ||
| 57 | 55 | ||
| 58 | instance Storable Vector2 where | 56 | sizeFloat = sizeOf (undefined :: CFloat) |
| 59 | sizeOf _ = 2*sizeFloat | 57 | |
| 60 | alignment _ = alignment (undefined :: CFloat) | 58 | |
| 61 | 59 | instance Storable Vector2 where | |
| 62 | peek ptr = do | 60 | sizeOf _ = 2*sizeFloat |
| 63 | ax <- peekByteOff ptr 0 | 61 | alignment _ = alignment (undefined :: CFloat) |
| 64 | ay <- peekByteOff ptr $ sizeFloat | 62 | |
| 65 | return (Vector2 ax ay) | 63 | peek ptr = do |
| 66 | 64 | ax <- peekByteOff ptr 0 | |
| 67 | poke ptr (Vector2 ax ay) = do | 65 | ay <- peekByteOff ptr $ sizeFloat |
| 68 | pokeByteOff ptr 0 ax | 66 | return (Vector2 ax ay) |
| 69 | pokeByteOff ptr sizeFloat ay | 67 | |
| 70 | 68 | poke ptr (Vector2 ax ay) = do | |
| 71 | 69 | pokeByteOff ptr 0 ax | |
| 72 | -- | Get the vector's x coordinate. | 70 | pokeByteOff ptr sizeFloat ay |
| 71 | |||
| 72 | |||
| 73 | -- | Get the vector's x coordinate. | ||
| 73 | x (Vector2 ax _) = ax | 74 | x (Vector2 ax _) = ax |
| 74 | 75 | ||
| 75 | 76 | ||
| 76 | -- | Get the vector's y coordinate. | 77 | -- | Get the vector's y coordinate. |
| 77 | y (Vector2 _ ay) = ay | 78 | y (Vector2 _ ay) = ay |
| 78 | 79 | ||
| 79 | 80 | ||
| 80 | -- | Unit vector along the X axis. | 81 | -- | Unit vector along the X axis. |
| 81 | unitx :: Vector2 | 82 | unitx :: Vector2 |
| 82 | unitx = Vector2 1 0 | 83 | unitx = Vector2 1 0 |
| 83 | 84 | ||
| 84 | 85 | ||
| 85 | -- | Unit vector along the Y axis. | 86 | -- | Unit vector along the Y axis. |
| 86 | unity :: Vector2 | 87 | unity :: Vector2 |
| 87 | unity = Vector2 0 1 | 88 | unity = Vector2 0 1 |
| 88 | 89 | ||
| 89 | 90 | ||
| 90 | -- | Zero vector. | 91 | -- | Zero vector. |
| 91 | zero :: Vector2 | 92 | zero :: Vector2 |
| 92 | zero = Vector2 0 0 | 93 | zero = Vector2 0 0 |
| 93 | 94 | ||
| 94 | 95 | ||
| 95 | -- | Create a vector from the given list. | 96 | -- | Create a vector from the given list. |
| 96 | fromList :: [Float] -> Vector2 | 97 | fromList :: [Float] -> Vector2 |
| 97 | fromList (ax:ay:_) = Vector2 ax ay | 98 | fromList (ax:ay:_) = Vector2 ax ay |
| 98 | 99 | ||
| 99 | 100 | ||
| 100 | -- | Create a vector from the given values. | 101 | -- | Create a vector from the given values. |
| 101 | vec2 :: Float -> Float -> Vector2 | 102 | vec2 :: Float -> Float -> Vector2 |
| 102 | vec2 ax ay = Vector2 ax ay | 103 | vec2 ax ay = Vector2 ax ay |
| 103 | |||
| 104 | |||
| 105 | -- | Create a vector with components set to the minimum of each of the given vectors'. | ||
| 106 | v2min :: Vector2 -> Vector2 -> Vector2 | ||
| 107 | v2min (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.min ax bx) (Prelude.min ay by) | ||
| 108 | |||
| 109 | |||
| 110 | -- | Create a vector with components set to the maximum of each of the given vectors'. | ||
| 111 | v2max :: Vector2 -> Vector2 -> Vector2 | ||
| 112 | v2max (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.max ax bx) (Prelude.max ay by) | ||
| 113 | |||
| 114 | |||
| 115 | -- | Compute the given vectors' dot product. | ||
| 116 | dot :: Vector2 -> Vector2 -> Float | ||
| 117 | Vector2 ax ay `dot` Vector2 bx by = ax*bx + ay*by | ||
| 118 | |||
| 119 | |||
| 120 | -- | Compute the given vector's squared norm. | ||
| 121 | normSq :: Vector2 -> Float | ||
| 122 | normSq (Vector2 ax ay) = ax*ax + ay*ay | ||
| 123 | |||
| 124 | |||
| 125 | -- | Compute the given vector's norm. | ||
| 126 | norm :: Vector2 -> Float | ||
| 127 | norm = sqrt . normSq | ||
| 128 | |||
| 129 | |||
| 130 | -- | Multiply the given vector with the given scalar. | ||
| 131 | scale :: Float -> Vector2 -> Vector2 | ||
| 132 | scale s (Vector2 ax ay) = Vector2 (s*ax) (s*ay) | ||
| 133 | |||
| 134 | |||
| 135 | -- | Normalise the given vector. | ||
| 136 | normalise :: Vector2 -> Vector2 | ||
| 137 | normalise v = | ||
| 138 | let n' = norm v | ||
| 139 | n = if n' == 0 then 1 else n' | ||
| 140 | in | ||
| 141 | scale (1.0 / n) v | ||
| 142 | |||
| 143 | |||
| 144 | -- | Negate the given vector. | ||
| 145 | neg :: Vector2 -> Vector2 | ||
| 146 | neg (Vector2 ax ay) = Vector2 (-ax) (-ay) | ||
| 147 | 104 | ||
| 148 | 105 | ||
| 149 | -- | Compute a vector perpendicular to the given one, satisfying: | 106 | -- | Compute a vector perpendicular to the given one, satisfying: |
| 150 | -- | 107 | -- |
| 151 | -- perp (Vector2 0 1) = Vector2 1 0 | 108 | -- perp (Vector2 0 1) = Vector2 1 0 |
| 152 | -- | 109 | -- |
| 153 | -- perp (Vector2 1 0) = Vector2 0 (-1) | 110 | -- perp (Vector2 1 0) = Vector2 0 (-1) |
| 154 | perp :: Vector2 -> Vector2 | 111 | perp :: Vector2 -> Vector2 |
| 155 | perp (Vector2 x y) = Vector2 y (-x) | 112 | perp (Vector2 x y) = Vector2 y (-x) |
| 113 | |||
| 114 | |||
| 115 | -- | Compute the given vectors' dot product. | ||
| 116 | dot :: Vector2 -> Vector2 -> Float | ||
| 117 | Vector2 ax ay `dot` Vector2 bx by = ax*bx + ay*by | ||
| 118 | |||
| 119 | |||
| 120 | -- | Compute the given vector's squared norm. | ||
| 121 | normSq :: Vector2 -> Float | ||
| 122 | normSq (Vector2 ax ay) = ax*ax + ay*ay | ||
| 123 | |||
| 124 | |||
| 125 | -- | Compute the given vector's norm. | ||
| 126 | norm :: Vector2 -> Float | ||
| 127 | norm = sqrt . normSq | ||
| 128 | |||
| 129 | |||
| 130 | -- | Multiply the given vector with the given scalar. | ||
| 131 | scale :: Float -> Vector2 -> Vector2 | ||
| 132 | scale s (Vector2 ax ay) = Vector2 (s*ax) (s*ay) | ||
| 133 | |||
| 134 | |||
| 135 | -- | Negate the given vector. | ||
| 136 | neg :: Vector2 -> Vector2 | ||
| 137 | neg (Vector2 ax ay) = Vector2 (-ax) (-ay) | ||
| 138 | |||
| 139 | |||
| 140 | -- | Normalise the given vector. | ||
| 141 | normalise :: Vector2 -> Vector2 | ||
| 142 | normalise v = | ||
| 143 | let n' = norm v | ||
| 144 | n = if n' == 0 then 1 else n' | ||
| 145 | in scale (1.0 / n) v | ||
diff --git a/Spear/Math/Vector3.hs b/Spear/Math/Vector3.hs index 7ac0f7a..d280811 100644 --- a/Spear/Math/Vector3.hs +++ b/Spear/Math/Vector3.hs | |||
| @@ -14,18 +14,17 @@ module Spear.Math.Vector3 | |||
| 14 | , vec3 | 14 | , vec3 |
| 15 | , orbit | 15 | , orbit |
| 16 | -- * Operations | 16 | -- * Operations |
| 17 | , Spear.Math.Vector3.min | ||
| 18 | , Spear.Math.Vector3.max | ||
| 19 | , dot | 17 | , dot |
| 20 | , cross | 18 | , cross |
| 21 | , normSq | 19 | , normSq |
| 22 | , norm | 20 | , norm |
| 23 | , scale | 21 | , scale |
| 24 | , normalise | ||
| 25 | , neg | 22 | , neg |
| 23 | , normalise | ||
| 26 | ) | 24 | ) |
| 27 | where | 25 | where |
| 28 | 26 | ||
| 27 | |||
| 29 | import Foreign.C.Types (CFloat) | 28 | import Foreign.C.Types (CFloat) |
| 30 | import Foreign.Storable | 29 | import Foreign.Storable |
| 31 | 30 | ||
| @@ -73,6 +72,10 @@ instance Ord Vector3 where | |||
| 73 | || (ax == bx && ay > by) | 72 | || (ax == bx && ay > by) |
| 74 | || (ax == bx && ay == by && az > bz) | 73 | || (ax == bx && ay == by && az > bz) |
| 75 | 74 | ||
| 75 | max (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) | ||
| 76 | |||
| 77 | min (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) | ||
| 78 | |||
| 76 | 79 | ||
| 77 | sizeFloat = sizeOf (undefined :: CFloat) | 80 | sizeFloat = sizeOf (undefined :: CFloat) |
| 78 | 81 | ||
| @@ -149,16 +152,6 @@ orbit center radius anglex angley = | |||
| 149 | vec3 px py pz | 152 | vec3 px py pz |
| 150 | 153 | ||
| 151 | 154 | ||
| 152 | -- | Create a vector with components set to the minimum of each of the given vectors'. | ||
| 153 | min :: Vector3 -> Vector3 -> Vector3 | ||
| 154 | min (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) | ||
| 155 | |||
| 156 | |||
| 157 | -- | Create a vector with components set to the maximum of each of the given vectors'. | ||
| 158 | max :: Vector3 -> Vector3 -> Vector3 | ||
| 159 | max (Vector3 ax ay az) (Vector3 bx by bz) = Vector3 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) | ||
| 160 | |||
| 161 | |||
| 162 | -- | Compute the given vectors' dot product. | 155 | -- | Compute the given vectors' dot product. |
| 163 | dot :: Vector3 -> Vector3 -> Float | 156 | dot :: Vector3 -> Vector3 -> Float |
| 164 | Vector3 ax ay az `dot` Vector3 bx by bz = ax*bx + ay*by + az*bz | 157 | Vector3 ax ay az `dot` Vector3 bx by bz = ax*bx + ay*by + az*bz |
| @@ -169,31 +162,26 @@ cross :: Vector3 -> Vector3 -> Vector3 | |||
| 169 | (Vector3 ax ay az) `cross` (Vector3 bx by bz) = | 162 | (Vector3 ax ay az) `cross` (Vector3 bx by bz) = |
| 170 | Vector3 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) | 163 | Vector3 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) |
| 171 | 164 | ||
| 172 | 165 | ||
| 173 | -- | Compute the given vector's squared norm. | 166 | -- | Compute the given vector's squared norm. |
| 174 | normSq :: Vector3 -> Float | ||
| 175 | normSq (Vector3 ax ay az) = ax*ax + ay*ay + az*az | 167 | normSq (Vector3 ax ay az) = ax*ax + ay*ay + az*az |
| 176 | 168 | ||
| 177 | 169 | ||
| 178 | -- | Compute the given vector's norm. | 170 | -- | Compute the given vector's norm. |
| 179 | norm :: Vector3 -> Float | ||
| 180 | norm = sqrt . normSq | 171 | norm = sqrt . normSq |
| 181 | 172 | ||
| 182 | 173 | ||
| 183 | -- | Multiply the given vector with the given scalar. | 174 | -- | Multiply the given vector with the given scalar. |
| 184 | scale :: Float -> Vector3 -> Vector3 | ||
| 185 | scale s (Vector3 ax ay az) = Vector3 (s*ax) (s*ay) (s*az) | 175 | scale s (Vector3 ax ay az) = Vector3 (s*ax) (s*ay) (s*az) |
| 186 | 176 | ||
| 187 | 177 | ||
| 178 | -- | Negate the given vector. | ||
| 179 | neg (Vector3 ax ay az) = Vector3 (-ax) (-ay) (-az) | ||
| 180 | |||
| 181 | |||
| 188 | -- | Normalise the given vector. | 182 | -- | Normalise the given vector. |
| 189 | normalise :: Vector3 -> Vector3 | ||
| 190 | normalise v = | 183 | normalise v = |
| 191 | let n' = norm v | 184 | let n' = norm v |
| 192 | n = if n' == 0 then 1 else n' | 185 | n = if n' == 0 then 1 else n' |
| 193 | in | 186 | in scale (1.0 / n) v |
| 194 | scale (1.0 / n) v | ||
| 195 | |||
| 196 | 187 | ||
| 197 | -- | Negate the given vector. | ||
| 198 | neg :: Vector3 -> Vector3 | ||
| 199 | neg (Vector3 ax ay az) = Vector3 (-ax) (-ay) (-az) | ||
diff --git a/Spear/Math/Vector4.hs b/Spear/Math/Vector4.hs index 9ba35bc..554fb27 100644 --- a/Spear/Math/Vector4.hs +++ b/Spear/Math/Vector4.hs | |||
| @@ -1,183 +1,176 @@ | |||
| 1 | module Spear.Math.Vector4 | 1 | module Spear.Math.Vector4 |
| 2 | ( | 2 | ( |
| 3 | Vector4 | 3 | Vector4 |
| 4 | -- * Accessors | 4 | -- * Accessors |
| 5 | , x | 5 | , x |
| 6 | , y | 6 | , y |
| 7 | , z | 7 | , z |
| 8 | , w | 8 | , w |
| 9 | -- * Construction | 9 | -- * Construction |
| 10 | , unitX | 10 | , unitX |
| 11 | , unitY | 11 | , unitY |
| 12 | , unitZ | 12 | , unitZ |
| 13 | , fromList | 13 | , fromList |
| 14 | , vec4 | 14 | , vec4 |
| 15 | -- * Operations | 15 | -- * Operations |
| 16 | , Spear.Math.Vector4.min | 16 | , dot |
| 17 | , Spear.Math.Vector4.max | 17 | , normSq |
| 18 | , dot | 18 | , norm |
| 19 | , normSq | 19 | , scale |
| 20 | , norm | 20 | , neg |
| 21 | , scale | 21 | , normalise |
| 22 | , normalise | 22 | ) |
| 23 | , neg | 23 | where |
| 24 | ) | 24 | |
| 25 | where | 25 | |
| 26 | 26 | import Foreign.C.Types (CFloat) | |
| 27 | 27 | import Foreign.Storable | |
| 28 | import Foreign.C.Types (CFloat) | 28 | |
| 29 | import Foreign.Storable | 29 | |
| 30 | 30 | -- | Represents a vector in 3D. | |
| 31 | |||
| 32 | -- | Represents a vector in 3D. | ||
| 33 | data Vector4 = Vector4 | 31 | data Vector4 = Vector4 |
| 34 | {-# UNPACK #-} !Float | 32 | {-# UNPACK #-} !Float |
| 35 | {-# UNPACK #-} !Float | 33 | {-# UNPACK #-} !Float |
| 36 | {-# UNPACK #-} !Float | 34 | {-# UNPACK #-} !Float |
| 37 | {-# UNPACK #-} !Float | 35 | {-# UNPACK #-} !Float |
| 38 | deriving (Eq, Show) | 36 | deriving (Eq, Show) |
| 39 | 37 | ||
| 40 | 38 | ||
| 41 | instance Num Vector4 where | 39 | instance Num Vector4 where |
| 42 | Vector4 ax ay az aw + Vector4 bx by bz bw = Vector4 (ax + bx) (ay + by) (az + bz) (aw + bw) | 40 | Vector4 ax ay az aw + Vector4 bx by bz bw = Vector4 (ax + bx) (ay + by) (az + bz) (aw + bw) |
| 43 | Vector4 ax ay az aw - Vector4 bx by bz bw = Vector4 (ax - bx) (ay - by) (az - bz) (aw - bw) | 41 | Vector4 ax ay az aw - Vector4 bx by bz bw = Vector4 (ax - bx) (ay - by) (az - bz) (aw - bw) |
| 44 | Vector4 ax ay az aw * Vector4 bx by bz bw = Vector4 (ax * bx) (ay * by) (az * bz) (aw * bw) | 42 | Vector4 ax ay az aw * Vector4 bx by bz bw = Vector4 (ax * bx) (ay * by) (az * bz) (aw * bw) |
| 45 | abs (Vector4 ax ay az aw) = Vector4 (abs ax) (abs ay) (abs az) (abs aw) | 43 | abs (Vector4 ax ay az aw) = Vector4 (abs ax) (abs ay) (abs az) (abs aw) |
| 46 | signum (Vector4 ax ay az aw) = Vector4 (signum ax) (signum ay) (signum az) (signum aw) | 44 | signum (Vector4 ax ay az aw) = Vector4 (signum ax) (signum ay) (signum az) (signum aw) |
| 47 | fromInteger i = Vector4 i' i' i' i' where i' = fromInteger i | 45 | fromInteger i = Vector4 i' i' i' i' where i' = fromInteger i |
| 48 | 46 | ||
| 49 | 47 | ||
| 50 | instance Fractional Vector4 where | 48 | instance Fractional Vector4 where |
| 51 | Vector4 ax ay az aw / Vector4 bx by bz bw = Vector4 (ax / bx) (ay / by) (az / bz) (aw / bw) | 49 | Vector4 ax ay az aw / Vector4 bx by bz bw = Vector4 (ax / bx) (ay / by) (az / bz) (aw / bw) |
| 52 | fromRational r = Vector4 r' r' r' r' where r' = fromRational r | 50 | fromRational r = Vector4 r' r' r' r' where r' = fromRational r |
| 53 | 51 | ||
| 54 | 52 | ||
| 55 | instance Ord Vector4 where | 53 | instance Ord Vector4 where |
| 56 | Vector4 ax ay az aw <= Vector4 bx by bz bw | 54 | Vector4 ax ay az aw <= Vector4 bx by bz bw |
| 57 | = (ax <= bx) | 55 | = (ax <= bx) |
| 58 | || (az == bx && ay <= by) | 56 | || (az == bx && ay <= by) |
| 59 | || (ax == bx && ay == by && az <= bz) | 57 | || (ax == bx && ay == by && az <= bz) |
| 60 | || (ax == bx && ay == by && az == bz && aw <= bw) | 58 | || (ax == bx && ay == by && az == bz && aw <= bw) |
| 61 | 59 | ||
| 62 | Vector4 ax ay az aw >= Vector4 bx by bz bw | 60 | Vector4 ax ay az aw >= Vector4 bx by bz bw |
| 63 | = (ax >= bx) | 61 | = (ax >= bx) |
| 64 | || (ax == bx && ay >= by) | 62 | || (ax == bx && ay >= by) |
| 65 | || (ax == bx && ay == by && az >= bz) | 63 | || (ax == bx && ay == by && az >= bz) |
| 66 | || (ax == bx && ay == by && az == bz && aw >= bw) | 64 | || (ax == bx && ay == by && az == bz && aw >= bw) |
| 67 | 65 | ||
| 68 | Vector4 ax ay az aw < Vector4 bx by bz bw | 66 | Vector4 ax ay az aw < Vector4 bx by bz bw |
| 69 | = (ax < bx) | 67 | = (ax < bx) |
| 70 | || (az == bx && ay < by) | 68 | || (az == bx && ay < by) |
| 71 | || (ax == bx && ay == by && az < bz) | 69 | || (ax == bx && ay == by && az < bz) |
| 72 | || (ax == bx && ay == by && az == bz && aw < bw) | 70 | || (ax == bx && ay == by && az == bz && aw < bw) |
| 73 | 71 | ||
| 74 | Vector4 ax ay az aw > Vector4 bx by bz bw | 72 | Vector4 ax ay az aw > Vector4 bx by bz bw |
| 75 | = (ax > bx) | 73 | = (ax > bx) |
| 76 | || (ax == bx && ay > by) | 74 | || (ax == bx && ay > by) |
| 77 | || (ax == bx && ay == by && az > bz) | 75 | || (ax == bx && ay == by && az > bz) |
| 78 | || (ax == bx && ay == by && az == bz && aw > bw) | 76 | || (ax == bx && ay == by && az == bz && aw > bw) |
| 79 | 77 | ||
| 80 | 78 | min (Vector4 ax ay az aw) (Vector4 bx by bz bw) = | |
| 81 | sizeFloat = sizeOf (undefined :: CFloat) | 79 | Vector4 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) (Prelude.min aw bw) |
| 82 | 80 | ||
| 83 | 81 | max (Vector4 ax ay az aw) (Vector4 bx by bz bw) = | |
| 84 | instance Storable Vector4 where | 82 | Vector4 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) (Prelude.min aw bw) |
| 85 | sizeOf _ = 4*sizeFloat | 83 | |
| 86 | alignment _ = alignment (undefined :: CFloat) | 84 | |
| 87 | 85 | sizeFloat = sizeOf (undefined :: CFloat) | |
| 88 | peek ptr = do | 86 | |
| 89 | ax <- peekByteOff ptr 0 | 87 | |
| 90 | ay <- peekByteOff ptr $ 1 * sizeFloat | 88 | instance Storable Vector4 where |
| 91 | az <- peekByteOff ptr $ 2 * sizeFloat | 89 | sizeOf _ = 4*sizeFloat |
| 92 | aw <- peekByteOff ptr $ 3 * sizeFloat | 90 | alignment _ = alignment (undefined :: CFloat) |
| 93 | return (Vector4 ax ay az aw) | 91 | |
| 94 | 92 | peek ptr = do | |
| 95 | poke ptr (Vector4 ax ay az aw) = do | 93 | ax <- peekByteOff ptr 0 |
| 96 | pokeByteOff ptr 0 ax | 94 | ay <- peekByteOff ptr $ 1 * sizeFloat |
| 97 | pokeByteOff ptr (1 * sizeFloat) ay | 95 | az <- peekByteOff ptr $ 2 * sizeFloat |
| 98 | pokeByteOff ptr (2 * sizeFloat) az | 96 | aw <- peekByteOff ptr $ 3 * sizeFloat |
| 99 | pokeByteOff ptr (3 * sizeFloat) aw | 97 | return (Vector4 ax ay az aw) |
| 100 | 98 | ||
| 101 | 99 | poke ptr (Vector4 ax ay az aw) = do | |
| 102 | x (Vector4 ax _ _ _ ) = ax | 100 | pokeByteOff ptr 0 ax |
| 103 | y (Vector4 _ ay _ _ ) = ay | 101 | pokeByteOff ptr (1 * sizeFloat) ay |
| 104 | z (Vector4 _ _ az _ ) = az | 102 | pokeByteOff ptr (2 * sizeFloat) az |
| 105 | w (Vector4 _ _ _ aw) = aw | 103 | pokeByteOff ptr (3 * sizeFloat) aw |
| 106 | 104 | ||
| 107 | 105 | ||
| 108 | -- | Unit vector along the X axis. | 106 | x (Vector4 ax _ _ _ ) = ax |
| 109 | unitX :: Vector4 | 107 | y (Vector4 _ ay _ _ ) = ay |
| 110 | unitX = Vector4 1 0 0 0 | 108 | z (Vector4 _ _ az _ ) = az |
| 111 | 109 | w (Vector4 _ _ _ aw) = aw | |
| 112 | 110 | ||
| 113 | -- | Unit vector along the Y axis. | 111 | |
| 114 | unitY :: Vector4 | 112 | -- | Unit vector along the X axis. |
| 115 | unitY = Vector4 0 1 0 0 | 113 | unitX :: Vector4 |
| 116 | 114 | unitX = Vector4 1 0 0 0 | |
| 117 | 115 | ||
| 118 | -- | Unit vector along the Z axis. | 116 | |
| 119 | unitZ :: Vector4 | 117 | -- | Unit vector along the Y axis. |
| 120 | unitZ = Vector4 0 0 1 0 | 118 | unitY :: Vector4 |
| 121 | 119 | unitY = Vector4 0 1 0 0 | |
| 122 | 120 | ||
| 123 | -- | Create a vector from the given list. | 121 | |
| 124 | fromList :: [Float] -> Vector4 | 122 | -- | Unit vector along the Z axis. |
| 125 | fromList (ax:ay:az:aw:_) = Vector4 ax ay az aw | 123 | unitZ :: Vector4 |
| 126 | 124 | unitZ = Vector4 0 0 1 0 | |
| 127 | 125 | ||
| 128 | -- | Create a 4D vector from the given values. | 126 | |
| 129 | vec4 :: Float -> Float -> Float -> Float -> Vector4 | 127 | -- | Create a vector from the given list. |
| 130 | vec4 ax ay az aw = Vector4 ax ay az aw | 128 | fromList :: [Float] -> Vector4 |
| 131 | 129 | fromList (ax:ay:az:aw:_) = Vector4 ax ay az aw | |
| 132 | 130 | ||
| 133 | -- | Create a vector whose components are the minimum of each of the given vectors'. | 131 | |
| 134 | min :: Vector4 -> Vector4 -> Vector4 | 132 | -- | Create a 4D vector from the given values. |
| 135 | min (Vector4 ax ay az aw) (Vector4 bx by bz bw) = | 133 | vec4 :: Float -> Float -> Float -> Float -> Vector4 |
| 136 | Vector4 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) (Prelude.min aw bw) | 134 | vec4 ax ay az aw = Vector4 ax ay az aw |
| 137 | 135 | ||
| 138 | 136 | ||
| 139 | -- | Create a vector whose components are the maximum of each of the given vectors'. | 137 | -- | Compute the given vectors' dot product. |
| 140 | max :: Vector4 -> Vector4 -> Vector4 | 138 | dot :: Vector4 -> Vector4 -> Float |
| 141 | max (Vector4 ax ay az aw) (Vector4 bx by bz bw) = | 139 | Vector4 ax ay az aw `dot` Vector4 bx by bz bw = ax*bx + ay*by + az*bz + aw*bw |
| 142 | Vector4 (Prelude.max ax bx) (Prelude.max ay by) (Prelude.max az bz) (Prelude.min aw bw) | 140 | |
| 143 | 141 | ||
| 144 | 142 | -- | Compute the given vectors' cross product. | |
| 145 | -- | Compute the given vectors' dot product. | 143 | -- The vectors are projected to 3D space. The resulting vector is the cross product of the vectors' projections with w=0. |
| 146 | dot :: Vector4 -> Vector4 -> Float | 144 | cross :: Vector4 -> Vector4 -> Vector4 |
| 147 | Vector4 ax ay az aw `dot` Vector4 bx by bz bw = ax*bx + ay*by + az*bz + aw*bw | 145 | (Vector4 ax ay az _) `cross` (Vector4 bx by bz _) = |
| 148 | 146 | Vector4 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) 0 | |
| 149 | 147 | ||
| 150 | -- | Compute the given vectors' cross product. | 148 | |
| 151 | -- The vectors are projected to 3D space. The resulting vector is the cross product of the vectors' projections with w=0. | 149 | -- | Compute the given vector's squared norm. |
| 152 | cross :: Vector4 -> Vector4 -> Vector4 | 150 | normSq :: Vector4 -> Float |
| 153 | (Vector4 ax ay az _) `cross` (Vector4 bx by bz _) = | 151 | normSq (Vector4 ax ay az aw) = ax*ax + ay*ay + az*az + aw*aw |
| 154 | Vector4 (ay * bz - az * by) (az * bx - ax * bz) (ax * by - ay * bx) 0 | 152 | |
| 155 | 153 | ||
| 156 | 154 | -- | Compute the given vector's norm. | |
| 157 | -- | Compute the given vector's squared norm. | 155 | norm :: Vector4 -> Float |
| 158 | normSq :: Vector4 -> Float | 156 | norm = sqrt . normSq |
| 159 | normSq (Vector4 ax ay az aw) = ax*ax + ay*ay + az*az + aw*aw | 157 | |
| 160 | 158 | ||
| 161 | 159 | -- | Multiply the given vector with the given scalar. | |
| 162 | -- | Compute the given vector's norm. | 160 | scale :: Float -> Vector4 -> Vector4 |
| 163 | norm :: Vector4 -> Float | 161 | scale s (Vector4 ax ay az aw) = Vector4 (s*ax) (s*ay) (s*az) (s*aw) |
| 164 | norm = sqrt . normSq | 162 | |
| 165 | 163 | ||
| 166 | 164 | -- | Negate the given vector. | |
| 167 | -- | Multiply the given vector with the given scalar. | 165 | neg :: Vector4 -> Vector4 |
| 168 | scale :: Float -> Vector4 -> Vector4 | 166 | neg (Vector4 ax ay az aw) = Vector4 (-ax) (-ay) (-az) (-aw) |
| 169 | scale s (Vector4 ax ay az aw) = Vector4 (s*ax) (s*ay) (s*az) (s*aw) | 167 | |
| 170 | 168 | ||
| 171 | 169 | -- | Normalise the given vector. | |
| 172 | -- | Normalise the given vector. | 170 | normalise :: Vector4 -> Vector4 |
| 173 | normalise :: Vector4 -> Vector4 | 171 | normalise v = |
| 174 | normalise v = | 172 | let n' = norm v |
| 175 | let n' = norm v | 173 | n = if n' == 0 then 1 else n' |
| 176 | n = if n' == 0 then 1 else n' | 174 | in |
| 177 | in | 175 | scale (1.0 / n) v |
| 178 | scale (1.0 / n) v | 176 | |
| 179 | |||
| 180 | |||
| 181 | -- | Negate the given vector. | ||
| 182 | neg :: Vector4 -> Vector4 | ||
| 183 | neg (Vector4 ax ay az aw) = Vector4 (-ax) (-ay) (-az) (-aw) | ||
