Rev 784 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 782 | chris | 1 | using System; |
| 2 | using System.Collections.Generic; |
||
| 3 | using System.Linq; |
||
| 4 | using System.Text; |
||
| 5 | using System.Threading.Tasks; |
||
| 6 | |||
| 7 | namespace BauzoidNET.math |
||
| 8 | { |
||
| 787 | chris | 9 | public class Matrix4 |
| 782 | chris | 10 | { |
| 784 | chris | 11 | public const int M11 = 0; |
| 12 | public const int M21 = 1; |
||
| 13 | public const int M31 = 2; |
||
| 14 | public const int M41 = 3; |
||
| 15 | public const int M12 = 4; |
||
| 16 | public const int M22 = 5; |
||
| 17 | public const int M32 = 6; |
||
| 18 | public const int M42 = 7; |
||
| 19 | public const int M13 = 8; |
||
| 20 | public const int M23 = 9; |
||
| 21 | public const int M33 = 10; |
||
| 22 | public const int M43 = 11; |
||
| 23 | public const int M14 = 12; |
||
| 24 | public const int M24 = 13; |
||
| 25 | public const int M34 = 14; |
||
| 26 | public const int M44 = 15; |
||
| 782 | chris | 27 | |
| 784 | chris | 28 | public const int MATRIX_SIZE = 4; |
| 782 | chris | 29 | |
| 30 | public float[] values = new float[MATRIX_SIZE*MATRIX_SIZE]; |
||
| 31 | |||
| 32 | public Matrix4() |
||
| 33 | { |
||
| 34 | } |
||
| 35 | |||
| 36 | /** Copy constructor. */ |
||
| 37 | public Matrix4(Matrix4 b) |
||
| 38 | { |
||
| 39 | for (int i = 0; i < values.Length; i++) |
||
| 40 | this.values[i] = b.values[i]; |
||
| 41 | } |
||
| 42 | |||
| 43 | public Matrix4(float[] m) |
||
| 44 | { |
||
| 45 | for (int i = 0; i < values.Length; i++) |
||
| 46 | this.values[i] = m[i]; |
||
| 47 | } |
||
| 48 | |||
| 49 | public float get(int row, int col) |
||
| 50 | { |
||
| 51 | return values[col*MATRIX_SIZE + row]; |
||
| 52 | } |
||
| 53 | |||
| 54 | public void set(int row, int col, float value) |
||
| 55 | { |
||
| 56 | values[col*MATRIX_SIZE + row] = value; |
||
| 57 | } |
||
| 58 | |||
| 59 | public void zero() |
||
| 60 | { |
||
| 61 | for (int i = 0; i < values.Length; i++) |
||
| 62 | values[i] = 0.0f; |
||
| 63 | } |
||
| 64 | |||
| 65 | public void identity() |
||
| 66 | { |
||
| 67 | zero(); |
||
| 68 | values[M11] = 1.0f; values[M22] = 1.0f; values[M33] = 1.0f; values[M44] = 1.0f; |
||
| 69 | } |
||
| 70 | |||
| 71 | public bool equals(Matrix4 other) |
||
| 72 | { |
||
| 73 | for (int i = 0; i < values.Length; i++) |
||
| 74 | { |
||
| 75 | if (this.values[i] != other.values[i]) |
||
| 76 | return false; |
||
| 77 | } |
||
| 78 | return true; |
||
| 79 | } |
||
| 80 | |||
| 81 | public bool isSingular() |
||
| 82 | { |
||
| 83 | float determinant = getDeterminant(); |
||
| 84 | return ((float)Math.Abs(determinant) < MathUtil.EPSILON); |
||
| 85 | } |
||
| 86 | |||
| 87 | public Matrix4 getTranspose() |
||
| 88 | { |
||
| 89 | Matrix4 result = new Matrix4(); |
||
| 90 | |||
| 91 | for (int row = 0; row < MATRIX_SIZE; row++) |
||
| 92 | { |
||
| 93 | for (int col = 0; col < MATRIX_SIZE; col++) |
||
| 94 | { |
||
| 95 | float v = this.get(row, col); |
||
| 96 | this.set(col, row, v); |
||
| 97 | } |
||
| 98 | } |
||
| 99 | |||
| 100 | return result; |
||
| 101 | } |
||
| 102 | |||
| 103 | public float getDeterminant() |
||
| 104 | { |
||
| 105 | |||
| 106 | float result = |
||
| 107 | values[M14] * values[M23] * values[M32] * values[M41] - |
||
| 108 | values[M13] * values[M24] * values[M32] * values[M41] - |
||
| 109 | values[M14] * values[M22] * values[M33] * values[M41] + |
||
| 110 | values[M12] * values[M24] * values[M33] * values[M41] + |
||
| 111 | values[M13] * values[M22] * values[M34] * values[M41] - |
||
| 112 | values[M12] * values[M23] * values[M34] * values[M41] - |
||
| 113 | values[M14] * values[M23] * values[M31] * values[M42] + |
||
| 114 | values[M13] * values[M24] * values[M31] * values[M42] + |
||
| 115 | values[M14] * values[M21] * values[M33] * values[M42] - |
||
| 116 | values[M11] * values[M24] * values[M33] * values[M42] - |
||
| 117 | values[M13] * values[M21] * values[M34] * values[M42] + |
||
| 118 | values[M11] * values[M23] * values[M34] * values[M42] + |
||
| 119 | values[M14] * values[M22] * values[M31] * values[M43] - |
||
| 120 | values[M12] * values[M24] * values[M31] * values[M43] - |
||
| 121 | values[M14] * values[M21] * values[M32] * values[M43] + |
||
| 122 | values[M11] * values[M24] * values[M32] * values[M43] + |
||
| 123 | values[M12] * values[M21] * values[M34] * values[M43] - |
||
| 124 | values[M11] * values[M22] * values[M34] * values[M43] - |
||
| 125 | values[M13] * values[M22] * values[M31] * values[M44] + |
||
| 126 | values[M12] * values[M23] * values[M31] * values[M44] + |
||
| 127 | values[M13] * values[M21] * values[M32] * values[M44] - |
||
| 128 | values[M11] * values[M23] * values[M32] * values[M44] - |
||
| 129 | values[M12] * values[M21] * values[M33] * values[M44] + |
||
| 130 | values[M11] * values[M22] * values[M33] * values[M44]; |
||
| 131 | return result; |
||
| 132 | } |
||
| 133 | |||
| 134 | public Matrix4 getInverse() |
||
| 135 | { |
||
| 136 | Matrix4 result = new Matrix4(); |
||
| 137 | |||
| 138 | float determinant = getDeterminant(); |
||
| 139 | if (determinant == 0.0f) |
||
| 140 | { |
||
| 141 | // singular matrix cannot be inverted |
||
| 142 | return this; |
||
| 143 | } |
||
| 144 | |||
| 145 | result.values[M11] = values[M23] * values[M34] * values[M42] |
||
| 146 | - values[M24] * values[M33] * values[M42] |
||
| 147 | + values[M24] * values[M32] * values[M43] |
||
| 148 | - values[M22] * values[M34] * values[M43] |
||
| 149 | - values[M23] * values[M32] * values[M44] |
||
| 150 | + values[M22] * values[M33] * values[M44]; |
||
| 151 | result.values[M12] = values[M14] * values[M33] * values[M42] |
||
| 152 | - values[M13] * values[M34] * values[M42] |
||
| 153 | - values[M14] * values[M32] * values[M43] |
||
| 154 | + values[M12] * values[M34] * values[M43] |
||
| 155 | + values[M13] * values[M32] * values[M44] |
||
| 156 | - values[M12] * values[M33] * values[M44]; |
||
| 157 | result.values[M13] = values[M13] * values[M24] * values[M42] |
||
| 158 | - values[M14] * values[M23] * values[M42] |
||
| 159 | + values[M14] * values[M22] * values[M43] |
||
| 160 | - values[M12] * values[M24] * values[M43] |
||
| 161 | - values[M13] * values[M22] * values[M44] |
||
| 162 | + values[M12] * values[M23] * values[M44]; |
||
| 163 | result.values[M14] = values[M14] * values[M23] * values[M32] |
||
| 164 | - values[M13] * values[M24] * values[M32] |
||
| 165 | - values[M14] * values[M22] * values[M33] |
||
| 166 | + values[M12] * values[M24] * values[M33] |
||
| 167 | + values[M13] * values[M22] * values[M34] |
||
| 168 | - values[M12] * values[M23] * values[M34]; |
||
| 169 | result.values[M21] = values[M24] * values[M33] * values[M41] |
||
| 170 | - values[M23] * values[M34] * values[M41] |
||
| 171 | - values[M24] * values[M31] * values[M43] |
||
| 172 | + values[M21] * values[M34] * values[M43] |
||
| 173 | + values[M23] * values[M31] * values[M44] |
||
| 174 | - values[M21] * values[M33] * values[M44]; |
||
| 175 | result.values[M22] = values[M13] * values[M34] * values[M41] |
||
| 176 | - values[M14] * values[M33] * values[M41] |
||
| 177 | + values[M14] * values[M31] * values[M43] |
||
| 178 | - values[M11] * values[M34] * values[M43] |
||
| 179 | - values[M13] * values[M31] * values[M44] |
||
| 180 | + values[M11] * values[M33] * values[M44]; |
||
| 181 | result.values[M23] = values[M14] * values[M23] * values[M41] |
||
| 182 | - values[M13] * values[M24] * values[M41] |
||
| 183 | - values[M14] * values[M21] * values[M43] |
||
| 184 | + values[M11] * values[M24] * values[M43] |
||
| 185 | + values[M13] * values[M21] * values[M44] |
||
| 186 | - values[M11] * values[M23] * values[M44]; |
||
| 187 | result.values[M24] = values[M13] * values[M24] * values[M31] |
||
| 188 | - values[M14] * values[M23] * values[M31] |
||
| 189 | + values[M14] * values[M21] * values[M33] |
||
| 190 | - values[M11] * values[M24] * values[M33] |
||
| 191 | - values[M13] * values[M21] * values[M34] |
||
| 192 | + values[M11] * values[M23] * values[M34]; |
||
| 193 | result.values[M31] = values[M22] * values[M34] * values[M41] |
||
| 194 | - values[M24] * values[M32] * values[M41] |
||
| 195 | + values[M24] * values[M31] * values[M42] |
||
| 196 | - values[M21] * values[M34] * values[M42] |
||
| 197 | - values[M22] * values[M31] * values[M44] |
||
| 198 | + values[M21] * values[M32] * values[M44]; |
||
| 199 | result.values[M32] = values[M14] * values[M32] * values[M41] |
||
| 200 | - values[M12] * values[M34] * values[M41] |
||
| 201 | - values[M14] * values[M31] * values[M42] |
||
| 202 | + values[M11] * values[M34] * values[M42] |
||
| 203 | + values[M12] * values[M31] * values[M44] |
||
| 204 | - values[M11] * values[M32] * values[M44]; |
||
| 205 | result.values[M33] = values[M12] * values[M24] * values[M41] |
||
| 206 | - values[M14] * values[M22] * values[M41] |
||
| 207 | + values[M14] * values[M21] * values[M42] |
||
| 208 | - values[M11] * values[M24] * values[M42] |
||
| 209 | - values[M12] * values[M21] * values[M44] |
||
| 210 | + values[M11] * values[M22] * values[M44]; |
||
| 211 | result.values[M34] = values[M14] * values[M22] * values[M31] |
||
| 212 | - values[M12] * values[M24] * values[M31] |
||
| 213 | - values[M14] * values[M21] * values[M32] |
||
| 214 | + values[M11] * values[M24] * values[M32] |
||
| 215 | + values[M12] * values[M21] * values[M34] |
||
| 216 | - values[M11] * values[M22] * values[M34]; |
||
| 217 | result.values[M41] = values[M23] * values[M32] * values[M41] |
||
| 218 | - values[M22] * values[M33] * values[M41] |
||
| 219 | - values[M23] * values[M31] * values[M42] |
||
| 220 | + values[M21] * values[M33] * values[M42] |
||
| 221 | + values[M22] * values[M31] * values[M43] |
||
| 222 | - values[M21] * values[M32] * values[M43]; |
||
| 223 | result.values[M42] = values[M12] * values[M33] * values[M41] |
||
| 224 | - values[M13] * values[M32] * values[M41] |
||
| 225 | + values[M13] * values[M31] * values[M42] |
||
| 226 | - values[M11] * values[M33] * values[M42] |
||
| 227 | - values[M12] * values[M31] * values[M43] |
||
| 228 | + values[M11] * values[M32] * values[M43]; |
||
| 229 | result.values[M43] = values[M13] * values[M22] * values[M41] |
||
| 230 | - values[M12] * values[M23] * values[M41] |
||
| 231 | - values[M13] * values[M21] * values[M42] |
||
| 232 | + values[M11] * values[M23] * values[M42] |
||
| 233 | + values[M12] * values[M21] * values[M43] |
||
| 234 | - values[M11] * values[M22] * values[M43]; |
||
| 235 | result.values[M44] = values[M12] * values[M23] * values[M31] |
||
| 236 | - values[M13] * values[M22] * values[M31] |
||
| 237 | + values[M13] * values[M21] * values[M32] |
||
| 238 | - values[M11] * values[M23] * values[M32] |
||
| 239 | - values[M12] * values[M21] * values[M33] |
||
| 240 | + values[M11] * values[M22] * values[M33]; |
||
| 241 | |||
| 242 | float multiply = 1.0f / determinant; |
||
| 243 | |||
| 244 | for (int i = 0; i < values.Length; i++) |
||
| 245 | result.values[i] *= multiply; |
||
| 246 | |||
| 247 | return result; |
||
| 248 | } |
||
| 249 | |||
| 250 | public void copyTo(Matrix4 target) |
||
| 251 | { |
||
| 252 | for (int i = 0; i < values.Length; i++) |
||
| 253 | target.values[i] = this.values[i]; |
||
| 254 | } |
||
| 255 | |||
| 256 | public void copyFrom(Matrix4 source) |
||
| 257 | { |
||
| 258 | for (int i = 0; i < values.Length; i++) |
||
| 259 | this.values[i] = source.values[i]; |
||
| 260 | } |
||
| 261 | |||
| 262 | public void postMultiply(Matrix4 v) |
||
| 263 | { |
||
| 264 | multiply(this, this, v); |
||
| 265 | } |
||
| 266 | |||
| 267 | public void preMultiply(Matrix4 v) |
||
| 268 | { |
||
| 269 | multiply(this, v, this); |
||
| 270 | } |
||
| 271 | |||
| 272 | static public void multiply(Matrix4 result, Matrix4 a, Matrix4 b) |
||
| 273 | { |
||
| 274 | float result11 = a.values[M11] * b.values[M11] + a.values[M21] * b.values[M12] + a.values[M31] * b.values[M13] + a.values[M41] * b.values[M14]; |
||
| 275 | float result21 = a.values[M11] * b.values[M21] + a.values[M21] * b.values[M22] + a.values[M31] * b.values[M23] + a.values[M41] * b.values[M24]; |
||
| 276 | float result31 = a.values[M11] * b.values[M31] + a.values[M21] * b.values[M32] + a.values[M31] * b.values[M33] + a.values[M41] * b.values[M34]; |
||
| 277 | float result41 = a.values[M11] * b.values[M41] + a.values[M21] * b.values[M42] + a.values[M31] * b.values[M43] + a.values[M41] * b.values[M44]; |
||
| 278 | float result12 = a.values[M12] * b.values[M11] + a.values[M22] * b.values[M12] + a.values[M32] * b.values[M13] + a.values[M42] * b.values[M14]; |
||
| 279 | float result22 = a.values[M12] * b.values[M21] + a.values[M22] * b.values[M22] + a.values[M32] * b.values[M23] + a.values[M42] * b.values[M24]; |
||
| 280 | float result32 = a.values[M12] * b.values[M31] + a.values[M22] * b.values[M32] + a.values[M32] * b.values[M33] + a.values[M42] * b.values[M34]; |
||
| 281 | float result42 = a.values[M12] * b.values[M41] + a.values[M22] * b.values[M42] + a.values[M32] * b.values[M43] + a.values[M42] * b.values[M44]; |
||
| 282 | float result13 = a.values[M13] * b.values[M11] + a.values[M23] * b.values[M12] + a.values[M33] * b.values[M13] + a.values[M43] * b.values[M14]; |
||
| 283 | float result23 = a.values[M13] * b.values[M21] + a.values[M23] * b.values[M22] + a.values[M33] * b.values[M23] + a.values[M43] * b.values[M24]; |
||
| 284 | float result33 = a.values[M13] * b.values[M31] + a.values[M23] * b.values[M32] + a.values[M33] * b.values[M33] + a.values[M43] * b.values[M34]; |
||
| 285 | float result43 = a.values[M13] * b.values[M41] + a.values[M23] * b.values[M42] + a.values[M33] * b.values[M43] + a.values[M43] * b.values[M44]; |
||
| 286 | float result14 = a.values[M14] * b.values[M11] + a.values[M24] * b.values[M12] + a.values[M34] * b.values[M13] + a.values[M44] * b.values[M14]; |
||
| 287 | float result24 = a.values[M14] * b.values[M21] + a.values[M24] * b.values[M22] + a.values[M34] * b.values[M23] + a.values[M44] * b.values[M24]; |
||
| 288 | float result34 = a.values[M14] * b.values[M31] + a.values[M24] * b.values[M32] + a.values[M34] * b.values[M33] + a.values[M44] * b.values[M34]; |
||
| 289 | float result44 = a.values[M14] * b.values[M41] + a.values[M24] * b.values[M42] + a.values[M34] * b.values[M43] + a.values[M44] * b.values[M44]; |
||
| 290 | result.values[M11] = result11; |
||
| 291 | result.values[M21] = result21; |
||
| 292 | result.values[M31] = result31; |
||
| 293 | result.values[M41] = result41; |
||
| 294 | result.values[M12] = result12; |
||
| 295 | result.values[M22] = result22; |
||
| 296 | result.values[M32] = result32; |
||
| 297 | result.values[M42] = result42; |
||
| 298 | result.values[M13] = result13; |
||
| 299 | result.values[M23] = result23; |
||
| 300 | result.values[M33] = result33; |
||
| 301 | result.values[M43] = result43; |
||
| 302 | result.values[M14] = result14; |
||
| 303 | result.values[M24] = result24; |
||
| 304 | result.values[M34] = result34; |
||
| 305 | result.values[M44] = result44; |
||
| 306 | } |
||
| 307 | |||
| 308 | static public Matrix4 multiply(Matrix4 a, Matrix4 b) |
||
| 309 | { |
||
| 310 | Matrix4 result = new Matrix4(); |
||
| 311 | multiply(result, a, b); |
||
| 312 | return result; |
||
| 313 | } |
||
| 314 | |||
| 315 | public void multiply(Matrix4 other) |
||
| 316 | { |
||
| 317 | Matrix4.multiply(this, this, other); |
||
| 318 | } |
||
| 319 | |||
| 320 | static public Matrix4 createIdentity() |
||
| 321 | { |
||
| 322 | return createScale(1.0f, 1.0f, 1.0f); |
||
| 323 | } |
||
| 324 | |||
| 325 | static public Matrix4 createScale(float sx, float sy, float sz) |
||
| 326 | { |
||
| 327 | Matrix4 result = new Matrix4(); |
||
| 328 | result.setScale(sx, sy, sz); |
||
| 329 | return result; |
||
| 330 | } |
||
| 331 | |||
| 332 | static public Matrix4 createScale(Vector3 scale) |
||
| 333 | { |
||
| 334 | return createScale(scale.x, scale.y, scale.z); |
||
| 335 | } |
||
| 336 | |||
| 337 | static public Matrix4 createScale(float s) |
||
| 338 | { |
||
| 339 | return createScale(s, s, s); |
||
| 340 | } |
||
| 341 | |||
| 342 | public void setScale(float sx, float sy, float sz) |
||
| 343 | { |
||
| 344 | zero(); |
||
| 345 | this.values[M11] = sx; |
||
| 346 | this.values[M22] = sy; |
||
| 347 | this.values[M33] = sz; |
||
| 348 | this.values[M44] = 1.0f; |
||
| 349 | } |
||
| 350 | |||
| 351 | public void setScale(Vector3 scale) |
||
| 352 | { |
||
| 353 | setScale(scale.x, scale.y, scale.z); |
||
| 354 | } |
||
| 355 | |||
| 356 | public void setScale(float s) |
||
| 357 | { |
||
| 358 | setScale(s, s, s); |
||
| 359 | } |
||
| 360 | |||
| 361 | static public Matrix4 createRotationX(float degrees) |
||
| 362 | { |
||
| 363 | Matrix4 matrix = new Matrix4(); |
||
| 364 | matrix.setRotationX(degrees); |
||
| 365 | return matrix; |
||
| 366 | } |
||
| 367 | |||
| 368 | public void setRotationX(float degrees) |
||
| 369 | { |
||
| 370 | float degreesrad = MathUtil.degToRad(degrees); |
||
| 371 | float sinvalue = (float)Math.Sin(degreesrad); |
||
| 372 | float cosvalue = (float)Math.Cos(degreesrad); |
||
| 373 | |||
| 374 | this.identity(); |
||
| 375 | this.values[M22] = cosvalue; |
||
| 376 | this.values[M32] = -sinvalue; |
||
| 377 | this.values[M23] = sinvalue; |
||
| 378 | this.values[M33] = cosvalue; |
||
| 379 | } |
||
| 380 | |||
| 381 | static public Matrix4 createRotationY(float degrees) |
||
| 382 | { |
||
| 383 | Matrix4 matrix = new Matrix4(); |
||
| 384 | matrix.setRotationY(degrees); |
||
| 385 | return matrix; |
||
| 386 | } |
||
| 387 | |||
| 388 | public void setRotationY(float degrees) |
||
| 389 | { |
||
| 390 | float degreesrad = MathUtil.degToRad(degrees); |
||
| 391 | float sinvalue = (float)Math.Sin(degreesrad); |
||
| 392 | float cosvalue = (float)Math.Cos(degreesrad); |
||
| 393 | |||
| 394 | this.identity(); |
||
| 395 | this.values[M11] = cosvalue; |
||
| 396 | this.values[M31] = sinvalue; |
||
| 397 | this.values[M13] = -sinvalue; |
||
| 398 | this.values[M33] = cosvalue; |
||
| 399 | } |
||
| 400 | |||
| 401 | static public Matrix4 createRotationZ(float degrees) |
||
| 402 | { |
||
| 403 | Matrix4 matrix = new Matrix4(); |
||
| 404 | matrix.setRotationZ(degrees); |
||
| 405 | return matrix; |
||
| 406 | } |
||
| 407 | |||
| 408 | public void setRotationZ(float degrees) |
||
| 409 | { |
||
| 410 | float degreesrad = MathUtil.degToRad(degrees); |
||
| 411 | float sinvalue = (float)Math.Sin(degreesrad); |
||
| 412 | float cosvalue = (float)Math.Cos(degreesrad); |
||
| 413 | |||
| 414 | this.identity(); |
||
| 415 | this.values[M11] = cosvalue; |
||
| 416 | this.values[M21] = -sinvalue; |
||
| 417 | this.values[M12] = sinvalue; |
||
| 418 | this.values[M22] = cosvalue; |
||
| 419 | } |
||
| 420 | |||
| 421 | static public Matrix4 createRotation(Vector3 axis, float degrees) |
||
| 422 | { |
||
| 423 | Matrix4 matrix = new Matrix4(); |
||
| 424 | matrix.setRotation(axis, degrees); |
||
| 425 | return matrix; |
||
| 426 | } |
||
| 427 | |||
| 428 | public void setRotation(Vector3 axis, float degrees) |
||
| 429 | { |
||
| 430 | float radangle = MathUtil.degToRad(degrees); |
||
| 431 | float radcos = (float)Math.Cos(radangle); |
||
| 432 | float radsin = (float)Math.Sin(radangle); |
||
| 433 | |||
| 434 | this.identity(); |
||
| 435 | this.values[M11] = radcos + axis.x * axis.x * (1 - radcos); |
||
| 436 | this.values[M21] = axis.z * radsin + axis.y * axis.x * (1 - radcos); |
||
| 437 | this.values[M31] = -axis.y * radsin + axis.z * axis.x * (1 - radcos); |
||
| 438 | this.values[M12] = -axis.z * radsin + axis.x * axis.y * (1 - radcos); |
||
| 439 | this.values[M22] = radcos + axis.y * axis.y * (1 - radcos); |
||
| 440 | this.values[M32] = axis.x * radsin + axis.z * axis.y * (1 - radcos); |
||
| 441 | this.values[M13] = axis.y * radsin + axis.x * axis.z * (1 - radcos); |
||
| 442 | this.values[M23] = -axis.x * radsin + axis.y * axis.z * (1 - radcos); |
||
| 443 | this.values[M33] = radcos + axis.z * axis.z * (1 - radcos); |
||
| 444 | this.values[M44] = 1.0f; |
||
| 445 | } |
||
| 446 | |||
| 447 | static public Matrix4 createTranslation(float x, float y, float z) |
||
| 448 | { |
||
| 449 | Matrix4 result = new Matrix4(); |
||
| 450 | result.setTranslation(x, y, z); |
||
| 451 | return result; |
||
| 452 | } |
||
| 453 | |||
| 454 | static public Matrix4 createTranslation(Vector3 translate) |
||
| 455 | { |
||
| 456 | return createTranslation(translate.x, translate.y, translate.z); |
||
| 457 | } |
||
| 458 | |||
| 459 | public void setTranslation(float x, float y, float z) |
||
| 460 | { |
||
| 461 | this.values[M11] = 1.0f; this.values[M21] = 0.0f; this.values[M31] = 0.0f; this.values[M41] = 0.0f; |
||
| 462 | this.values[M12] = 0.0f; this.values[M22] = 1.0f; this.values[M32] = 0.0f; this.values[M42] = 0.0f; |
||
| 463 | this.values[M13] = 0.0f; this.values[M23] = 0.0f; this.values[M33] = 1.0f; this.values[M43] = 0.0f; |
||
| 464 | this.values[M14] = x; this.values[M24] = y; this.values[M34] = z; this.values[M44] = 1.0f; |
||
| 465 | } |
||
| 466 | |||
| 467 | public void setTranslation(Vector3 translate) |
||
| 468 | { |
||
| 469 | setTranslation(translate.x, translate.y, translate.z); |
||
| 470 | } |
||
| 471 | |||
| 472 | static public Matrix4 createFromVectors(Vector3 forward, Vector3 up, Vector3 right) |
||
| 473 | { |
||
| 474 | forward.normalize(); |
||
| 475 | up.normalize(); |
||
| 476 | right.normalize(); |
||
| 477 | |||
| 478 | Matrix4 result = new Matrix4(); |
||
| 479 | result.setFromVectors(forward, up, right); |
||
| 480 | return result; |
||
| 481 | } |
||
| 482 | |||
| 483 | public void setFromVectors(Vector3 forward, Vector3 up, Vector3 right) |
||
| 484 | { |
||
| 485 | forward.normalize(); |
||
| 486 | up.normalize(); |
||
| 487 | right.normalize(); |
||
| 488 | |||
| 489 | identity(); |
||
| 490 | |||
| 491 | this.values[M11] = right.x; |
||
| 492 | this.values[M12] = right.y; |
||
| 493 | this.values[M13] = right.z; |
||
| 494 | this.values[M21] = up.x; |
||
| 495 | this.values[M22] = up.y; |
||
| 496 | this.values[M23] = up.z; |
||
| 497 | this.values[M31] = -forward.x; |
||
| 498 | this.values[M32] = -forward.y; |
||
| 499 | this.values[M33] = -forward.z; |
||
| 500 | this.values[M44] = 1.0f; |
||
| 501 | } |
||
| 502 | |||
| 503 | static public Matrix4 createPerspective(float fovDegreesY, float aspect, float zNear, float zFar) |
||
| 504 | { |
||
| 505 | Matrix4 result = new Matrix4(); |
||
| 506 | result.setPerspective(fovDegreesY, aspect, zNear, zFar); |
||
| 507 | return result; |
||
| 508 | } |
||
| 509 | |||
| 510 | public void setPerspective(float fovDegreesY, float aspect, float zNear, float zFar) |
||
| 511 | { |
||
| 512 | float f = 1.0f / (float) Math.Tan(fovDegreesY * (Math.PI / 360.0)); |
||
| 513 | float rangeReciprocal = 1.0f / (zNear - zFar); |
||
| 514 | |||
| 515 | this.values[M11] = f / aspect; |
||
| 516 | this.values[M21] = 0.0f; |
||
| 517 | this.values[M31] = 0.0f; |
||
| 518 | this.values[M41] = 0.0f; |
||
| 519 | |||
| 520 | this.values[M12] = 0.0f; |
||
| 521 | this.values[M22] = f; |
||
| 522 | this.values[M32] = 0.0f; |
||
| 523 | this.values[M42] = 0.0f; |
||
| 524 | |||
| 525 | this.values[M13] = 0.0f; |
||
| 526 | this.values[M23] = 0.0f; |
||
| 527 | this.values[M33] = (zFar + zNear) * rangeReciprocal; |
||
| 528 | this.values[M43] = -1.0f; |
||
| 529 | |||
| 530 | this.values[M14] = 0.0f; |
||
| 531 | this.values[M24] = 0.0f; |
||
| 532 | this.values[M34] = 2.0f * zFar * zNear * rangeReciprocal; |
||
| 533 | this.values[M44] = 0.0f; |
||
| 534 | } |
||
| 535 | |||
| 536 | static public Matrix4 createFrustum(float left, float right, float bottom, float top, float near, float far) |
||
| 537 | { |
||
| 538 | Matrix4 matrix = new Matrix4(); |
||
| 539 | matrix.setFrustum(left, right, bottom, top, near, far); |
||
| 540 | return matrix; |
||
| 541 | } |
||
| 542 | |||
| 543 | public void setFrustum(float left, float right, float bottom, float top, float near, float far) |
||
| 544 | { |
||
| 545 | if (left == right) |
||
| 546 | { |
||
| 547 | throw new ArgumentException("left == right"); |
||
| 548 | } |
||
| 549 | if (top == bottom) |
||
| 550 | { |
||
| 551 | throw new ArgumentException("top == bottom"); |
||
| 552 | } |
||
| 553 | if (near == far) |
||
| 554 | { |
||
| 555 | throw new ArgumentException("near == far"); |
||
| 556 | } |
||
| 557 | if (near <= 0.0f) |
||
| 558 | { |
||
| 559 | throw new ArgumentException("near <= 0.0f"); |
||
| 560 | } |
||
| 561 | if (far <= 0.0f) |
||
| 562 | { |
||
| 563 | throw new ArgumentException("far <= 0.0f"); |
||
| 564 | } |
||
| 565 | |||
| 566 | float r_width = 1.0f / (right - left); |
||
| 567 | float r_height = 1.0f / (top - bottom); |
||
| 568 | float r_depth = 1.0f / (near - far); |
||
| 569 | float x = 2.0f * (near * r_width); |
||
| 570 | float y = 2.0f * (near * r_height); |
||
| 571 | float A = 2.0f * ((right + left) * r_width); |
||
| 572 | float B = (top + bottom) * r_height; |
||
| 573 | float C = (far + near) * r_depth; |
||
| 574 | float D = 2.0f * (far * near * r_depth); |
||
| 575 | |||
| 576 | this.values[M11] = x; |
||
| 577 | this.values[M21] = 0.0f; |
||
| 578 | this.values[M31] = 0.0f; |
||
| 579 | this.values[M41] = 0.0f; |
||
| 580 | |||
| 581 | this.values[M12] = 0.0f; |
||
| 582 | this.values[M22] = y; |
||
| 583 | this.values[M32] = 0.0f; |
||
| 584 | this.values[M42] = 0.0f; |
||
| 585 | |||
| 586 | this.values[M13] = A; |
||
| 587 | this.values[M23] = B; |
||
| 588 | this.values[M33] = C; |
||
| 589 | this.values[M43] = -1.0f; |
||
| 590 | |||
| 591 | this.values[M14] = 0.0f; |
||
| 592 | this.values[M24] = 0.0f; |
||
| 593 | this.values[M34] = D; |
||
| 594 | this.values[M44] = 0.0f; |
||
| 595 | } |
||
| 596 | |||
| 597 | static public Matrix4 createOrtho(float left, float right, float bottom, float top, float near, float far) |
||
| 598 | { |
||
| 599 | Matrix4 matrix = new Matrix4(); |
||
| 600 | matrix.setOrtho(left, right, bottom, top, near, far); |
||
| 601 | return matrix; |
||
| 602 | } |
||
| 603 | |||
| 604 | public void setOrtho(float left, float right, float bottom, float top, float near, float far) |
||
| 605 | { |
||
| 606 | if (left == right) |
||
| 607 | throw new ArgumentException("left and right must not be identical!"); |
||
| 608 | |||
| 609 | if (bottom == top) |
||
| 610 | throw new ArgumentException("bottom and top must not be identical!"); |
||
| 611 | |||
| 612 | if (near == far) |
||
| 613 | throw new ArgumentException("near and far must not be identical!"); |
||
| 614 | |||
| 615 | float r_width = 1.0f / (right - left); |
||
| 616 | float r_height = 1.0f / (top - bottom); |
||
| 617 | float r_depth = 1.0f / (far - near); |
||
| 618 | float x = 2.0f * (r_width); |
||
| 619 | float y = 2.0f * (r_height); |
||
| 620 | float z = -2.0f * (r_depth); |
||
| 621 | float tx = -(right + left) * r_width; |
||
| 622 | float ty = -(top + bottom) * r_height; |
||
| 623 | float tz = -(far + near) * r_depth; |
||
| 624 | |||
| 625 | this.values[M11] = x; this.values[M21] = 0.0f; this.values[M31] = 0.0f; this.values[M41] = 0.0f; |
||
| 626 | this.values[M12] = 0.0f; this.values[M22] = y; this.values[M32] = 0.0f; this.values[M42] = 0.0f; |
||
| 627 | this.values[M13] = 0.0f; this.values[M23] = 0.0f; this.values[M33] = z; this.values[M43] = 0.0f; |
||
| 628 | this.values[M14] = tx; this.values[M24] = ty; this.values[M34] = tz; this.values[M44] = 1.0f; |
||
| 629 | } |
||
| 630 | |||
| 631 | static public Matrix4 createLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) |
||
| 632 | { |
||
| 633 | Matrix4 matrix = new Matrix4(); |
||
| 634 | matrix.setLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ); |
||
| 635 | return matrix; |
||
| 636 | } |
||
| 637 | |||
| 638 | public void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) |
||
| 639 | { |
||
| 640 | float fx = centerX - eyeX; |
||
| 641 | float fy = centerY - eyeY; |
||
| 642 | float fz = centerZ - eyeZ; |
||
| 643 | |||
| 644 | // Normalize f |
||
| 645 | float rlf = 1.0f / Vector3.length(fx, fy, fz); |
||
| 646 | fx *= rlf; |
||
| 647 | fy *= rlf; |
||
| 648 | fz *= rlf; |
||
| 649 | |||
| 650 | // compute s = f x up (x means "cross product") |
||
| 651 | float sx = fy * upZ - fz * upY; |
||
| 652 | float sy = fz * upX - fx * upZ; |
||
| 653 | float sz = fx * upY - fy * upX; |
||
| 654 | |||
| 655 | // and normalize s |
||
| 656 | float rls = 1.0f / Vector3.length(sx, sy, sz); |
||
| 657 | sx *= rls; |
||
| 658 | sy *= rls; |
||
| 659 | sz *= rls; |
||
| 660 | |||
| 661 | // compute u = s x f |
||
| 662 | float ux = sy * fz - sz * fy; |
||
| 663 | float uy = sz * fx - sx * fz; |
||
| 664 | float uz = sx * fy - sy * fx; |
||
| 665 | |||
| 666 | this.values[M11] = sx; |
||
| 667 | this.values[M21] = ux; |
||
| 668 | this.values[M31] = -fx; |
||
| 669 | this.values[M41] = 0.0f; |
||
| 670 | |||
| 671 | this.values[M12] = sy; |
||
| 672 | this.values[M22] = uy; |
||
| 673 | this.values[M32] = -fy; |
||
| 674 | this.values[M42] = 0.0f; |
||
| 675 | |||
| 676 | this.values[M13] = sz; |
||
| 677 | this.values[M23] = uz; |
||
| 678 | this.values[M33] = -fz; |
||
| 679 | this.values[M43] = 0.0f; |
||
| 680 | |||
| 681 | this.values[M14] = 0.0f; |
||
| 682 | this.values[M24] = 0.0f; |
||
| 683 | this.values[M34] = 0.0f; |
||
| 684 | this.values[M44] = 1.0f; |
||
| 685 | |||
| 686 | this.values[M14] = this.values[M11] * -eyeX + this.values[M12] * -eyeY + this.values[M13] * -eyeZ + this.values[M14]; |
||
| 687 | this.values[M24] = this.values[M21] * -eyeX + this.values[M22] * -eyeY + this.values[M23] * -eyeZ + this.values[M24]; |
||
| 688 | this.values[M34] = this.values[M31] * -eyeX + this.values[M32] * -eyeY + this.values[M33] * -eyeZ + this.values[M34]; |
||
| 689 | this.values[M44] = this.values[M41] * -eyeX + this.values[M42] * -eyeY + this.values[M43] * -eyeZ + this.values[M44]; |
||
| 690 | } |
||
| 691 | |||
| 692 | public Vector3 transform(Vector3 vector) |
||
| 693 | { |
||
| 694 | |||
| 695 | return new Vector3( |
||
| 696 | values[M11] * vector.x + values[M21] * vector.y + values[M31] * vector.z + values[M41], |
||
| 697 | values[M12] * vector.x + values[M22] * vector.y + values[M32] * vector.z + values[M42], |
||
| 698 | values[M13] * vector.x + values[M23] * vector.y + values[M33] * vector.z + values[M43]); |
||
| 699 | } |
||
| 700 | |||
| 701 | public Vector4 transform(Vector4 vector) |
||
| 702 | { |
||
| 703 | return new Vector4( |
||
| 704 | values[M11] * vector.x + values[M21] * vector.y + values[M31] * vector.z + values[M41] * vector.w, |
||
| 705 | values[M12] * vector.x + values[M22] * vector.y + values[M32] * vector.z + values[M42] * vector.w, |
||
| 706 | values[M13] * vector.x + values[M23] * vector.y + values[M33] * vector.z + values[M43] * vector.w, |
||
| 707 | values[M14] * vector.x + values[M24] * vector.y + values[M34] * vector.z + values[M44] * vector.w); |
||
| 708 | } |
||
| 709 | |||
| 710 | static public void interpolate(Matrix4 result, Matrix4 a, Matrix4 b, float ratio) |
||
| 711 | { |
||
| 712 | result.values[M11] = a.values[M11] + (b.values[M11] - a.values[M11]) * ratio; |
||
| 713 | result.values[M21] = a.values[M21] + (b.values[M21] - a.values[M21]) * ratio; |
||
| 714 | result.values[M31] = a.values[M31] + (b.values[M31] - a.values[M31]) * ratio; |
||
| 715 | result.values[M41] = a.values[M41] + (b.values[M41] - a.values[M41]) * ratio; |
||
| 716 | result.values[M12] = a.values[M12] + (b.values[M12] - a.values[M12]) * ratio; |
||
| 717 | result.values[M22] = a.values[M22] + (b.values[M22] - a.values[M22]) * ratio; |
||
| 718 | result.values[M32] = a.values[M32] + (b.values[M32] - a.values[M32]) * ratio; |
||
| 719 | result.values[M42] = a.values[M42] + (b.values[M42] - a.values[M42]) * ratio; |
||
| 720 | result.values[M13] = a.values[M13] + (b.values[M13] - a.values[M13]) * ratio; |
||
| 721 | result.values[M23] = a.values[M23] + (b.values[M23] - a.values[M23]) * ratio; |
||
| 722 | result.values[M33] = a.values[M33] + (b.values[M33] - a.values[M33]) * ratio; |
||
| 723 | result.values[M43] = a.values[M43] + (b.values[M43] - a.values[M43]) * ratio; |
||
| 724 | result.values[M14] = a.values[M14] + (b.values[M14] - a.values[M14]) * ratio; |
||
| 725 | result.values[M24] = a.values[M24] + (b.values[M24] - a.values[M24]) * ratio; |
||
| 726 | result.values[M34] = a.values[M34] + (b.values[M34] - a.values[M34]) * ratio; |
||
| 727 | result.values[M44] = a.values[M44] + (b.values[M44] - a.values[M44]) * ratio; |
||
| 728 | } |
||
| 729 | |||
| 730 | static public Matrix4 interpolate(Matrix4 a, Matrix4 b, float ratio) |
||
| 731 | { |
||
| 732 | Matrix4 result = createIdentity(); |
||
| 733 | interpolate(result, a, b, ratio); |
||
| 734 | return result; |
||
| 735 | } |
||
| 736 | |||
| 737 | public Vector3 getForwardVector() |
||
| 738 | { |
||
| 739 | Vector3 forward = new Vector3(-values[M31], -values[M32], -values[M33]); |
||
| 740 | forward.normalize(); |
||
| 741 | return forward; |
||
| 742 | } |
||
| 743 | |||
| 744 | public Vector3 getUpVector() |
||
| 745 | { |
||
| 746 | Vector3 up = new Vector3(values[M21], values[M22], values[M23]); |
||
| 747 | up.normalize(); |
||
| 748 | return up; |
||
| 749 | } |
||
| 750 | |||
| 751 | public Vector3 getRightVector() |
||
| 752 | { |
||
| 753 | Vector3 right = new Vector3(values[M11], values[M12], values[M13]); |
||
| 754 | right.normalize(); |
||
| 755 | return right; |
||
| 756 | } |
||
| 757 | |||
| 758 | public float[] toGLMatrix() |
||
| 759 | { |
||
| 760 | return values; |
||
| 761 | } |
||
| 762 | |||
| 763 | public void fromGLMatrix(float[] m) |
||
| 764 | { |
||
| 765 | //values = m; |
||
| 766 | for (int i = 0; i < values.Length; i++) |
||
| 767 | values[i] = m[i]; |
||
| 768 | } |
||
| 769 | |||
| 770 | // TODO: convert to C# equivalent |
||
| 771 | /* |
||
| 772 | public FloatBuffer toFloatBuffer() |
||
| 773 | { |
||
| 774 | FloatBuffer buffer = BufferUtils.newFloatBuffer(16); |
||
| 775 | |||
| 776 | BufferUtils.copy(values, buffer, values.length, 0); |
||
| 777 | |||
| 778 | return buffer; |
||
| 779 | }*/ |
||
| 780 | } |
||
| 781 | } |