1 /** 2 * Copyright (C) 2009-2012 Klaus Reimer <k@ailis.de> 3 * See LICENSE.txt for licensing information 4 * 5 * @require threedee.js 6 */ 7 8 /** 9 * @constructor 10 * Constructs a new matrix initialized as an identity matrix. 11 * 12 * @class 13 * A matrix with 4x4 entries. 14 */ 15 threedee.Matrix = function() 16 { 17 threedee.Matrix.counter++; 18 }; 19 20 /** 21 * Instance counter. 22 * @private 23 * @type {number} 24 */ 25 threedee.Matrix.counter = 0; 26 27 /** 28 * A temporary matrix for internal operations. 29 * @private 30 * @type {!threedee.Matrix} 31 */ 32 threedee.Matrix.TMP = new threedee.Matrix(); 33 34 /** 35 * The matrix entry 0;0. 36 * @type {number} 37 */ 38 threedee.Matrix.prototype.m00 = 1; 39 40 /** 41 * The matrix entry 0;1. 42 * @type {number} 43 */ 44 threedee.Matrix.prototype.m01 = 0; 45 46 /** 47 * The matrix entry 0;2. 48 * @type {number} 49 */ 50 threedee.Matrix.prototype.m02 = 0; 51 52 /** 53 * The matrix entry 0;3. 54 * @type {number} 55 */ 56 threedee.Matrix.prototype.m03 = 0; 57 58 /** 59 * The matrix entry 1;0. 60 * @type {number} 61 */ 62 threedee.Matrix.prototype.m10 = 0; 63 64 /** 65 * The matrix entry 1;1. 66 * @type {number} 67 */ 68 threedee.Matrix.prototype.m11 = 1; 69 70 /** 71 * The matrix entry 1;2. 72 * @type {number} 73 */ 74 threedee.Matrix.prototype.m12 = 0; 75 76 /** 77 * The matrix entry 1;3. 78 * @type {number} 79 */ 80 threedee.Matrix.prototype.m13 = 0; 81 82 /** 83 * The matrix entry 2;0. 84 * @type {number} 85 */ 86 threedee.Matrix.prototype.m20 = 0; 87 88 /** 89 * The matrix entry 2;1. 90 * @type {number} 91 */ 92 threedee.Matrix.prototype.m21 = 0; 93 94 /** 95 * The matrix entry 2;2. 96 * @type {number} * 97 */ 98 threedee.Matrix.prototype.m22 = 1; 99 100 /** 101 * The matrix entry 2;3. 102 * @type {number} 103 */ 104 threedee.Matrix.prototype.m23 = 0; 105 106 /** 107 * The matrix entry 3;0. 108 * @type {number} 109 */ 110 threedee.Matrix.prototype.m30 = 0; 111 112 /** 113 * The matrix entry 3;1. 114 * @type {number} 115 */ 116 threedee.Matrix.prototype.m31 = 0; 117 118 /** 119 * The matrix entry 3;2. 120 * @type {number} 121 */ 122 threedee.Matrix.prototype.m32 = 0; 123 124 /** 125 * The matrix entry 3;3. 126 * @type {number} 127 */ 128 threedee.Matrix.prototype.m33 = 1; 129 130 /** 131 * Returns and resets the current instance counter. 132 * 133 * @return {number} 134 * The number of created instances since the last call. 135 */ 136 threedee.Matrix.count = function() 137 { 138 var value = threedee.Matrix.counter; 139 threedee.Matrix.counter = 0; 140 return value; 141 }; 142 143 /** 144 * Returns a copy of this matrix. 145 * 146 * @return {!threedee.Matrix} 147 * A copy of this matrix 148 */ 149 threedee.Matrix.prototype.copy = function() 150 { 151 return new threedee.Matrix().set( 152 this.m00, this.m01, this.m02, this.m03, 153 this.m10, this.m11, this.m12, this.m13, 154 this.m20, this.m21, this.m22, this.m23, 155 this.m30, this.m31, this.m32, this.m33); 156 }; 157 158 /** 159 * Sets the matrix entries. 160 * 161 * @param {number} m00 162 * The matrix entry 0;0 163 * @param {number} m01 164 * The matrix entry 0;1 165 * @param {number} m02 166 * The matrix entry 0;2 167 * @param {number} m03 168 * The matrix entry 0;3 169 * @param {number} m10 170 * The matrix entry 1;0 171 * @param {number} m11 172 * The matrix entry 1;1 173 * @param {number} m12 174 * The matrix entry 1;2 175 * @param {number} m13 176 * The matrix entry 1;3 177 * @param {number} m20 178 * The matrix entry 2;0 179 * @param {number} m21 180 * The matrix entry 2;1 181 * @param {number} m22 182 * The matrix entry 2;2 183 * @param {number} m23 184 * The matrix entry 2;3 185 * @param {number} m30 186 * The matrix entry 3;0 187 * @param {number} m31 188 * The matrix entry 3;1 189 * @param {number} m32 190 * The matrix entry 3;2 191 * @param {number} m33 192 * The matrix entry 3;3 193 * @return {!threedee.Matrix} 194 * This matrix 195 */ 196 threedee.Matrix.prototype.set = function(m00, m01, m02, m03, 197 m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) 198 { 199 this.m00 = m00; 200 this.m01 = m01; 201 this.m02 = m02; 202 this.m03 = m03; 203 this.m10 = m10; 204 this.m11 = m11; 205 this.m12 = m12; 206 this.m13 = m13; 207 this.m20 = m20; 208 this.m21 = m21; 209 this.m22 = m22; 210 this.m23 = m23; 211 this.m30 = m30; 212 this.m31 = m31; 213 this.m32 = m32; 214 this.m33 = m33; 215 return this; 216 }; 217 218 /** 219 * Sets the entries of this matrix to an identity matrix. 220 * 221 * @return {!threedee.Matrix} 222 * The matrix 223 */ 224 threedee.Matrix.prototype.setIdentity = function() 225 { 226 return this.set( 227 1, 0, 0, 0, 228 0, 1, 0, 0, 229 0, 0, 1, 0, 230 0, 0, 0, 1); 231 }; 232 233 /** 234 * Sets the entries of this matrix to an X rotation matrix. 235 * 236 * @param {number} angle 237 * The rotation angle in clock-wise RAD 238 * @return {!threedee.Matrix} 239 * This matrix 240 */ 241 threedee.Matrix.prototype.setRotateX = function(angle) 242 { 243 var s, c; 244 245 s = Math.sin(angle); 246 c = Math.cos(angle); 247 return this.set( 248 1, 0, 0, 0, 249 0, c, -s, 0, 250 0, s, c, 0, 251 0, 0, 0, 1); 252 }; 253 254 /** 255 * Sets the entries of this matrix to an Y rotation matrix. 256 * 257 * @param {number} angle 258 * The rotation angle in anti-clock-wise RAD 259 * @return {!threedee.Matrix} 260 * This matrix 261 */ 262 threedee.Matrix.prototype.setRotateY = function(angle) 263 { 264 var s, c; 265 266 s = Math.sin(angle); 267 c = Math.cos(angle); 268 return this.set( 269 c, 0, s, 0, 270 0, 1, 0, 0, 271 -s, 0, c, 0, 272 0, 0, 0, 1); 273 }; 274 275 /** 276 * Sets the entries of this matrix to an Z rotation matrix. 277 * 278 * @param {number} angle 279 * The rotation angle in anti-clock-wise RAD 280 * @return {!threedee.Matrix} 281 * This matrix 282 */ 283 threedee.Matrix.prototype.setRotateZ = function(angle) 284 { 285 var s, c; 286 287 s = Math.sin(angle); 288 c = Math.cos(angle); 289 return this.set( 290 c, -s, 0, 0, 291 s, c, 0, 0, 292 0, 0, 1, 0, 293 0, 0, 0, 1); 294 }; 295 296 /** 297 * Sets the entries of this matrix to a scaling matrix. 298 * 299 * @param {number} fx 300 * The X scale factor 301 * @param {number} fy 302 * The Y scale factor. Optional. Defaults to fx. 303 * @param {number} fz 304 * The Z scale factor. Optional. Defaults to fx. 305 * @return {!threedee.Matrix} 306 * This matrix 307 */ 308 threedee.Matrix.prototype.setScale = function(fx, fy, fz) 309 { 310 return this.set( 311 fx, 0, 0, 0, 312 0, fy === undefined ? fx : fy, 0, 0, 313 0, 0, fz === undefined ? fx : fz, 0, 314 0, 0, 0, 1); 315 }; 316 317 /** 318 * Sets the entries of this matrix to a X scaling matrix. 319 * 320 * @param {number} f 321 * The scale factor 322 * @return {!threedee.Matrix} 323 * This matrix 324 */ 325 threedee.Matrix.prototype.setScaleX = function(f) 326 { 327 return this.set( 328 f, 0, 0, 0, 329 0, 1, 0, 0, 330 0, 0, 1, 0, 331 0, 0, 0, 1); 332 }; 333 334 /** 335 * Sets the entries of this matrix to a Y scaling matrix. 336 * 337 * @param {number} f 338 * The scale factor 339 * @return {!threedee.Matrix} 340 * This matrix 341 */ 342 threedee.Matrix.prototype.setScaleY = function(f) 343 { 344 return this.set( 345 1, 0, 0, 0, 346 0, f, 0, 0, 347 0, 0, 1, 0, 348 0, 0, 0, 1); 349 }; 350 351 /** 352 * Sets the entries of this matrix to a Z scaling matrix. 353 * 354 * @param {number} f 355 * The scale factor 356 * @return {!threedee.Matrix} 357 * This matrix 358 */ 359 threedee.Matrix.prototype.setScaleZ = function(f) 360 { 361 return this.set( 362 1, 0, 0, 0, 363 0, 1, 0, 0, 364 0, 0, f, 0, 365 0, 0, 0, 1); 366 }; 367 368 /** 369 * Sets the entries of this matrix to a translation matrix. 370 * 371 * @param {number} dx 372 * The X delta 373 * @param {number} dy 374 * The Y delta. 375 * @param {number} dz 376 * The Z delta. 377 * @return {!threedee.Matrix} 378 * This matrix 379 */ 380 threedee.Matrix.prototype.setTranslate = function(dx, dy, dz) 381 { 382 return this.set( 383 1, 0, 0, dx, 384 0, 1, 0, dy, 385 0, 0, 1, dz, 386 0, 0, 0, 1); 387 }; 388 389 /** 390 * Sets the entries of this matrix to a X translation matrix. 391 * 392 * @param {number} d 393 * The delta 394 * @return {!threedee.Matrix} 395 * This matrix 396 */ 397 threedee.Matrix.prototype.setTranslateX = function(d) 398 { 399 return this.set( 400 1, 0, 0, d, 401 0, 1, 0, 0, 402 0, 0, 1, 0, 403 0, 0, 0, 1); 404 }; 405 406 /** 407 * Sets the entries of this matrix to a Y translation matrix. 408 * 409 * @param {number} d 410 * The delta 411 * @return {!threedee.Matrix} 412 * This matrix 413 */ 414 threedee.Matrix.prototype.setTranslateY = function(d) 415 { 416 return this.set( 417 1, 0, 0, 0, 418 0, 1, 0, d, 419 0, 0, 1, 0, 420 0, 0, 0, 1); 421 }; 422 423 /** 424 * Sets the entries of this matrix to a Z translation matrix. 425 * 426 * @param {number} d 427 * The delta 428 * @return {!threedee.Matrix} 429 * This matrix 430 */ 431 threedee.Matrix.prototype.setTranslateZ = function(d) 432 { 433 return this.set( 434 1, 0, 0, 0, 435 0, 1, 0, 0, 436 0, 0, 1, d, 437 0, 0, 0, 1); 438 }; 439 440 /** 441 * Multiplies this matrix with the specified matrix. The result is written 442 * to this matrix. 443 * 444 * @param {!threedee.Matrix} m 445 * The other matrix 446 * @return {!threedee.Matrix} 447 * This matrix 448 */ 449 threedee.Matrix.prototype.transform = function(m) 450 { 451 return this.set(this.m00 * m.m00 + this.m01 * m.m10 + this.m02 452 * m.m20 + this.m03 * m.m30, this.m00 * m.m01 + this.m01 * m.m11 453 + this.m02 * m.m21 + this.m03 * m.m31, this.m00 * m.m02 + this.m01 454 * m.m12 + this.m02 * m.m22 + this.m03 * m.m32, this.m00 * m.m03 455 + this.m01 * m.m13 + this.m02 * m.m23 + this.m03 * m.m33, 456 457 this.m10 * m.m00 + this.m11 * m.m10 + this.m12 * m.m20 + this.m13 458 * m.m30, this.m10 * m.m01 + this.m11 * m.m11 + this.m12 * m.m21 459 + this.m13 * m.m31, this.m10 * m.m02 + this.m11 * m.m12 + this.m12 460 * m.m22 + this.m13 * m.m32, this.m10 * m.m03 + this.m11 * m.m13 461 + this.m12 * m.m23 + this.m13 * m.m33, 462 463 this.m20 * m.m00 + this.m21 * m.m10 + this.m22 * m.m20 + this.m23 464 * m.m30, this.m20 * m.m01 + this.m21 * m.m11 + this.m22 * m.m21 465 + this.m23 * m.m31, this.m20 * m.m02 + this.m21 * m.m12 + this.m22 466 * m.m22 + this.m23 * m.m32, this.m20 * m.m03 + this.m21 * m.m13 467 + this.m22 * m.m23 + this.m23 * m.m33, 468 469 this.m30 * m.m00 + this.m31 * m.m10 + this.m32 * m.m20 + this.m33 470 * m.m30, this.m30 * m.m01 + this.m31 * m.m11 + this.m32 * m.m21 471 + this.m33 * m.m31, this.m30 * m.m02 + this.m31 * m.m12 + this.m32 472 * m.m22 + this.m33 * m.m32, this.m30 * m.m03 + this.m31 * m.m13 473 + this.m32 * m.m23 + this.m33 * m.m33); 474 }; 475 476 /** 477 * Multiplies this matrix with the specified factor. 478 * 479 * @param {number} f 480 * The factor 481 * @return {!threedee.Matrix} 482 * This matrix 483 */ 484 threedee.Matrix.prototype.multiply = function(f) 485 { 486 this.m00 *= f; 487 this.m01 *= f; 488 this.m02 *= f; 489 this.m03 *= f; 490 this.m10 *= f; 491 this.m11 *= f; 492 this.m12 *= f; 493 this.m13 *= f; 494 this.m20 *= f; 495 this.m21 *= f; 496 this.m22 *= f; 497 this.m23 *= f; 498 this.m30 *= f; 499 this.m31 *= f; 500 this.m32 *= f; 501 this.m33 *= f; 502 return this; 503 }; 504 505 /** 506 * Divides this matrix by the specified factor. 507 * 508 * @param {number} f 509 * The factor 510 * @return {!threedee.Matrix} 511 * This matrix 512 */ 513 threedee.Matrix.prototype.divide = function(f) 514 { 515 this.m00 /= f; 516 this.m01 /= f; 517 this.m02 /= f; 518 this.m03 /= f; 519 this.m10 /= f; 520 this.m11 /= f; 521 this.m12 /= f; 522 this.m13 /= f; 523 this.m20 /= f; 524 this.m21 /= f; 525 this.m22 /= f; 526 this.m23 /= f; 527 this.m30 /= f; 528 this.m31 /= f; 529 this.m32 /= f; 530 this.m33 /= f; 531 return this; 532 }; 533 534 /** 535 * Translates this matrix by the specified deltas 536 * 537 * @param {number} dx 538 * The X delta 539 * @param {number} dy 540 * The Y delta 541 * @param {number} dz 542 * The Z delta 543 * @return {!threedee.Matrix} 544 * This matrix 545 */ 546 threedee.Matrix.prototype.translate = function(dx, dy, dz) 547 { 548 return this.transform(threedee.Matrix.TMP.setTranslate(dx, dy, dz)); 549 }; 550 551 /** 552 * X-Translates this matrix by the specified delta 553 * 554 * @param {number} d 555 * The delta 556 * @return {!threedee.Matrix} 557 * This matrix 558 */ 559 threedee.Matrix.prototype.translateX = function(d) 560 { 561 return this.transform(threedee.Matrix.TMP.setTranslateX(d)); 562 }; 563 564 /** 565 * Y-Translates this matrix by the specified delta 566 * 567 * @param {number} d 568 * The delta 569 * @return {!threedee.Matrix} 570 * This matrix 571 */ 572 threedee.Matrix.prototype.translateY = function(d) 573 { 574 return this.transform(threedee.Matrix.TMP.setTranslateY(d)); 575 }; 576 577 /** 578 * Z-Translates this matrix by the specified delta 579 * 580 * @param {number} d 581 * The delta 582 * @return {!threedee.Matrix} 583 * This matrix 584 */ 585 threedee.Matrix.prototype.translateZ = function(d) 586 { 587 return this.transform(threedee.Matrix.TMP.setTranslateZ(d)); 588 }; 589 590 /** 591 * Scales this matrix by the specified factors 592 * 593 * @param {number} fx 594 * The X factor 595 * @param {number} fy 596 * The Y factor. Optional. Defaults to fx. 597 * @param {number} fz 598 * The Z factor. Optional. Defaults to fx. 599 * @return {!threedee.Matrix} 600 * This matrix 601 */ 602 threedee.Matrix.prototype.scale = function(fx, fy, fz) 603 { 604 return this.transform(threedee.Matrix.TMP.setScale(fx, 605 fy === undefined ? fx : fy, fz === undefined ? fx : fz)); 606 }; 607 608 /** 609 * X-Scales this matrix by the specified factor 610 * 611 * @param {number} f 612 * The factor 613 * @return {!threedee.Matrix} 614 * This matrix 615 */ 616 threedee.Matrix.prototype.scaleX = function(f) 617 { 618 return this.transform(threedee.Matrix.TMP.setScaleX(f)); 619 }; 620 621 /** 622 * Y-Scales this matrix by the specified factor 623 * 624 * @param {number} f 625 * The factor 626 * @return {!threedee.Matrix} 627 * This matrix 628 */ 629 threedee.Matrix.prototype.scaleY = function(f) 630 { 631 return this.transform(threedee.Matrix.TMP.setScaleY(f)); 632 }; 633 634 /** 635 * Z-Scales this matrix by the specified factor 636 * 637 * @param {number} f 638 * The factor 639 * @return {!threedee.Matrix} 640 * This matrix 641 */ 642 threedee.Matrix.prototype.scaleZ = function(f) 643 { 644 return this.transform(threedee.Matrix.TMP.setScaleZ(f)); 645 }; 646 647 /** 648 * X-Rotates this matrix by the specified angle 649 * 650 * @param {number} r 651 * The angle in clock-wise RAD 652 * @return {!threedee.Matrix} 653 * This matrix 654 */ 655 threedee.Matrix.prototype.rotateX = function(r) 656 { 657 return this.transform(threedee.Matrix.TMP.setRotateX(r)); 658 }; 659 660 /** 661 * Y-Rotates this matrix by the specified angle 662 * 663 * @param {number} r 664 * The angle in clock-wise RAD 665 * @return {!threedee.Matrix} 666 * This matrix 667 */ 668 threedee.Matrix.prototype.rotateY = function(r) 669 { 670 return this.transform(threedee.Matrix.TMP.setRotateY(r)); 671 }; 672 673 /** 674 * Z-Rotates this matrix by the specified angle 675 * 676 * @param {number} r 677 * The angle in clock-wise RAD 678 * @return {!threedee.Matrix} 679 * This matrix 680 */ 681 threedee.Matrix.prototype.rotateZ = function(r) 682 { 683 return this.transform(threedee.Matrix.TMP.setRotateZ(r)); 684 }; 685 686 /** 687 * Returns the determinant of the matrix. 688 * 689 * @return {number} The determinant of the matrix 690 */ 691 threedee.Matrix.prototype.getDeterminant = function() 692 { 693 return this.m03 * this.m12 * this.m21 * this.m30 - this.m02 694 * this.m13 * this.m21 * this.m30 - this.m03 * this.m11 695 * this.m22 * this.m30 + this.m01 * this.m13 * this.m22 696 * this.m30 + this.m02 * this.m11 * this.m23 * this.m30 697 - this.m01 * this.m12 * this.m23 * this.m30 - this.m03 698 * this.m12 * this.m20 * this.m31 + this.m02 * this.m13 699 * this.m20 * this.m31 + this.m03 * this.m10 * this.m22 700 * this.m31 - this.m00 * this.m13 * this.m22 * this.m31 701 - this.m02 * this.m10 * this.m23 * this.m31 + this.m00 702 * this.m12 * this.m23 * this.m31 + this.m03 * this.m11 703 * this.m20 * this.m32 - this.m01 * this.m13 * this.m20 704 * this.m32 - this.m03 * this.m10 * this.m21 * this.m32 705 + this.m00 * this.m13 * this.m21 * this.m32 + this.m01 706 * this.m10 * this.m23 * this.m32 - this.m00 * this.m11 707 * this.m23 * this.m32 - this.m02 * this.m11 * this.m20 708 * this.m33 + this.m01 * this.m12 * this.m20 * this.m33 709 + this.m02 * this.m10 * this.m21 * this.m33 - this.m00 710 * this.m12 * this.m21 * this.m33 - this.m01 * this.m10 711 * this.m22 * this.m33 + this.m00 * this.m11 * this.m22 712 * this.m33; 713 }; 714 715 /** 716 * Inverts this matrix. 717 * 718 * @return {!threedee.Matrix} 719 * This matrix 720 */ 721 threedee.Matrix.prototype.invert = function() 722 { 723 return this.set( 724 this.m12 * this.m23 * this.m31 - this.m13 725 * this.m22 * this.m31 + this.m13 * this.m21 * this.m32 726 - this.m11 * this.m23 * this.m32 - this.m12 * this.m21 727 * this.m33 + this.m11 * this.m22 * this.m33, 728 729 this.m03 * this.m22 * this.m31 - this.m02 * this.m23 730 * this.m31 - this.m03 * this.m21 * this.m32 + this.m01 731 * this.m23 * this.m32 + this.m02 * this.m21 * this.m33 732 - this.m01 * this.m22 * this.m33, 733 734 this.m02 * this.m13 * this.m31 - this.m03 * this.m12 735 * this.m31 + this.m03 * this.m11 * this.m32 - this.m01 736 * this.m13 * this.m32 - this.m02 * this.m11 * this.m33 737 + this.m01 * this.m12 * this.m33, 738 739 this.m03 * this.m12 * this.m21 - this.m02 * this.m13 740 * this.m21 - this.m03 * this.m11 * this.m22 + this.m01 741 * this.m13 * this.m22 + this.m02 * this.m11 * this.m23 742 - this.m01 * this.m12 * this.m23, 743 744 this.m13 * this.m22 * this.m30 - this.m12 * this.m23 745 * this.m30 - this.m13 * this.m20 * this.m32 + this.m10 746 * this.m23 * this.m32 + this.m12 * this.m20 * this.m33 747 - this.m10 * this.m22 * this.m33, 748 749 this.m02 * this.m23 * this.m30 - this.m03 * this.m22 750 * this.m30 + this.m03 * this.m20 * this.m32 - this.m00 751 * this.m23 * this.m32 - this.m02 * this.m20 * this.m33 752 + this.m00 * this.m22 * this.m33, 753 754 this.m03 * this.m12 * this.m30 - this.m02 * this.m13 755 * this.m30 - this.m03 * this.m10 * this.m32 + this.m00 756 * this.m13 * this.m32 + this.m02 * this.m10 * this.m33 757 - this.m00 * this.m12 * this.m33, 758 759 this.m02 * this.m13 * this.m20 - this.m03 * this.m12 760 * this.m20 + this.m03 * this.m10 * this.m22 - this.m00 761 * this.m13 * this.m22 - this.m02 * this.m10 * this.m23 762 + this.m00 * this.m12 * this.m23, 763 764 this.m11 * this.m23 * this.m30 - this.m13 * this.m21 765 * this.m30 + this.m13 * this.m20 * this.m31 - this.m10 766 * this.m23 * this.m31 - this.m11 * this.m20 * this.m33 767 + this.m10 * this.m21 * this.m33, 768 769 this.m03 * this.m21 * this.m30 - this.m01 * this.m23 770 * this.m30 - this.m03 * this.m20 * this.m31 + this.m00 771 * this.m23 * this.m31 + this.m01 * this.m20 * this.m33 772 - this.m00 * this.m21 * this.m33, 773 774 this.m01 * this.m13 * this.m30 - this.m03 * this.m11 775 * this.m30 + this.m03 * this.m10 * this.m31 - this.m00 776 * this.m13 * this.m31 - this.m01 * this.m10 * this.m33 777 + this.m00 * this.m11 * this.m33, 778 779 this.m03 * this.m11 * this.m20 - this.m01 * this.m13 780 * this.m20 - this.m03 * this.m10 * this.m21 + this.m00 781 * this.m13 * this.m21 + this.m01 * this.m10 * this.m23 782 - this.m00 * this.m11 * this.m23, 783 784 this.m12 * this.m21 * this.m30 - this.m11 * this.m22 785 * this.m30 - this.m12 * this.m20 * this.m31 + this.m10 786 * this.m22 * this.m31 + this.m11 * this.m20 * this.m32 787 - this.m10 * this.m21 * this.m32, 788 789 this.m01 * this.m22 * this.m30 - this.m02 * this.m21 790 * this.m30 + this.m02 * this.m20 * this.m31 - this.m00 791 * this.m22 * this.m31 - this.m01 * this.m20 * this.m32 792 + this.m00 * this.m21 * this.m32, 793 794 this.m02 * this.m11 * this.m30 - this.m01 * this.m12 795 * this.m30 - this.m02 * this.m10 * this.m31 + this.m00 796 * this.m12 * this.m31 + this.m01 * this.m10 * this.m32 797 - this.m00 * this.m11 * this.m32, 798 799 this.m01 * this.m12 * this.m20 - this.m02 * this.m11 800 * this.m20 + this.m02 * this.m10 * this.m21 - this.m00 801 * this.m12 * this.m21 - this.m01 * this.m10 * this.m22 802 + this.m00 * this.m11 * this.m22).divide(this.getDeterminant()); 803 }; 804