Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 200 | chris | 1 | package com.gebauz.Bauzoid.math; |
| 2 | |||
| 3 | public class Matrix3 |
||
| 4 | { |
||
| 5 | /* OpenGL Colum Major: |
||
| 6 | * m[0] m[3] m[6] |
||
| 7 | * m[1] m[4] m[7] |
||
| 8 | * m[2] m[5] m[8] |
||
| 9 | */ |
||
| 10 | |||
| 11 | public float m11; |
||
| 12 | public float m21; |
||
| 13 | public float m31; |
||
| 14 | public float m12; |
||
| 15 | public float m22; |
||
| 16 | public float m32; |
||
| 17 | public float m13; |
||
| 18 | public float m23; |
||
| 19 | public float m33; |
||
| 20 | |||
| 21 | static public final int MATRIX_SIZE = 3; |
||
| 22 | |||
| 23 | public Matrix3() |
||
| 24 | { |
||
| 25 | } |
||
| 26 | |||
| 27 | public float get(int row, int col) |
||
| 28 | { |
||
| 29 | switch (row) |
||
| 30 | { |
||
| 31 | case 0: |
||
| 32 | switch (col) |
||
| 33 | { |
||
| 34 | case 0: return m11; |
||
| 35 | case 1: return m12; |
||
| 36 | case 2: return m13; |
||
| 37 | } |
||
| 38 | break; |
||
| 39 | case 1: |
||
| 40 | switch (col) |
||
| 41 | { |
||
| 42 | case 0: return m21; |
||
| 43 | case 1: return m22; |
||
| 44 | case 2: return m23; |
||
| 45 | } |
||
| 46 | break; |
||
| 47 | case 2: |
||
| 48 | switch (col) |
||
| 49 | { |
||
| 50 | case 0: return m31; |
||
| 51 | case 1: return m32; |
||
| 52 | case 2: return m33; |
||
| 53 | } |
||
| 54 | break; |
||
| 55 | } |
||
| 56 | // should never reach here -> TODO: assert |
||
| 57 | return 0.0f; |
||
| 58 | } |
||
| 59 | |||
| 60 | public void set(int row, int col, float value) |
||
| 61 | { |
||
| 62 | switch (row) |
||
| 63 | { |
||
| 64 | case 0: |
||
| 65 | switch (col) |
||
| 66 | { |
||
| 67 | case 0: |
||
| 68 | m11 = value; |
||
| 69 | break; |
||
| 70 | case 1: |
||
| 71 | m12 = value; |
||
| 72 | break; |
||
| 73 | case 2: |
||
| 74 | m13 = value; |
||
| 75 | break; |
||
| 76 | } |
||
| 77 | break; |
||
| 78 | case 1: |
||
| 79 | switch (col) |
||
| 80 | { |
||
| 81 | case 0: |
||
| 82 | m21 = value; |
||
| 83 | break; |
||
| 84 | case 1: |
||
| 85 | m22 = value; |
||
| 86 | break; |
||
| 87 | case 2: |
||
| 88 | m23 = value; |
||
| 89 | break; |
||
| 90 | } |
||
| 91 | break; |
||
| 92 | case 2: |
||
| 93 | switch (col) |
||
| 94 | { |
||
| 95 | case 0: |
||
| 96 | m31 = value; |
||
| 97 | break; |
||
| 98 | case 1: |
||
| 99 | m32 = value; |
||
| 100 | break; |
||
| 101 | case 2: |
||
| 102 | m33 = value; |
||
| 103 | break; |
||
| 104 | } |
||
| 105 | break; |
||
| 106 | } |
||
| 107 | } |
||
| 108 | |||
| 109 | public void zero() |
||
| 110 | { |
||
| 111 | m11 = 0.0f; m12 = 0.0f; m13 = 0.0f; |
||
| 112 | m21 = 0.0f; m22 = 0.0f; m23 = 0.0f; |
||
| 113 | m31 = 0.0f; m32 = 0.0f; m33 = 0.0f; |
||
| 114 | } |
||
| 115 | |||
| 116 | public void identity() |
||
| 117 | { |
||
| 118 | zero(); |
||
| 119 | m11 = 1.0f; m22 = 1.0f; m33 = 1.0f; |
||
| 120 | } |
||
| 121 | |||
| 122 | public boolean equals(Matrix3 other) |
||
| 123 | { |
||
| 124 | return ((m11 == other.m11) && (m12 == other.m12) && (m13 == other.m13) && |
||
| 125 | (m21 == other.m21) && (m22 == other.m22) && (m23 == other.m23) && |
||
| 126 | (m31 == other.m31) && (m32 == other.m32) && (m33 == other.m33)); |
||
| 127 | } |
||
| 128 | |||
| 129 | public boolean isSingular() |
||
| 130 | { |
||
| 131 | float determinant = getDeterminant(); |
||
| 132 | return ((float)Math.abs(determinant) < MathUtil.EPSILON); |
||
| 133 | } |
||
| 134 | |||
| 135 | public Matrix3 getTranspose() |
||
| 136 | { |
||
| 137 | Matrix3 result = new Matrix3(); |
||
| 138 | result.m11 = m11; |
||
| 139 | result.m12 = m21; |
||
| 140 | result.m13 = m31; |
||
| 141 | result.m21 = m12; |
||
| 142 | result.m22 = m22; |
||
| 143 | result.m23 = m32; |
||
| 144 | result.m31 = m13; |
||
| 145 | result.m32 = m23; |
||
| 146 | result.m33 = m33; |
||
| 147 | return result; |
||
| 148 | } |
||
| 149 | |||
| 150 | public float getDeterminant() |
||
| 151 | { |
||
| 152 | float result = |
||
| 153 | m11 * (m22 * m33 - m23 * m32) - |
||
| 154 | m21 * (m12 * m33 - m13 * m32) + |
||
| 155 | m31 * (m12 * m23 - m13 * m22); |
||
| 156 | return result; |
||
| 157 | } |
||
| 158 | |||
| 159 | public Matrix3 getInverse() |
||
| 160 | { |
||
| 161 | Matrix3 result = new Matrix3(); |
||
| 162 | |||
| 163 | float determinant = getDeterminant(); |
||
| 164 | if (determinant == 0.0f) |
||
| 165 | { |
||
| 166 | // singular matrix cannot be inverted |
||
| 167 | return this; |
||
| 168 | } |
||
| 169 | |||
| 170 | result.m11 = m22 * m33 - m32 * m23; |
||
| 171 | result.m21 = -(m21 * m33 - m23 * m31); |
||
| 172 | result.m31 = m21 * m32 - m22 * m31; |
||
| 173 | result.m12 = -(m12 * m33 - m32 * m13); |
||
| 174 | result.m22 = m11 * m33 - m13 * m31; |
||
| 175 | result.m32 = -(m11 * m32 - m12 * m31); |
||
| 176 | result.m13 = m12 * m23 - m13 * m22; |
||
| 177 | result.m23 = -(m11 * m23 - m13 * m21); |
||
| 178 | result.m33 = m11 * m22 - m21 * m12; |
||
| 179 | |||
| 180 | float multiply = 1.0f / determinant; |
||
| 181 | result.m11 *= multiply; |
||
| 182 | result.m21 *= multiply; |
||
| 183 | result.m31 *= multiply; |
||
| 184 | result.m12 *= multiply; |
||
| 185 | result.m22 *= multiply; |
||
| 186 | result.m32 *= multiply; |
||
| 187 | result.m13 *= multiply; |
||
| 188 | result.m23 *= multiply; |
||
| 189 | result.m33 *= multiply; |
||
| 190 | |||
| 191 | return result; |
||
| 192 | } |
||
| 193 | |||
| 194 | public void copyTo(Matrix3 target) |
||
| 195 | { |
||
| 196 | target.m11 = m11; target.m12 = m12; target.m13 = m13; |
||
| 197 | target.m21 = m21; target.m22 = m22; target.m23 = m23; |
||
| 198 | target.m31 = m31; target.m32 = m32; target.m33 = m33; |
||
| 199 | } |
||
| 200 | |||
| 201 | public void copyFrom(Matrix3 source) |
||
| 202 | { |
||
| 203 | m11 = source.m11; m12 = source.m12; m13 = source.m13; |
||
| 204 | m21 = source.m21; m22 = source.m22; m23 = source.m23; |
||
| 205 | m31 = source.m31; m32 = source.m32; m33 = source.m33; |
||
| 206 | } |
||
| 207 | |||
| 208 | public void postMultiply(Matrix3 v) |
||
| 209 | { |
||
| 210 | multiply(this, this, v); |
||
| 211 | } |
||
| 212 | |||
| 213 | public void preMultiply(Matrix3 v) |
||
| 214 | { |
||
| 215 | multiply(this, v, this); |
||
| 216 | } |
||
| 217 | |||
| 218 | static public void multiply(Matrix3 result, Matrix3 a, Matrix3 b) |
||
| 219 | { |
||
| 220 | float result11 = a.m11 * b.m11 + a.m21 * b.m12 + a.m31 * b.m13; |
||
| 221 | float result21 = a.m11 * b.m21 + a.m21 * b.m22 + a.m31 * b.m23; |
||
| 222 | float result31 = a.m11 * b.m31 + a.m21 * b.m32 + a.m31 * b.m33; |
||
| 223 | float result12 = a.m12 * b.m11 + a.m22 * b.m12 + a.m32 * b.m13; |
||
| 224 | float result22 = a.m12 * b.m21 + a.m22 * b.m22 + a.m32 * b.m23; |
||
| 225 | float result32 = a.m12 * b.m31 + a.m22 * b.m32 + a.m32 * b.m33; |
||
| 226 | float result13 = a.m13 * b.m11 + a.m23 * b.m12 + a.m33 * b.m13; |
||
| 227 | float result23 = a.m13 * b.m21 + a.m23 * b.m22 + a.m33 * b.m23; |
||
| 228 | float result33 = a.m13 * b.m31 + a.m23 * b.m32 + a.m33 * b.m33; |
||
| 229 | result.m11 = result11; |
||
| 230 | result.m21 = result21; |
||
| 231 | result.m31 = result31; |
||
| 232 | result.m12 = result12; |
||
| 233 | result.m22 = result22; |
||
| 234 | result.m32 = result32; |
||
| 235 | result.m13 = result13; |
||
| 236 | result.m23 = result23; |
||
| 237 | result.m33 = result33; |
||
| 238 | } |
||
| 239 | |||
| 240 | static public Matrix3 multiply(Matrix3 a, Matrix3 b) |
||
| 241 | { |
||
| 242 | Matrix3 result = new Matrix3(); |
||
| 243 | multiply(result, a, b); |
||
| 244 | return result; |
||
| 245 | } |
||
| 246 | |||
| 247 | static public Matrix3 createIdentity() |
||
| 248 | { |
||
| 249 | return createScale(1.0f, 1.0f, 1.0f); |
||
| 250 | } |
||
| 251 | |||
| 252 | static public Matrix3 createScale(float sx, float sy, float sz) |
||
| 253 | { |
||
| 254 | Matrix3 result = new Matrix3(); |
||
| 255 | |||
| 256 | result.m11 = sx; |
||
| 257 | result.m22 = sy; |
||
| 258 | result.m33 = sz; |
||
| 259 | |||
| 260 | return result; |
||
| 261 | } |
||
| 262 | |||
| 263 | static public Matrix3 createScale(Vector3 scale) |
||
| 264 | { |
||
| 265 | return createScale(scale.x, scale.y, scale.z); |
||
| 266 | } |
||
| 267 | |||
| 268 | static public Matrix3 createScale(float s) |
||
| 269 | { |
||
| 270 | return createScale(s, s, s); |
||
| 271 | } |
||
| 272 | |||
| 273 | static public Matrix3 createRotationX(float degrees) |
||
| 274 | { |
||
| 275 | float degreesrad = MathUtil.degToRad(degrees); |
||
| 276 | float sinvalue = (float)Math.sin(degreesrad); |
||
| 277 | float cosvalue = (float)Math.cos(degreesrad); |
||
| 278 | |||
| 279 | Matrix3 matrix = createIdentity(); |
||
| 280 | matrix.m22 = cosvalue; |
||
| 281 | matrix.m32 = -sinvalue; |
||
| 282 | matrix.m23 = sinvalue; |
||
| 283 | matrix.m33 = cosvalue; |
||
| 284 | return matrix; |
||
| 285 | } |
||
| 286 | |||
| 287 | static public Matrix3 createRotationY(float degrees) |
||
| 288 | { |
||
| 289 | float degreesrad = MathUtil.degToRad(degrees); |
||
| 290 | float sinvalue = (float)Math.sin(degreesrad); |
||
| 291 | float cosvalue = (float)Math.cos(degreesrad); |
||
| 292 | |||
| 293 | Matrix3 matrix = createIdentity(); |
||
| 294 | matrix.m11 = cosvalue; |
||
| 295 | matrix.m31 = sinvalue; |
||
| 296 | matrix.m13 = -sinvalue; |
||
| 297 | matrix.m33 = cosvalue; |
||
| 298 | return matrix; |
||
| 299 | } |
||
| 300 | |||
| 301 | static public Matrix3 createRotationZ(float degrees) |
||
| 302 | { |
||
| 303 | float degreesrad = MathUtil.degToRad(degrees); |
||
| 304 | float sinvalue = (float)Math.sin(degreesrad); |
||
| 305 | float cosvalue = (float)Math.cos(degreesrad); |
||
| 306 | |||
| 307 | Matrix3 matrix = createIdentity(); |
||
| 308 | matrix.m11 = cosvalue; |
||
| 309 | matrix.m21 = -sinvalue; |
||
| 310 | matrix.m12 = sinvalue; |
||
| 311 | matrix.m22 = cosvalue; |
||
| 312 | return matrix; |
||
| 313 | } |
||
| 314 | |||
| 315 | static public Matrix3 createRotation(Vector3 axis, float degrees) |
||
| 316 | { |
||
| 317 | float radangle = MathUtil.degToRad(degrees); |
||
| 318 | float radcos = (float)Math.cos(radangle); |
||
| 319 | float radsin = (float)Math.sin(radangle); |
||
| 320 | |||
| 321 | Matrix3 matrix = new Matrix3(); |
||
| 322 | matrix.m11 = radcos + axis.x * axis.x * (1 - radcos); |
||
| 323 | matrix.m21 = axis.z * radsin + axis.y * axis.x * (1 - radcos); |
||
| 324 | matrix.m31 = -axis.y * radsin + axis.z * axis.x * (1 - radcos); |
||
| 325 | matrix.m12 = -axis.z * radsin + axis.x * axis.y * (1 - radcos); |
||
| 326 | matrix.m22 = radcos + axis.y * axis.y * (1 - radcos); |
||
| 327 | matrix.m32 = axis.x * radsin + axis.z * axis.y * (1 - radcos); |
||
| 328 | matrix.m13 = axis.y * radsin + axis.x * axis.z * (1 - radcos); |
||
| 329 | matrix.m23 = -axis.x * radsin + axis.y * axis.z * (1 - radcos); |
||
| 330 | matrix.m33 = radcos + axis.z * axis.z * (1 - radcos); |
||
| 331 | return matrix; |
||
| 332 | } |
||
| 333 | |||
| 334 | static public Matrix3 createFromVectors(Vector3 forward, Vector3 up, Vector3 right) |
||
| 335 | { |
||
| 336 | forward.normalize(); |
||
| 337 | up.normalize(); |
||
| 338 | right.normalize(); |
||
| 339 | |||
| 340 | Matrix3 result = createIdentity(); |
||
| 341 | |||
| 342 | result.m11 = right.x; |
||
| 343 | result.m12 = right.y; |
||
| 344 | result.m13 = right.z; |
||
| 345 | result.m21 = up.x; |
||
| 346 | result.m22 = up.y; |
||
| 347 | result.m23 = up.z; |
||
| 348 | result.m31 = -forward.x; |
||
| 349 | result.m32 = -forward.y; |
||
| 350 | result.m33 = -forward.z; |
||
| 351 | |||
| 352 | return result; |
||
| 353 | } |
||
| 354 | |||
| 355 | public Vector3 transform(Vector3 vector) |
||
| 356 | { |
||
| 357 | return new Vector3( |
||
| 358 | m11 * vector.x + m21 * vector.y + m31 * vector.z, |
||
| 359 | m12 * vector.x + m22 * vector.y + m32 * vector.z, |
||
| 360 | m13 * vector.x + m23 * vector.y + m33 * vector.z); |
||
| 361 | } |
||
| 362 | |||
| 363 | static public void interpolate(Matrix3 result, Matrix3 a, Matrix3 b, float ratio) |
||
| 364 | { |
||
| 365 | result.m11 = a.m11 + (b.m11 - a.m11) * ratio; |
||
| 366 | result.m21 = a.m21 + (b.m21 - a.m21) * ratio; |
||
| 367 | result.m31 = a.m31 + (b.m31 - a.m31) * ratio; |
||
| 368 | result.m12 = a.m12 + (b.m12 - a.m12) * ratio; |
||
| 369 | result.m22 = a.m22 + (b.m22 - a.m22) * ratio; |
||
| 370 | result.m32 = a.m32 + (b.m32 - a.m32) * ratio; |
||
| 371 | result.m13 = a.m13 + (b.m13 - a.m13) * ratio; |
||
| 372 | result.m23 = a.m23 + (b.m23 - a.m23) * ratio; |
||
| 373 | result.m33 = a.m33 + (b.m33 - a.m33) * ratio; |
||
| 374 | } |
||
| 375 | |||
| 376 | static public Matrix3 interpolate(Matrix3 a, Matrix3 b, float ratio) |
||
| 377 | { |
||
| 378 | Matrix3 result = createIdentity(); |
||
| 379 | interpolate(result, a, b, ratio); |
||
| 380 | return result; |
||
| 381 | } |
||
| 382 | |||
| 383 | public Vector3 getForwardVector() |
||
| 384 | { |
||
| 385 | Vector3 forward = new Vector3(-m31, -m32, -m33); |
||
| 386 | forward.normalize(); |
||
| 387 | return forward; |
||
| 388 | } |
||
| 389 | |||
| 390 | public Vector3 getUpVector() |
||
| 391 | { |
||
| 392 | Vector3 up = new Vector3(m21, m22, m23); |
||
| 393 | up.normalize(); |
||
| 394 | return up; |
||
| 395 | } |
||
| 396 | |||
| 397 | public Vector3 getRightVector() |
||
| 398 | { |
||
| 399 | Vector3 right = new Vector3(m11, m12, m13); |
||
| 400 | right.normalize(); |
||
| 401 | return right; |
||
| 402 | } |
||
| 403 | |||
| 404 | public float[] toGLMatrix() |
||
| 405 | { |
||
| 406 | float[] m = new float[16]; |
||
| 407 | |||
| 408 | m[0] = m11; m[1] = m21; m[2] = m31; m[3] = 0.0f; |
||
| 409 | m[4] = m12; m[5] = m22; m[6] = m32; m[7] = 0.0f; |
||
| 410 | m[8] = m13; m[9] = m23; m[10] = m33; m[11] = 0.0f; |
||
| 411 | m[12] = 0.0f; m[13] = 0.0f; m[14] = 0.0f; m[15] = 1.0f; |
||
| 412 | |||
| 413 | return m; |
||
| 414 | } |
||
| 415 | |||
| 416 | } |