aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Spear/Math/AABB.hs4
-rw-r--r--Spear/Math/Circle.hs8
-rw-r--r--Spear/Math/Matrix3.hs480
-rw-r--r--Spear/Math/Matrix4.hs838
-rw-r--r--Spear/Math/Plane.hs2
-rw-r--r--Spear/Math/Vector2.hs278
-rw-r--r--Spear/Math/Vector3.hs40
-rw-r--r--Spear/Math/Vector4.hs349
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
20aabb [] = error "Attempting to build a BoundingVolume from an empty list!" 20aabb [] = error "Attempting to build a BoundingVolume from an empty list!"
21 21
22aabb (x:xs) = foldr update (AABB x x) xs 22aabb (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.
27aabbpt :: AABB -> Vector2 -> Bool 27aabbpt :: AABB -> Vector2 -> Bool
28aabbpt (AABB min max) v = v >= min && v <= max 28aabbpt (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
22circle [] = error "Attempting to build a Circle from an empty list!" 22circle [] = error "Attempting to build a Circle from an empty list!"
23circle (x:xs) = Circle c r 23circle (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 @@
1module Spear.Math.Matrix3 1module 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)
40where 40where
41 41
42 42
43import Spear.Math.Vector2 as V2 43import Spear.Math.Vector2 as V2
44import Spear.Math.Vector3 as V3 44import Spear.Math.Vector3 as V3
45 45
46import Foreign.Storable 46import Foreign.Storable
47 47
48 48
49-- | Represents a 3x3 column major matrix. 49-- | Represents a 3x3 column major matrix.
50data Matrix3 = Matrix3 50data 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
57instance Show Matrix3 where 57instance 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
67instance Num Matrix3 where 67instance 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
101instance Storable Matrix3 where 101instance 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
122col0 (Matrix3 a00 _ _ a01 _ _ a02 _ _ ) = vec3 a00 a01 a02 122col0 (Matrix3 a00 _ _ a01 _ _ a02 _ _ ) = vec3 a00 a01 a02
123col1 (Matrix3 _ a10 _ _ a11 _ _ a12 _ ) = vec3 a10 a11 a12 123col1 (Matrix3 _ a10 _ _ a11 _ _ a12 _ ) = vec3 a10 a11 a12
124col2 (Matrix3 _ _ a20 _ _ a21 _ _ a22) = vec3 a20 a21 a22 124col2 (Matrix3 _ _ a20 _ _ a21 _ _ a22) = vec3 a20 a21 a22
125 125
126 126
127row0 (Matrix3 a00 a10 a20 _ _ _ _ _ _ ) = vec3 a00 a10 a20 127row0 (Matrix3 a00 a10 a20 _ _ _ _ _ _ ) = vec3 a00 a10 a20
128row1 (Matrix3 _ _ _ a01 a11 a21 _ _ _ ) = vec3 a01 a11 a21 128row1 (Matrix3 _ _ _ a01 a11 a21 _ _ _ ) = vec3 a01 a11 a21
129row2 (Matrix3 _ _ _ _ _ _ a02 a12 a22) = vec3 a02 a12 a22 129row2 (Matrix3 _ _ _ _ _ _ a02 a12 a22) = vec3 a02 a12 a22
130 130
131 131
132right (Matrix3 a00 _ _ a01 _ _ _ _ _) = vec2 a00 a01 132right (Matrix3 a00 _ _ a01 _ _ _ _ _) = vec2 a00 a01
133up (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11 133up (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11
134forward (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11 134forward (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11
135position (Matrix3 _ _ a20 _ _ a21 _ _ _) = vec2 a20 a21 135position (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.
139mat3 = Matrix3 139mat3 = Matrix3
140 140
141 141
142-- | Build a matrix from three vectors in 3D. 142-- | Build a matrix from three vectors in 3D.
143mat3fromVec :: Vector3 -> Vector3 -> Vector3 -> Matrix3 143mat3fromVec :: Vector3 -> Vector3 -> Vector3 -> Matrix3
144mat3fromVec v0 v1 v2 = Matrix3 144mat3fromVec 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.
151transform :: Vector2 -- ^ Right vector 151transform :: 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
156transform r f p = mat3 156transform 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.
187id :: Matrix3 187id :: Matrix3
188id = mat3 188id = 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.
216rot :: Float -> Matrix3 216rot :: Float -> Matrix3
217rot angle = mat3 217rot 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.
227scale :: Float -> Float -> Float -> Matrix3 227scale :: Float -> Float -> Float -> Matrix3
228scale sx sy sz = mat3 228scale 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.
235scalev :: Vector3 -> Matrix3 235scalev :: Vector3 -> Matrix3
236scalev v = mat3 236scalev 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.
247reflectX :: Matrix3 247reflectX :: Matrix3
248reflectX = mat3 248reflectX = 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.
255reflectY :: Matrix3 255reflectY :: Matrix3
256reflectY = mat3 256reflectY = 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.
263reflectZ :: Matrix3 263reflectZ :: Matrix3
264reflectZ = mat3 264reflectZ = 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.
271transpose :: Matrix3 -> Matrix3 271transpose :: Matrix3 -> Matrix3
272transpose m = mat3 272transpose 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.
298mul :: Matrix3 -> Vector3 -> Vector3 298mul :: Matrix3 -> Vector3 -> Vector3
299mul m v = vec3 x' y' z' 299mul 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.
308zipWith :: (Float -> Float -> Float) -> Matrix3 -> Matrix3 -> Matrix3 308zipWith :: (Float -> Float -> Float) -> Matrix3 -> Matrix3 -> Matrix3
309zipWith f a b = Matrix3 309zipWith 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'.
316map :: (Float -> Float) -> Matrix3 -> Matrix3 316map :: (Float -> Float) -> Matrix3 -> Matrix3
317map f m = Matrix3 317map 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.
324inverseTransform :: Matrix3 -> Matrix3 324inverseTransform :: Matrix3 -> Matrix3
325inverseTransform mat = 325inverseTransform 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
335fromDeg :: (Floating a) => a -> a 335fromDeg :: (Floating a) => a -> a
336fromDeg = (*pi) . (/180) 336fromDeg = (*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 @@
1module Spear.Math.Matrix4 1module 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)
51where 51where
52 52
53 53
54import Spear.Math.Vector3 as V3 54import Spear.Math.Vector3 as V3
55import Spear.Math.Vector4 as V4 55import Spear.Math.Vector4 as V4
56 56
57import Foreign.Storable 57import Foreign.Storable
58 58
59 59
60-- | Represents a 4x4 column major matrix. 60-- | Represents a 4x4 column major matrix.
61data Matrix4 = Matrix4 61data 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
69instance Show Matrix4 where 69instance 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
80instance Num Matrix4 where 80instance 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
124instance Storable Matrix4 where 124instance 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
149col0 (Matrix4 a00 _ _ _ a01 _ _ _ a02 _ _ _ a03 _ _ _ ) = vec4 a00 a01 a02 a03 149col0 (Matrix4 a00 _ _ _ a01 _ _ _ a02 _ _ _ a03 _ _ _ ) = vec4 a00 a01 a02 a03
150col1 (Matrix4 _ a10 _ _ _ a11 _ _ _ a12 _ _ _ a13 _ _ ) = vec4 a10 a11 a12 a13 150col1 (Matrix4 _ a10 _ _ _ a11 _ _ _ a12 _ _ _ a13 _ _ ) = vec4 a10 a11 a12 a13
151col2 (Matrix4 _ _ a20 _ _ _ a21 _ _ _ a22 _ _ _ a23 _ ) = vec4 a20 a21 a22 a23 151col2 (Matrix4 _ _ a20 _ _ _ a21 _ _ _ a22 _ _ _ a23 _ ) = vec4 a20 a21 a22 a23
152col3 (Matrix4 _ _ _ a30 _ _ _ a31 _ _ _ a32 _ _ _ a33) = vec4 a30 a31 a32 a33 152col3 (Matrix4 _ _ _ a30 _ _ _ a31 _ _ _ a32 _ _ _ a33) = vec4 a30 a31 a32 a33
153 153
154 154
155row0 (Matrix4 a00 a01 a02 a03 _ _ _ _ _ _ _ _ _ _ _ _ ) = vec4 a00 a01 a02 a03 155row0 (Matrix4 a00 a01 a02 a03 _ _ _ _ _ _ _ _ _ _ _ _ ) = vec4 a00 a01 a02 a03
156row1 (Matrix4 _ _ _ _ a10 a11 a12 a13 _ _ _ _ _ _ _ _ ) = vec4 a10 a11 a12 a13 156row1 (Matrix4 _ _ _ _ a10 a11 a12 a13 _ _ _ _ _ _ _ _ ) = vec4 a10 a11 a12 a13
157row2 (Matrix4 _ _ _ _ _ _ _ _ a20 a21 a22 a23 _ _ _ _ ) = vec4 a20 a21 a22 a23 157row2 (Matrix4 _ _ _ _ _ _ _ _ a20 a21 a22 a23 _ _ _ _ ) = vec4 a20 a21 a22 a23
158row3 (Matrix4 _ _ _ _ _ _ _ _ _ _ _ _ a30 a31 a32 a33) = vec4 a30 a31 a32 a33 158row3 (Matrix4 _ _ _ _ _ _ _ _ _ _ _ _ a30 a31 a32 a33) = vec4 a30 a31 a32 a33
159 159
160 160
161right (Matrix4 a00 _ _ _ a01 _ _ _ a02 _ _ _ _ _ _ _) = vec3 a00 a01 a02 161right (Matrix4 a00 _ _ _ a01 _ _ _ a02 _ _ _ _ _ _ _) = vec3 a00 a01 a02
162up (Matrix4 _ a10 _ _ _ a11 _ _ _ a12 _ _ _ _ _ _) = vec3 a10 a11 a12 162up (Matrix4 _ a10 _ _ _ a11 _ _ _ a12 _ _ _ _ _ _) = vec3 a10 a11 a12
163forward (Matrix4 _ _ a20 _ _ _ a21 _ _ _ a22 _ _ _ _ _) = vec3 a20 a21 a22 163forward (Matrix4 _ _ a20 _ _ _ a21 _ _ _ a22 _ _ _ _ _) = vec3 a20 a21 a22
164position (Matrix4 _ _ _ a30 _ _ _ a31 _ _ _ a32 _ _ _ _) = vec3 a30 a31 a32 164position (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.
168mat4 = Matrix4 168mat4 = Matrix4
169 169
170 170
171-- | Build a matrix from four vectors in 4D. 171-- | Build a matrix from four vectors in 4D.
172mat4fromVec :: Vector4 -> Vector4 -> Vector4 -> Vector4 -> Matrix4 172mat4fromVec :: Vector4 -> Vector4 -> Vector4 -> Vector4 -> Matrix4
173mat4fromVec v0 v1 v2 v3 = Matrix4 173mat4fromVec 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.
181transform :: Vector3 -- ^ Right vector. 181transform :: 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
187transform right up fwd pos = mat4 187transform 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.
236zipWith :: (Float -> Float -> Float) -> Matrix4 -> Matrix4 -> Matrix4 236zipWith :: (Float -> Float -> Float) -> Matrix4 -> Matrix4 -> Matrix4
237zipWith f a b = Matrix4 237zipWith 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.
245map :: (Float -> Float) -> Matrix4 -> Matrix4 245map :: (Float -> Float) -> Matrix4 -> Matrix4
246map f m = Matrix4 246map 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.
254id :: Matrix4 254id :: Matrix4
255id = mat4 255id = 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.
263transl :: Float -> Float -> Float -> Matrix4 263transl :: Float -> Float -> Float -> Matrix4
264transl x y z = mat4 264transl 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.
272translv :: Vector3 -> Matrix4 272translv :: Vector3 -> Matrix4
273translv v = mat4 273translv 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.
282rotX :: Float -> Matrix4 282rotX :: Float -> Matrix4
283rotX angle = mat4 283rotX 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.
295rotY :: Float -> Matrix4 295rotY :: Float -> Matrix4
296rotY angle = mat4 296rotY 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.
308rotZ :: Float -> Matrix4 308rotZ :: Float -> Matrix4
309rotZ angle = mat4 309rotZ 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.
321axisAngle :: Vector3 -> Float -> Matrix4 321axisAngle :: Vector3 -> Float -> Matrix4
322axisAngle v angle = mat4 322axisAngle 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.
343scale :: Float -> Float -> Float -> Matrix4 343scale :: Float -> Float -> Float -> Matrix4
344scale sx sy sz = mat4 344scale 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.
352scalev :: Vector3 -> Matrix4 352scalev :: Vector3 -> Matrix4
353scalev v = mat4 353scalev 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.
365reflectX :: Matrix4 365reflectX :: Matrix4
366reflectX = mat4 366reflectX = 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.
374reflectY :: Matrix4 374reflectY :: Matrix4
375reflectY = mat4 375reflectY = 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.
383reflectZ :: Matrix4 383reflectZ :: Matrix4
384reflectZ = mat4 384reflectZ = 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.
392ortho :: Float -- ^ Left. 392ortho :: 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
400ortho l r b t n f = 400ortho 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.
412perspective :: Float -- ^ Fovy - Vertical field of view angle in degrees. 412perspective :: 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
417perspective fovy r near far = 417perspective 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.
448transpose :: Matrix4 -> Matrix4 448transpose :: Matrix4 -> Matrix4
449transpose m = mat4 449transpose 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.
457inverseTransform :: Matrix4 -> Matrix4 457inverseTransform :: Matrix4 -> Matrix4
458inverseTransform mat = 458inverseTransform 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.
618mul :: Float -> Matrix4 -> Vector3 -> Vector3 618mul :: Float -> Matrix4 -> Vector3 -> Vector3
619mul w m v = vec3 x' y' z' 619mul 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.
628mulp :: Matrix4 -> Vector3 -> Vector3 628mulp :: Matrix4 -> Vector3 -> Vector3
629mulp = mul 1 629mulp = 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.
633muld :: Matrix4 -> Vector3 -> Vector3 633muld :: Matrix4 -> Vector3 -> Vector3
634muld = mul 0 634muld = 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.
641mul' :: Float -> Matrix4 -> Vector3 -> Vector3 641mul' :: Float -> Matrix4 -> Vector3 -> Vector3
642mul' w m v = vec3 (x'/w') (y'/w') (z'/w') 642mul' 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
651toRAD = (*pi) . (/180) 651toRAD = (*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
7where 7where
8 8
9 9
10import Spear.Math.Vector3 as Vector 10import Spear.Math.Vector3
11 11
12 12
13data PointPlanePos = Front | Back | Contained deriving (Eq, Ord, Show) 13data 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 @@
1module Spear.Math.Vector2 1module 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)
24where 22where
25 23
26import Foreign.C.Types (CFloat) 24
27import Foreign.Storable 25import Foreign.C.Types (CFloat)
28 26import Foreign.Storable
29 27
30-- | Represents a vector in 2D. 28
31data Vector2 = Vector2 {-# UNPACK #-} !Float {-# UNPACK #-} !Float deriving (Eq, Show) 29-- | Represents a vector in 2D.
32 30data Vector2 = Vector2 {-# UNPACK #-} !Float {-# UNPACK #-} !Float deriving (Eq, Show)
33 31
34instance Num Vector2 where 32
35 Vector2 ax ay + Vector2 bx by = Vector2 (ax + bx) (ay + by) 33instance 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
43instance Fractional Vector2 where 41
44 Vector2 ax ay / Vector2 bx by = Vector2 (ax / bx) (ay / by) 42instance 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
48instance Ord Vector2 where 46
49 Vector2 ax ay <= Vector2 bx by = (ax <= bx) || (ax == bx && ay <= by) 47instance 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)
55sizeFloat = sizeOf (undefined :: CFloat) 53 min (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.min ax bx) (Prelude.min ay by)
56 54
57 55
58instance Storable Vector2 where 56sizeFloat = sizeOf (undefined :: CFloat)
59 sizeOf _ = 2*sizeFloat 57
60 alignment _ = alignment (undefined :: CFloat) 58
61 59instance 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.
73x (Vector2 ax _) = ax 74x (Vector2 ax _) = ax
74 75
75 76
76-- | Get the vector's y coordinate. 77-- | Get the vector's y coordinate.
77y (Vector2 _ ay) = ay 78y (Vector2 _ ay) = ay
78 79
79 80
80-- | Unit vector along the X axis. 81-- | Unit vector along the X axis.
81unitx :: Vector2 82unitx :: Vector2
82unitx = Vector2 1 0 83unitx = Vector2 1 0
83 84
84 85
85-- | Unit vector along the Y axis. 86-- | Unit vector along the Y axis.
86unity :: Vector2 87unity :: Vector2
87unity = Vector2 0 1 88unity = Vector2 0 1
88 89
89 90
90-- | Zero vector. 91-- | Zero vector.
91zero :: Vector2 92zero :: Vector2
92zero = Vector2 0 0 93zero = Vector2 0 0
93 94
94 95
95-- | Create a vector from the given list. 96-- | Create a vector from the given list.
96fromList :: [Float] -> Vector2 97fromList :: [Float] -> Vector2
97fromList (ax:ay:_) = Vector2 ax ay 98fromList (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.
101vec2 :: Float -> Float -> Vector2 102vec2 :: Float -> Float -> Vector2
102vec2 ax ay = Vector2 ax ay 103vec2 ax ay = Vector2 ax ay
103
104
105-- | Create a vector with components set to the minimum of each of the given vectors'.
106v2min :: Vector2 -> Vector2 -> Vector2
107v2min (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'.
111v2max :: Vector2 -> Vector2 -> Vector2
112v2max (Vector2 ax ay) (Vector2 bx by) = Vector2 (Prelude.max ax bx) (Prelude.max ay by)
113
114
115-- | Compute the given vectors' dot product.
116dot :: Vector2 -> Vector2 -> Float
117Vector2 ax ay `dot` Vector2 bx by = ax*bx + ay*by
118
119
120-- | Compute the given vector's squared norm.
121normSq :: Vector2 -> Float
122normSq (Vector2 ax ay) = ax*ax + ay*ay
123
124
125-- | Compute the given vector's norm.
126norm :: Vector2 -> Float
127norm = sqrt . normSq
128
129
130-- | Multiply the given vector with the given scalar.
131scale :: Float -> Vector2 -> Vector2
132scale s (Vector2 ax ay) = Vector2 (s*ax) (s*ay)
133
134
135-- | Normalise the given vector.
136normalise :: Vector2 -> Vector2
137normalise 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.
145neg :: Vector2 -> Vector2
146neg (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)
154perp :: Vector2 -> Vector2 111perp :: Vector2 -> Vector2
155perp (Vector2 x y) = Vector2 y (-x) 112perp (Vector2 x y) = Vector2 y (-x)
113
114
115-- | Compute the given vectors' dot product.
116dot :: Vector2 -> Vector2 -> Float
117Vector2 ax ay `dot` Vector2 bx by = ax*bx + ay*by
118
119
120-- | Compute the given vector's squared norm.
121normSq :: Vector2 -> Float
122normSq (Vector2 ax ay) = ax*ax + ay*ay
123
124
125-- | Compute the given vector's norm.
126norm :: Vector2 -> Float
127norm = sqrt . normSq
128
129
130-- | Multiply the given vector with the given scalar.
131scale :: Float -> Vector2 -> Vector2
132scale s (Vector2 ax ay) = Vector2 (s*ax) (s*ay)
133
134
135-- | Negate the given vector.
136neg :: Vector2 -> Vector2
137neg (Vector2 ax ay) = Vector2 (-ax) (-ay)
138
139
140-- | Normalise the given vector.
141normalise :: Vector2 -> Vector2
142normalise 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)
27where 25where
28 26
27
29import Foreign.C.Types (CFloat) 28import Foreign.C.Types (CFloat)
30import Foreign.Storable 29import 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
77sizeFloat = sizeOf (undefined :: CFloat) 80sizeFloat = 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'.
153min :: Vector3 -> Vector3 -> Vector3
154min (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'.
158max :: Vector3 -> Vector3 -> Vector3
159max (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.
163dot :: Vector3 -> Vector3 -> Float 156dot :: Vector3 -> Vector3 -> Float
164Vector3 ax ay az `dot` Vector3 bx by bz = ax*bx + ay*by + az*bz 157Vector3 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.
174normSq :: Vector3 -> Float
175normSq (Vector3 ax ay az) = ax*ax + ay*ay + az*az 167normSq (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.
179norm :: Vector3 -> Float
180norm = sqrt . normSq 171norm = sqrt . normSq
181 172
182 173
183-- | Multiply the given vector with the given scalar. 174-- | Multiply the given vector with the given scalar.
184scale :: Float -> Vector3 -> Vector3
185scale s (Vector3 ax ay az) = Vector3 (s*ax) (s*ay) (s*az) 175scale s (Vector3 ax ay az) = Vector3 (s*ax) (s*ay) (s*az)
186 176
187 177
178-- | Negate the given vector.
179neg (Vector3 ax ay az) = Vector3 (-ax) (-ay) (-az)
180
181
188-- | Normalise the given vector. 182-- | Normalise the given vector.
189normalise :: Vector3 -> Vector3
190normalise v = 183normalise 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.
198neg :: Vector3 -> Vector3
199neg (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 @@
1module Spear.Math.Vector4 1module 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 23where
24) 24
25where 25
26 26import Foreign.C.Types (CFloat)
27 27import Foreign.Storable
28import Foreign.C.Types (CFloat) 28
29import Foreign.Storable 29
30 30-- | Represents a vector in 3D.
31
32-- | Represents a vector in 3D.
33data Vector4 = Vector4 31data 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
41instance Num Vector4 where 39instance 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
50instance Fractional Vector4 where 48instance 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
55instance Ord Vector4 where 53instance 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) =
81sizeFloat = 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) =
84instance 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 85sizeFloat = sizeOf (undefined :: CFloat)
88 peek ptr = do 86
89 ax <- peekByteOff ptr 0 87
90 ay <- peekByteOff ptr $ 1 * sizeFloat 88instance 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
102x (Vector4 ax _ _ _ ) = ax 100 pokeByteOff ptr 0 ax
103y (Vector4 _ ay _ _ ) = ay 101 pokeByteOff ptr (1 * sizeFloat) ay
104z (Vector4 _ _ az _ ) = az 102 pokeByteOff ptr (2 * sizeFloat) az
105w (Vector4 _ _ _ aw) = aw 103 pokeByteOff ptr (3 * sizeFloat) aw
106 104
107 105
108-- | Unit vector along the X axis. 106x (Vector4 ax _ _ _ ) = ax
109unitX :: Vector4 107y (Vector4 _ ay _ _ ) = ay
110unitX = Vector4 1 0 0 0 108z (Vector4 _ _ az _ ) = az
111 109w (Vector4 _ _ _ aw) = aw
112 110
113-- | Unit vector along the Y axis. 111
114unitY :: Vector4 112-- | Unit vector along the X axis.
115unitY = Vector4 0 1 0 0 113unitX :: Vector4
116 114unitX = Vector4 1 0 0 0
117 115
118-- | Unit vector along the Z axis. 116
119unitZ :: Vector4 117-- | Unit vector along the Y axis.
120unitZ = Vector4 0 0 1 0 118unitY :: Vector4
121 119unitY = Vector4 0 1 0 0
122 120
123-- | Create a vector from the given list. 121
124fromList :: [Float] -> Vector4 122-- | Unit vector along the Z axis.
125fromList (ax:ay:az:aw:_) = Vector4 ax ay az aw 123unitZ :: Vector4
126 124unitZ = Vector4 0 0 1 0
127 125
128-- | Create a 4D vector from the given values. 126
129vec4 :: Float -> Float -> Float -> Float -> Vector4 127-- | Create a vector from the given list.
130vec4 ax ay az aw = Vector4 ax ay az aw 128fromList :: [Float] -> Vector4
131 129fromList (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
134min :: Vector4 -> Vector4 -> Vector4 132-- | Create a 4D vector from the given values.
135min (Vector4 ax ay az aw) (Vector4 bx by bz bw) = 133vec4 :: Float -> Float -> Float -> Float -> Vector4
136 Vector4 (Prelude.min ax bx) (Prelude.min ay by) (Prelude.min az bz) (Prelude.min aw bw) 134vec4 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.
140max :: Vector4 -> Vector4 -> Vector4 138dot :: Vector4 -> Vector4 -> Float
141max (Vector4 ax ay az aw) (Vector4 bx by bz bw) = 139Vector4 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.
146dot :: Vector4 -> Vector4 -> Float 144cross :: Vector4 -> Vector4 -> Vector4
147Vector4 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.
152cross :: Vector4 -> Vector4 -> Vector4 150normSq :: Vector4 -> Float
153(Vector4 ax ay az _) `cross` (Vector4 bx by bz _) = 151normSq (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. 155norm :: Vector4 -> Float
158normSq :: Vector4 -> Float 156norm = sqrt . normSq
159normSq (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. 160scale :: Float -> Vector4 -> Vector4
163norm :: Vector4 -> Float 161scale s (Vector4 ax ay az aw) = Vector4 (s*ax) (s*ay) (s*az) (s*aw)
164norm = sqrt . normSq 162
165 163
166 164-- | Negate the given vector.
167-- | Multiply the given vector with the given scalar. 165neg :: Vector4 -> Vector4
168scale :: Float -> Vector4 -> Vector4 166neg (Vector4 ax ay az aw) = Vector4 (-ax) (-ay) (-az) (-aw)
169scale 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. 170normalise :: Vector4 -> Vector4
173normalise :: Vector4 -> Vector4 171normalise v =
174normalise 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.
182neg :: Vector4 -> Vector4
183neg (Vector4 ax ay az aw) = Vector4 (-ax) (-ay) (-az) (-aw)