diff options
author | Jeanne-Kamikaze <jeannekamikaze@gmail.com> | 2013-02-21 13:15:55 +0100 |
---|---|---|
committer | Jeanne-Kamikaze <jeannekamikaze@gmail.com> | 2013-02-21 13:15:55 +0100 |
commit | 44a2fc13f57454ed54223d028e287e053609971a (patch) | |
tree | 3ac931da2ad506c3f1cdf740a79a71ac404e40d4 | |
parent | 4919114716a7f170389a70ef95bcc60e8d7f8861 (diff) |
Made vector min/max part of Ord instance
-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) | ||