1 /* 2 SpiderGL Computer Graphics Library 3 Copyright (c) 2010, Marco Di Benedetto - Visual Computing Lab, ISTI - CNR 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 * Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 10 * Redistributions in binary form must reproduce the above copyright 11 notice, this list of conditions and the following disclaimer in the 12 documentation and/or other materials provided with the distribution. 13 * Neither the name of SpiderGL nor the 14 names of its contributors may be used to endorse or promote products 15 derived from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY 21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @fileOverview Space 31 */ 32 33 /** 34 * The SpiderGL.Space namespace. 35 * 36 * @namespace The SpiderGL.Space namespace. 37 */ 38 SpiderGL.Space = { }; 39 40 /** 41 * Creates a SpiderGL.Space.MatrixStack. 42 * 43 * SpiderGL.Space.MatrixStack is a stack for 4x4 matrices. Initially, the stack depth is one and contains an identity matrix. 44 * Every method or getter to access the top matrix (or a derivation like inverse or transpose) returns a copy of the internal matrix. 45 * For performance reasons, variants of the above accessors (having the same identifier with the postfix "$" appended) that return a reference to the internal matrix are also present. 46 * The transpose, inverse, and inverse-transpose of the top matrix are calculated and cached when they are accessed. 47 * 48 * @class The SpiderGL.Space.MatrixStack is a stack for 4x4 matrices. 49 * 50 * @augments SpiderGL.Core.ObjectBase 51 * 52 * @param {function(this)} [onChange] A callback function called whenever the stack is modified. 53 * 54 * @example 55 * var s = new SpiderGL.Space.MatrixStack(); 56 * s.loadIdentity(); 57 * s.scale([2, 0.5, 2]); 58 * for (var i=0; i<n; ++i) { 59 * s.push(); 60 * s.translate(positions[i]); 61 * matrices[i] = { 62 * m : s.matrix, 63 * i : s.inverse, 64 * t : s.transpose, 65 * it : s.inverseTranspose 66 * }; 67 * s.pop(); 68 * } 69 * 70 * @see reset 71 * @see SpiderGL.Space.TransformationStack 72 */ 73 SpiderGL.Space.MatrixStack = function (onChange) { 74 SpiderGL.Core.ObjectBase.call(this); 75 76 this._onChange = null; 77 this.reset(); 78 this._onChange = onChange; 79 } 80 81 SpiderGL.Space.MatrixStack.prototype = { 82 _invalidate : function () { 83 this._i = null; 84 this._t = null; 85 this._it = null; 86 if (this._onChange) { 87 this._onChange(this); 88 } 89 }, 90 91 /** 92 * Resets the stack. 93 * The stack is reset to its initial state, that is, a stack with depth one containing the identity matrix. 94 * 95 * @see SpiderGL.Math.Mat4.identity 96 */ 97 reset : function () { 98 var m = SpiderGL.Math.Mat4.identity(); 99 this._s = [ m ]; 100 this._l = 1; 101 this._m = m; 102 this._i = m; 103 this._t = m; 104 this._it = m; 105 if (this._onChange) { 106 this._onChange(this); 107 } 108 }, 109 110 /** 111 * Gets/Sets the callback invoked whenever the top matrix changes. 112 * Initially, no callback is defined. 113 * 114 * @event 115 */ 116 get onChange() { 117 return this._onChange; 118 }, 119 120 set onChange(f) { 121 this._onChange = f; 122 }, 123 124 /** 125 * Gets the stack depth. 126 * Initially, the stack contains an identity matrix, so its depth is one. 127 * 128 * @type number 129 * 130 * @readonly 131 */ 132 get size() { 133 return this._l; 134 }, 135 136 /** 137 * Gets a reference to the matrix at the top of the stack. 138 * The returned array MUST NOT be changed. 139 * Initially, the stack has depth one and contains an identity matrix. 140 * 141 * @type array 142 * 143 * @readonly 144 * 145 * @see #matrix 146 */ 147 get matrix$() { 148 return this._m; 149 }, 150 151 /** 152 * Gets a copy of the matrix at the top of the stack. 153 * Initially, the stack has depth one and contains an identity matrix. 154 * 155 * @type array 156 * 157 * @readonly 158 * 159 * @see #matrix$ 160 */ 161 get matrix() { 162 return SpiderGL.Math.Mat4.dup(this.matrix$); 163 }, 164 165 /** 166 * Alias for #matrix$. 167 * 168 * @type array 169 * 170 * @readonly 171 * 172 * @see #top 173 * @see #matrix$ 174 */ 175 get top$() { 176 return this.matrix$; 177 }, 178 179 /** 180 * Alias for #matrix. 181 * 182 * @type array 183 * 184 * @readonly 185 * 186 * @see #top$ 187 * @see #matrix 188 */ 189 get top() { 190 return this.matrix; 191 }, 192 193 /** 194 * Gets a reference to the inverse of the matrix at the top of the stack. 195 * The returned array MUST NOT be changed. 196 * 197 * @type array 198 * 199 * @readonly 200 * 201 * @see #inverse 202 */ 203 get inverse$() { 204 return (this._i || (this._i = SpiderGL.Math.Mat4.inverse(this._m))); 205 }, 206 207 /** 208 * Gets a copy of the inverse of the matrix at the top of the stack. 209 * 210 * @type array 211 * 212 * @readonly 213 * 214 * @see #inverse$ 215 */ 216 get inverse() { 217 return SpiderGL.Math.Mat4.dup(this.inverse$); 218 }, 219 220 /** 221 * Gets a reference to the transpose of the matrix at the top of the stack. 222 * The returned array MUST NOT be changed. 223 * 224 * @type array 225 * 226 * @readonly 227 * 228 * @see #transpose 229 */ 230 get transpose$() { 231 return (this._t || (this._t = SpiderGL.Math.Mat4.transpose(this._m))); 232 }, 233 234 /** 235 * Gets a copy of the transpose of the matrix at the top of the stack. 236 * 237 * @type array 238 * 239 * @readonly 240 * 241 * @see #transpose$ 242 */ 243 get transpose() { 244 return SpiderGL.Math.Mat4.dup(this.transpose$); 245 }, 246 247 /** 248 * Gets a reference to the transpose of the inverse of the matrix at the top of the stack. 249 * The returned array MUST NOT be changed. 250 * 251 * @type array 252 * 253 * @readonly 254 * 255 * @see #inverseTranspose 256 */ 257 get inverseTranspose$() { 258 return (this._it || (this._it = SpiderGL.Math.Mat4.transpose(this.inverse$))); 259 }, 260 261 /** 262 * Gets a copy of the transpose of the inverse of the matrix at the top of the stack. 263 * 264 * @type array 265 * 266 * @readonly 267 * 268 * @see #inverseTranspose$ 269 */ 270 get inverseTranspose() { 271 return SpiderGL.Math.Mat4.dup(this.inverseTranspose$); 272 }, 273 274 /** 275 * Pushes into the stack the matrix at its top. 276 * After a push operation, the stack depth is incremented by one and the two matrices at its top are identical. 277 * There is no limit on the depth the stack can reach. 278 * 279 * @see #pop 280 */ 281 push : function () { 282 var m = SpiderGL.Math.Mat4.dup(this._m); 283 this._s.push(m); 284 this._l++; 285 this._m = m; 286 }, 287 288 /** 289 * Pops the stack. 290 * After a pop operation, the stack depth is decremented by one. 291 * Nothing is done if the stack has only one element. 292 * 293 * @see #push 294 */ 295 pop : function () { 296 if (this._l <= 1) return; 297 this._s.pop(); 298 this._l--; 299 this._m = this._s[this._l - 1]; 300 this._invalidate(); 301 }, 302 303 /** 304 * Replaces the matrix at the top with a clone of the passed matrix. 305 * 306 * @param {array} m The matrix whose clone will be set as the top of the stack. 307 * 308 * @see #loadIdentity 309 * @see #multiply 310 * @see SpiderGL.Math.Mat4.dup 311 */ 312 load : function (m) { 313 m = SpiderGL.Math.Mat4.dup(m); 314 this._s[this._l - 1] = m; 315 this._m = m; 316 this._invalidate(); 317 }, 318 319 /** 320 * Replaces the matrix at the top with an identity matrix. 321 * 322 * @see #load 323 * @see #multiply 324 * @see SpiderGL.Math.Mat4.identity 325 * @see SpiderGL.Math.Mat4.identity$ 326 */ 327 loadIdentity : function () { 328 var m = SpiderGL.Math.Mat4.identity$(this._m); 329 this._i = m; 330 this._t = m; 331 this._it = m; 332 }, 333 334 /** 335 * Post-multiplies the matrix at the top with the passed matrix 336 * The matrix a at the top will be replaced by a * m. 337 * 338 * @param {array} m The matrix to post-multiply. 339 * 340 * @see #load 341 * @see SpiderGL.Math.Mat4.mul 342 * @see SpiderGL.Math.Mat4.mul$ 343 */ 344 multiply : function (m) { 345 SpiderGL.Math.Mat4.mul$(this._m, m); 346 this._invalidate(); 347 }, 348 349 /** 350 * Post-multiplies the matrix at the top with an ortographic projection matrix. 351 * 352 * @param {array} min The minimum coordinates of the parallel viewing volume. 353 * @param {array} max The maximum coordinates of the parallel viewing volume. 354 * 355 * @see #frustum 356 * @see #perspective 357 * @see SpiderGL.Math.Mat4.ortho 358 * @see SpiderGL.Math.Mat4.mul$ 359 */ 360 ortho : function (min, max) { 361 SpiderGL.Math.Mat4.mul$(this._m, SpiderGL.Math.Mat4.ortho(min, max)); 362 this._invalidate(); 363 }, 364 365 /** 366 * Post-multiplies the matrix at the top with a frustum matrix. 367 * 368 * @param {array} min A 3-component array with the minimum coordinates of the frustum volume. 369 * @param {array} max A 3-component array with the maximum coordinates of the frustum volume. 370 * 371 * @see #perspective 372 * @see #ortho 373 * @see SpiderGL.Math.Mat4.frustum 374 * @see SpiderGL.Math.Mat4.mul$ 375 */ 376 frustum : function (min, max) { 377 SpiderGL.Math.Mat4.mul$(this._m, SpiderGL.Math.Mat4.frustum(min, max)); 378 this._invalidate(); 379 }, 380 381 /** 382 * Post-multiplies the matrix at the top with a perspective projection matrix. 383 * 384 * @param {number} fovY The vertical field-of-view angle, in radians. 385 * @param {number} aspectRatio The projection plane aspect ratio. 386 * @param {number} zNear The distance of the near clipping plane. 387 * @param {number} zFar The distance of the far clipping plane. 388 * 389 * @see #frustum 390 * @see #ortho 391 * @see SpiderGL.Math.Mat4.perspective 392 * @see SpiderGL.Math.Mat4.mul$ 393 */ 394 perspective : function (fovY, aspectRatio, zNear, zFar) { 395 SpiderGL.Math.Mat4.mul$(this._m, SpiderGL.Math.Mat4.perspective(fovY, aspectRatio, zNear, zFar)); 396 this._invalidate(); 397 }, 398 399 /** 400 * Post-multiplies the matrix at the top with a look-at matrix. 401 * 402 * @param {array} position The viewer's position as a 3-dimensional vector. 403 * @param {array} target The viewer's look-at point as a 3-dimensional vector. 404 * @param {array} position The viewer's up vector as a 3-dimensional vector. 405 * 406 * @see SpiderGL.Math.Mat4.lookAt 407 * @see SpiderGL.Math.Mat4.mul$ 408 */ 409 lookAt : function (position, target, up) { 410 SpiderGL.Math.Mat4.mul$(this._m, SpiderGL.Math.Mat4.lookAt(position, target, up)); 411 this._invalidate(); 412 }, 413 414 /** 415 * Post-multiplies the matrix at the top with a translation matrix. 416 * 417 * @param {array} v A 3-dimensional vector with translation offsets. 418 * 419 * @see #rotate 420 * @see #scale 421 * @see SpiderGL.Math.Mat4.translation 422 * @see SpiderGL.Math.Mat4.translate$ 423 */ 424 translate : function (v) { 425 SpiderGL.Math.Mat4.translate$(this._m, v); 426 this._invalidate(); 427 }, 428 429 /** 430 * Post-multiplies the matrix at the top with a rotation matrix. 431 * 432 * @param {number} angle The counter-clockwise rotation angle, in radians. 433 * @param {array} axis A 3-dimensional vector representing the rotation axis. 434 * 435 * @see #translate 436 * @see #scale 437 * @see SpiderGL.Math.Mat4.rotationAngleAxis 438 * @see SpiderGL.Math.Mat4.rotateAngleAxis$ 439 */ 440 rotate : function (angle, axis) { 441 SpiderGL.Math.Mat4.rotateAngleAxis$(this._m, angle, axis); 442 this._invalidate(); 443 }, 444 445 /** 446 * Post-multiplies the matrix at the top with a scaling matrix. 447 * 448 * @param {array} v The scaling amount as a 3-dimensional array. 449 * 450 * @see #translate 451 * @see #rotate 452 * @see SpiderGL.Math.Mat4.scaling 453 * @see SpiderGL.Math.Mat4.scale$ 454 */ 455 scale : function (v) { 456 SpiderGL.Math.Mat4.scale$(this._m, v); 457 this._invalidate(); 458 } 459 }; 460 461 SpiderGL.Type.extend(SpiderGL.Space.MatrixStack, SpiderGL.Core.ObjectBase); 462 463 /** 464 * Creates a SpiderGL.Space.ViewportStack. 465 * 466 * SpiderGL.Space.ViewportStack is a stack for viewport rectangles, specified with lower and left coordinates, width and height. 467 * Initially, the stack depth is one and contains a rectangle with lower-eft coordinates equal to zero and width and height equal to one, that is, the array [0, 0, 1, 1]. 468 * Every method or getter to access the top rectangle returns a copy of the internal rectangle. 469 * For performance reasons, variants of the above accessors (having the same identifier with the postfix "$" appended) that return a reference to the internal rectangle are also present. 470 * 471 * @class The SpiderGL.Space.ViewportStack is a stack for viewport rectangles. 472 * 473 * @augments SpiderGL.Core.ObjectBase 474 * 475 * @param {function(this)} [onChange] A callback function called whenever the stack is modified. 476 * 477 * @example 478 * var s = new SpiderGL.Space.ViewportStack(); 479 * var dw = width / nx; 480 * var dh = height / ny; 481 * s.load(x, y, width, height); 482 * for (var x=0; x<nx; ++x) { 483 * for (var y=0; y<ny; ++y) { 484 * s.push(); 485 s.inner([x*dw, y*dh, dw, dh]); 486 viewports.push(s.rect); 487 * s.pop(); 488 * } 489 * 490 * @see reset 491 * @see SpiderGL.Space.TransformationStack 492 */ 493 SpiderGL.Space.ViewportStack = function (onChange) { 494 SpiderGL.Core.ObjectBase.call(this); 495 496 this._onChange = null; 497 this.reset(); 498 this._onChange = onChange; 499 } 500 501 SpiderGL.Space.ViewportStack.prototype = { 502 _invalidate : function () { 503 if (this._onChange) { 504 this._onChange(this); 505 } 506 }, 507 508 /** 509 * Resets the stack. 510 * The stack is reset to its initial state, that is, a stack with depth one containing the identity rectangle, that is, [0, 0, 1, 1]. 511 * 512 * @see #loadIdentity 513 */ 514 reset : function () { 515 var r = [0, 0, 1, 1]; 516 this._s = [ r ]; 517 this._l = 1; 518 this._r = r; 519 if (this._onChange) { 520 this._onChange(this); 521 } 522 }, 523 524 /** 525 * Gets/Sets the callback invoked whenever the top rectangle changes. 526 * Initially, no callback is defined. 527 * 528 * @event 529 */ 530 get onChange() { 531 return this._onChange; 532 }, 533 534 set onChange(f) { 535 this._onChange = f; 536 }, 537 538 /** 539 * Gets the stack depth. 540 * Initially, the stack contains the identity rectangle, that is, [0, 0, 1, 1]. 541 * 542 * @type number 543 * 544 * @readonly 545 */ 546 get size() { 547 return this._l; 548 }, 549 550 /** 551 * Gets a reference to the rectangle at the top of the stack. 552 * The returned array MUST NOT be changed. 553 * Initially, the stack has depth one and contains the identity rectangle, that is, [0, 0, 1, 1]. 554 * 555 * @type array 556 * 557 * @readonly 558 * 559 * @see #rect 560 */ 561 get rect$() { 562 return this._r; 563 }, 564 565 /** 566 * Gets a copy of the matrix at the top of the stack. 567 * Initially, the stack has depth one and contains the identity rectangle, that is, [0, 0, 1, 1]. 568 * 569 * @type array 570 * 571 * @readonly 572 * 573 * @see #rect$ 574 */ 575 get rect() { 576 return this.rect$.slice(0, 4); 577 }, 578 579 /** 580 * Alias for #rect$. 581 * 582 * @type array 583 * 584 * @readonly 585 * 586 * @see #top 587 * @see #rect$ 588 */ 589 get top$() { 590 return this.rect$; 591 }, 592 593 /** 594 * Alias for #rect. 595 * 596 * @type array 597 * 598 * @readonly 599 * 600 * @see #top$ 601 * @see #rect 602 */ 603 get top() { 604 return this.rect; 605 }, 606 607 /** 608 * Pushes into the stack the rectangle at its top. 609 * After a push operation, the stack depth is incremented by one and the two rectangle at its top are identical. 610 * There is no limit on the depth the stack can reach. 611 * 612 * @see #pop 613 */ 614 push : function () { 615 var r = this._r.slice(0, 4); 616 this._s.push(r); 617 this._l++; 618 this._r = r; 619 }, 620 621 /** 622 * Pops the stack. 623 * After a pop operation, the stack depth is decremented by one. 624 * Nothing is done if the stack has only one element. 625 * 626 * @see #push 627 */ 628 pop : function () { 629 if (this._l <= 1) return; 630 this._s.pop(); 631 this._l--; 632 this._r = this._s[this._l - 1]; 633 this._invalidate(); 634 }, 635 636 /** 637 * Replaces the rectangle at the top with a clone of the passed rectangle. 638 * 639 * @param {array} m The rectangle whose clone will be set as the top of the stack. 640 * 641 * @see #loadIdentity 642 * @see #inner 643 */ 644 load : function (r) { 645 r = r.slice(0, 4); 646 this._s[this._l - 1] = r; 647 this._r = r; 648 this._invalidate(); 649 }, 650 651 /** 652 * Replaces the rectangle at the top with the identity rectangle, that is, [0, 0, 1, 1]. 653 * 654 * @see #load 655 * @see #inner 656 */ 657 loadIdentity : function () { 658 var r = [0, 0, 1, 1]; 659 this._r = r; 660 }, 661 662 /** 663 * Replace the rectangle r at the top of the stack with Post-multiplies the matrix at the top with the passed matrix 664 * The matrix a at the top will be replaced by a * m. 665 * 666 * @param {array} m The matrix to post-multiply. 667 * 668 * @see #load 669 */ 670 inner : function (r) { 671 this._r[0] += r[0]; 672 this._r[1] += r[1]; 673 this._r[2] = r[2]; 674 this._r[3] = r[3]; 675 this._invalidate(); 676 } 677 }; 678 679 SpiderGL.Type.extend(SpiderGL.Space.ViewportStack, SpiderGL.Core.ObjectBase); 680 681 /** 682 * Creates a SpiderGL.Space.ViewportStack. 683 * 684 * SpiderGL.Space.ViewportStack is a stack for viewport rectangles, specified with lower and left coordinates, width and height. 685 * Initially, the stack depth is one and contains a rectangle with lower-eft coordinates equal to zero and width and height equal to one, that is, the array [0, 0, 1, 1]. 686 * Every method or getter to access the top rectangle returns a copy of the internal rectangle. 687 * For performance reasons, variants of the above accessors (having the same identifier with the postfix "$" appended) that return a reference to the internal rectangle are also present. 688 * 689 * @class The SpiderGL.Space.ViewportStack is a stack for viewport rectangles. 690 * 691 * @augments SpiderGL.Core.ObjectBase 692 * 693 * @param {function(this)} [onChange] A callback function called whenever the stack is modified. 694 * 695 * @example 696 * var s = new SpiderGL.Space.ViewportStack(); 697 * var dw = width / nx; 698 * var dh = height / ny; 699 * s.load(x, y, width, height); 700 * for (var x=0; x<nx; ++x) { 701 * for (var y=0; y<ny; ++y) { 702 * s.push(); 703 s.inner([0, 0, dw, dh]); 704 viewports.push(s.rect); 705 * s.pop(); 706 * } 707 * 708 * @see reset 709 * @see SpiderGL.Space.TransformationStack 710 */ 711 SpiderGL.Space.DepthRangeStack = function (onChange) { 712 SpiderGL.Core.ObjectBase.call(this); 713 714 this._onChange = null; 715 this.reset(); 716 this._onChange = onChange; 717 } 718 719 SpiderGL.Space.DepthRangeStack.prototype = { 720 _invalidate : function () { 721 if (this._onChange) { 722 this._onChange(this); 723 } 724 }, 725 726 /** 727 * Resets the stack. 728 * The stack is reset to its initial state, that is, a stack with depth one containing the identity rectangle, that is, [0, 0, 1, 1]. 729 * 730 * @see #loadIdentity 731 */ 732 reset : function () { 733 var r = [0, 1]; 734 this._s = [ r ]; 735 this._l = 1; 736 this._r = r; 737 if (this._onChange) { 738 this._onChange(this); 739 } 740 }, 741 742 /** 743 * Gets/Sets the callback invoked whenever the top rectangle changes. 744 * Initially, no callback is defined. 745 * 746 * @event 747 */ 748 get onChange() { 749 return this._onChange; 750 }, 751 752 set onChange(f) { 753 this._onChange = f; 754 }, 755 756 /** 757 * Gets the stack depth 758 * Initially, the stack contains an identity matrix, so its depth is one. 759 * 760 * @type number 761 * 762 * @readonly 763 */ 764 get size() { 765 return this._l; 766 }, 767 768 /** 769 * Gets a reference to the matrix at the top of the stack. 770 * The returned array MUST NOT be changed. 771 * Initially, the stack has depth one and contains an identity matrix. 772 * 773 * @type array 774 * 775 * @readonly 776 * 777 * @see #matrix 778 */ 779 get range$() { 780 return this._r; 781 }, 782 783 /** 784 * Gets a copy of the matrix at the top of the stack. 785 * Initially, the stack has depth one and contains an identity matrix. 786 * 787 * @type array 788 * 789 * @readonly 790 * 791 * @see #matrix$ 792 */ 793 get range() { 794 return this.range$.slice(0, 2); 795 }, 796 797 /** 798 * Alias for #rect$. 799 * 800 * @type array 801 * 802 * @readonly 803 * 804 * @see #top 805 * @see #rect$ 806 */ 807 get top$() { 808 return this.range$; 809 }, 810 811 /** 812 * Alias for #rect. 813 * 814 * @type array 815 * 816 * @readonly 817 * 818 * @see #top$ 819 * @see #rect 820 */ 821 get top() { 822 return this.range; 823 }, 824 825 /** 826 * Pushes into the stack the range at its top. 827 * After a push operation, the stack depth is incremented by one and the two rectangle at its top are identical. 828 * There is no limit on the depth the stack can reach. 829 * 830 * @see #pop 831 */ 832 push : function () { 833 var r = this._r.slice(0, 2); 834 this._s.push(r); 835 this._l++; 836 this._r = r; 837 }, 838 839 /** 840 * Pops the stack. 841 * After a pop operation, the stack depth is decremented by one. 842 * Nothing is done if the stack has only one element. 843 * 844 * @see #push 845 */ 846 pop : function () { 847 if (this._l <= 1) return; 848 this._s.pop(); 849 this._l--; 850 this._r = this._s[this._l - 1]; 851 this._invalidate(); 852 }, 853 854 /** 855 * Replaces the matrix at the top with a clone of the passed matrix. 856 * 857 * @param {array} m The matrix to push on the stack. The matrix actually pushed is a clone of m. 858 * 859 * @see #loadIdentity 860 * @see #multiply 861 * @see SpiderGL.Math.Mat4.dup 862 */ 863 load : function (r) { 864 r = r.slice(0, 2); 865 this._s[this._l - 1] = r; 866 this._r = r; 867 this._invalidate(); 868 }, 869 870 /** 871 * Replaces the matrix at the top with an identity matrix. 872 * 873 * @see #load 874 * @see #multiply 875 * @see SpiderGL.Math.Mat4.identity 876 * @see SpiderGL.Math.Mat4.identity$ 877 */ 878 loadIdentity : function () { 879 var r = [0, 1]; 880 this._r = r; 881 }, 882 883 /** 884 * Post-multiplies the matrix at the top with the passed matrix 885 * The matrix a at the top will be replaced by a * m. 886 * 887 * @param {array} m The matrix to post-multiply. 888 * 889 * @see #load 890 */ 891 inner : function (r) { 892 this._r[0] += r[0]; 893 this._r[1] = r[1]; 894 this._invalidate(); 895 } 896 }; 897 898 SpiderGL.Type.extend(SpiderGL.Space.DepthRangeStack, SpiderGL.Core.ObjectBase); 899 900 /** 901 * Creates a SpiderGL.Space.TransformationStack. 902 * 903 * The purpose of SpiderGL.Space.TransformationStack is to provide transformation stack similar to the one in the fixed-pipeline versions of OpenGL. 904 * Differently from OpenGL, which has two stacks, namely MODELVIEW and PRIJECTION, the SpiderGL.Space.TransformationStack is composed of three SpiderGL.Space.MatrixStack stacks: model, view and projection. 905 * All three stacks can be directly accessed, as well as utility getters to obtain compositions of matrices, e.g. model-view-projection, model-view-inverse etc. 906 * To avoid recalculation of several sub-products, matrix compositions and variations are cached and updated when stack operations occur. 907 * 908 * @class The SpiderGL.Space.TransformationStack holds the model, view and projection matrix stacks and calculates their matrix compositions. 909 * 910 * @augments SpiderGL.Core.ObjectBase 911 * 912 * @example 913 * var xform = new SpiderGL.Space.TransformationStack(); 914 * 915 * var uniforms = { 916 * uModelViewprojection : null, 917 * uNormalMatrix : null, 918 * uColor : null 919 * }; 920 * 921 * program.bind(); 922 * 923 * xform.projection.loadIdentity(); 924 * xform.projection.perspective(SpiderGL.Math.degToRad(60.0), width/height, 0.1, 100.0); 925 * 926 * xform.view.loadIdentity(); 927 * xform.view.lookAt([0, 0, 10], [0, 0, 0], [0, 1, 0]); 928 * 929 * xform.model.loadIdentity(); 930 * xform.model.scale([0.1, 0.1, 0.1]); 931 * 932 * for (var i=0; i<n; ++i) { 933 * s.push(); 934 * s.translate(models[i].positions); 935 * uniforms.uModelViewProjection = xform.modelViewProjectionMatrix; 936 * uniforms.uNormalMatrix = xform.modelSpaceNormalMatrix; 937 * uniforms.uColor = models[i].color; 938 * program.setUniforms(uniforms); 939 * drawModel(models[i]); 940 * s.pop(); 941 * } 942 * 943 * @see reset 944 * @see SpiderGL.Space.MatrixStack 945 */ 946 SpiderGL.Space.TransformationStack = function () { 947 SpiderGL.Core.ObjectBase.call(this); 948 949 var that = this; 950 951 this._mv = { }; 952 this._vp = { }; 953 this._mvp = { }; 954 this._n = { }; 955 this._c = { }; 956 957 this._m = new SpiderGL.Space.MatrixStack(function(){ 958 that._mv = { }; 959 that._mvp = { }; 960 that._n = { }; 961 that._c = { }; 962 }); 963 964 this._v = new SpiderGL.Space.MatrixStack(function(){ 965 that._mv = { }; 966 that._vp = { }; 967 that._mvp = { }; 968 that._n = { }; 969 that._c = { }; 970 }); 971 972 this._p = new SpiderGL.Space.MatrixStack(function(){ 973 that._vp = { }; 974 that._mvp = { }; 975 }); 976 977 this._viewport = new SpiderGL.Space.ViewportStack(function(){ 978 }); 979 980 this._depth = new SpiderGL.Space.DepthRangeStack(function(){ 981 }); 982 } 983 984 SpiderGL.Space.TransformationStack.prototype = { 985 /** 986 * Resets the three stacks. 987 * 988 * @see SpiderGL.Space.MatrixStack.reset 989 */ 990 reset : function () { 991 this._m.reset(); 992 this._v.reset(); 993 this._p.reset(); 994 }, 995 996 /** 997 * Gets the viewport stack. 998 * 999 * @type SpiderGL.Space.ViewportStack 1000 * 1001 * @see depthRange 1002 */ 1003 get viewport() { 1004 return this._viewport; 1005 }, 1006 1007 get viewportRect$() { 1008 return this._viewport.rect$; 1009 }, 1010 1011 get viewportRect() { 1012 return this._viewport.rect; 1013 }, 1014 1015 /** 1016 * Gets the depth range stack. 1017 * 1018 * @type SpiderGL.Space.DepthRangeStack 1019 * 1020 * @see viewport 1021 */ 1022 get depth() { 1023 return this._depth; 1024 }, 1025 1026 get depthRange$() { 1027 return this._depth.range$; 1028 }, 1029 1030 get depthRange() { 1031 return this._depth.range; 1032 }, 1033 1034 /** 1035 * Gets the model stack. 1036 * 1037 * @type SpiderGL.Space.MatrixStack 1038 * 1039 * @see view 1040 * @see projection 1041 */ 1042 get model() { 1043 return this._m; 1044 }, 1045 1046 /** 1047 * Gets a reference to the top matrix of the model stack. 1048 * The returned array MUST NOT be changed. 1049 * 1050 * @see modelMatrix 1051 * @see SpiderGL.Space.MatrixStack.matrix$ 1052 */ 1053 get modelMatrix$() { 1054 return this._m.matrix$; 1055 }, 1056 1057 /** 1058 * Gets a copy of the top matrix of the model stack. 1059 * 1060 * @type array 1061 * 1062 * @see modelMatrix$ 1063 * @see SpiderGL.Space.MatrixStack.matrix 1064 */ 1065 get modelMatrix() { 1066 return this._m.matrix; 1067 }, 1068 1069 /** 1070 * Gets a reference to the inverse of the top matrix of the model stack. 1071 * The returned array MUST NOT be changed. 1072 * 1073 * @type array 1074 * 1075 * @see modelMatrixInverse 1076 * @see SpiderGL.Space.MatrixStack.inverse$ 1077 */ 1078 get modelMatrixInverse$() { 1079 return this._m.inverse$; 1080 }, 1081 1082 /** 1083 * Gets a copy of the inverse of the top matrix of the model stack. 1084 * 1085 * @type array 1086 * 1087 * @see modelMatrixInverse$ 1088 * @see SpiderGL.Space.MatrixStack.inverse 1089 */ 1090 get modelMatrixInverse() { 1091 return this._m.inverse; 1092 }, 1093 1094 /** 1095 * Gets a reference to the transpose of the top matrix of the model stack. 1096 * The returned array MUST NOT be changed. 1097 * 1098 * @type array 1099 * 1100 * @see modelMatrixTranspose 1101 * @see SpiderGL.Space.MatrixStack.transpose$ 1102 */ 1103 get modelMatrixTranspose$() { 1104 return this._m.transpose$; 1105 }, 1106 1107 /** 1108 * Gets a copy of the transpose of the top matrix of the model stack. 1109 * 1110 * @type array 1111 * 1112 * @see modelMatrixTranspose$ 1113 * @see SpiderGL.Space.MatrixStack.transpose 1114 */ 1115 get modelMatrixTranspose() { 1116 return this._m.transpose; 1117 }, 1118 1119 /** 1120 * Gets a reference to the transpose of the inverse of the top matrix of the model stack. 1121 * The returned array MUST NOT be changed. 1122 * 1123 * @type array 1124 * 1125 * @see modelMatrixInverseTranspose 1126 * @see SpiderGL.Space.MatrixStack.inverseTranspose$ 1127 */ 1128 get modelMatrixInverseTranspose$() { 1129 return this._m.inverseTranspose$; 1130 }, 1131 1132 /** 1133 * Gets a copy of the transpose of the inverse of the top matrix of the model stack. 1134 * 1135 * @type array 1136 * 1137 * @see modelMatrixInverseTranspose$ 1138 * @see SpiderGL.Space.MatrixStack.inverseTranspose 1139 */ 1140 get modelMatrixInverseTranspose() { 1141 return this._m.inverseTranspose; 1142 }, 1143 1144 /** 1145 * Gets the view stack. 1146 * 1147 * @type SpiderGL.Space.MatrixStack 1148 * 1149 * @see model 1150 * @see projection 1151 */ 1152 get view() { 1153 return this._v; 1154 }, 1155 1156 /** 1157 * Gets a reference to the top matrix of the view stack. 1158 * The returned array MUST NOT be changed. 1159 * 1160 * @type array 1161 * 1162 * @see viewMatrix 1163 * @see SpiderGL.Space.MatrixStack.matrix$ 1164 */ 1165 get viewMatrix$() { 1166 return this._v.matrix$; 1167 }, 1168 1169 /** 1170 * Gets a copy of the top matrix of the view stack. 1171 * 1172 * @type array 1173 * 1174 * @see viewMatrix$ 1175 * @see SpiderGL.Space.MatrixStack.matrix 1176 */ 1177 get viewMatrix() { 1178 return this._v.matrix; 1179 }, 1180 1181 /** 1182 * Gets a reference to the inverse of the top matrix of the view stack. 1183 * The returned array MUST NOT be changed. 1184 * 1185 * @type array 1186 * 1187 * @see viewMatrixInverse 1188 * @see SpiderGL.Space.MatrixStack.inverse$ 1189 */ 1190 get viewMatrixInverse$() { 1191 return this._v.inverse$; 1192 }, 1193 1194 /** 1195 * Gets a copy of the inverse of the top matrix of the view stack. 1196 * 1197 * @type array 1198 * 1199 * @see viewMatrixInverse$ 1200 * @see SpiderGL.Space.MatrixStack.inverse 1201 */ 1202 get viewMatrixInverse() { 1203 return this._v.inverse; 1204 }, 1205 1206 /** 1207 * Gets a reference to the transpose of the top matrix of the view stack. 1208 * The returned array MUST NOT be changed. 1209 * 1210 * @type array 1211 * 1212 * @see viewMatrixTranspose 1213 * @see SpiderGL.Space.MatrixStack.transpose$ 1214 */ 1215 get viewMatrixTranspose$() { 1216 return this._v.transpose$; 1217 }, 1218 1219 /** 1220 * Gets a copy of the transpose of the top matrix of the view stack. 1221 * 1222 * @type array 1223 * 1224 * @see viewMatrixTranspose$ 1225 * @see SpiderGL.Space.MatrixStack.transpose 1226 */ 1227 get viewMatrixTranspose() { 1228 return this._v.transpose; 1229 }, 1230 1231 /** 1232 * Gets a reference to the transpose of the inverse of the top matrix of the view stack. 1233 * The returned array MUST NOT be changed. 1234 * 1235 * @type array 1236 * 1237 * @see viewMatrixInverseTranspose 1238 * @see SpiderGL.Space.MatrixStack.inverseTranspose$ 1239 */ 1240 get viewMatrixInverseTranspose$() { 1241 return this._v.inverseTranspose$; 1242 }, 1243 1244 /** 1245 * Gets a copy of the transpose of the inverse of the top matrix of the view stack. 1246 * 1247 * @type array 1248 * 1249 * @see viewMatrixInverseTranspose$ 1250 * @see SpiderGL.Space.MatrixStack.inverseTranspose 1251 */ 1252 get viewMatrixInverseTranspose() { 1253 return this._v.inverseTranspose; 1254 }, 1255 1256 /** 1257 * Gets the projection stack. 1258 * 1259 * @type SpiderGL.Space.MatrixStack 1260 * 1261 * @see model 1262 * @see view 1263 */ 1264 get projection() { 1265 return this._p; 1266 }, 1267 1268 /** 1269 * Gets a reference to the top matrix of the projection stack. 1270 * The returned array MUST NOT be changed. 1271 * 1272 * @type array 1273 * 1274 * @see projectionMatrix 1275 * @see SpiderGL.Space.MatrixStack.matrix$ 1276 */ 1277 get projectionMatrix$() { 1278 return this._p.matrix$; 1279 }, 1280 1281 /** 1282 * Gets a copy of the top matrix of the projection stack. 1283 * 1284 * @type array 1285 * 1286 * @see projectionMatrix$ 1287 * @see SpiderGL.Space.MatrixStack.matrix 1288 */ 1289 get projectionMatrix() { 1290 return this._p.matrix; 1291 }, 1292 1293 /** 1294 * Gets a reference to the inverse of the top matrix of the projection stack. 1295 * The returned array MUST NOT be changed. 1296 * 1297 * @type array 1298 * 1299 * @see projectionMatrixInverse 1300 * @see SpiderGL.Space.MatrixStack.inverse$ 1301 */ 1302 get projectionMatrixInverse$() { 1303 return this._p.inverse$; 1304 }, 1305 1306 /** 1307 * Gets a copy of the inverse of the top matrix of the projection stack. 1308 * 1309 * @type array 1310 * 1311 * @see projectionMatrixInverse$ 1312 * @see SpiderGL.Space.MatrixStack.inverse 1313 */ 1314 get projectionMatrixInverse() { 1315 return this._p.inverse; 1316 }, 1317 1318 /** 1319 * Gets a reference to the transpose of the top matrix of the projection stack. 1320 * The returned array MUST NOT be changed. 1321 * 1322 * @type array 1323 * 1324 * @see projectionMatrixTranspose 1325 * @see SpiderGL.Space.MatrixStack.transpose$ 1326 */ 1327 get projectionMatrixTranspose$() { 1328 return this._p.transpose$; 1329 }, 1330 1331 /** 1332 * Gets a copy of the transpose of the top matrix of the projection stack. 1333 * 1334 * @type array 1335 * 1336 * @see projectionMatrixTranspose$ 1337 * @see SpiderGL.Space.MatrixStack.transpose 1338 */ 1339 get projectionMatrixTranspose() { 1340 return this._p.transpose; 1341 }, 1342 1343 /** 1344 * Gets a reference to the transpose of the inverse of the top matrix of the projection stack. 1345 * The returned array MUST NOT be changed. 1346 * 1347 * @type array 1348 * 1349 * @see projectionMatrixInverseTranspose 1350 * @see SpiderGL.Space.MatrixStack.inverseTranspose$ 1351 */ 1352 get projectionMatrixInverseTranspose$() { 1353 return this._p.inverseTranspose$; 1354 }, 1355 1356 /** 1357 * Gets a copy of the transpose of the inverse of the top matrix of the projection stack. 1358 * 1359 * @type array 1360 * 1361 * @see projectionMatrixInverseTranspose$ 1362 * @see SpiderGL.Space.MatrixStack.inverseTranspose 1363 */ 1364 get projectionMatrixInverseTranspose() { 1365 return this._p.inverseTranspose; 1366 }, 1367 1368 /** 1369 * Gets a reference to the matrix T = V * M, where V is the view matrix and M the model matrix. 1370 * The returned array MUST NOT be changed. 1371 * 1372 * @type array 1373 * 1374 * @see modelViewMatrix 1375 */ 1376 get modelViewMatrix$() { 1377 return (this._mv.m || (this._mv.m = SpiderGL.Math.Mat4.mul(this.viewMatrix$, this.modelMatrix$))); 1378 }, 1379 1380 /** 1381 * Gets a copy of the matrix T = V * M, where V is the view matrix and M the model matrix. 1382 * 1383 * @type array 1384 * 1385 * @see modelViewMatrix$ 1386 */ 1387 get modelViewMatrix() { 1388 return SpiderGL.Math.Mat4.dup(this.modelViewMatrix$); 1389 }, 1390 1391 /** 1392 * Gets a reference to the inverse of the matrix T = V * M, where V is the view matrix and M the model matrix. 1393 * The returned array MUST NOT be changed. 1394 * 1395 * @type array 1396 * 1397 * @see modelViewMatrixInverse 1398 */ 1399 get modelViewMatrixInverse$() { 1400 return (this._mv.i || (this._mv.i = SpiderGL.Math.Mat4.mul(this.modelMatrixInverse$, this.viewMatrixInverse$))); 1401 }, 1402 1403 /** 1404 * Gets a copy of the inverse of the matrix T = V * M, where V is the view matrix and M the model matrix. 1405 * 1406 * @type array 1407 * 1408 * @see modelViewMatrixInverse$ 1409 */ 1410 get modelViewMatrixInverse() { 1411 return SpiderGL.Math.Mat4.dup(this.modelViewMatrixInverse$); 1412 }, 1413 1414 /** 1415 * Gets a reference to the transpose of the matrix T = V * M, where V is the view matrix and M the model matrix. 1416 * The returned array MUST NOT be changed. 1417 * 1418 * @type array 1419 * 1420 * @see modelViewMatrixTranspose 1421 */ 1422 get modelViewMatrixTranspose$() { 1423 return (this._mv.t || (this._mv.t = SpiderGL.Math.Mat4.transpose(this.modelViewMatrix$))); 1424 }, 1425 1426 /** 1427 * Gets a copy of the transpose of the matrix T = V * M, where V is the view matrix and M the model matrix. 1428 * 1429 * @type array 1430 * 1431 * @see modelViewMatrixTranspose$ 1432 */ 1433 get modelViewMatrixTranspose() { 1434 return SpiderGL.Math.Mat4.dup(this.modelViewMatrixTranspose$); 1435 }, 1436 1437 /** 1438 * Gets a reference to the transpose of the inverse of the matrix T = V * M, where V is the view matrix and M the model matrix. 1439 * The returned array MUST NOT be changed. 1440 * 1441 * @type array 1442 * 1443 * @see modelViewMatrixInverseTranspose 1444 */ 1445 get modelViewMatrixInverseTranspose$() { 1446 return (this._mv.it || (this._mv.it = SpiderGL.Math.Mat4.transpose(this.modelViewMatrixInverse$))); 1447 }, 1448 1449 /** 1450 * Gets a copy of the transpose of the inverse of the matrix T = V * M, where V is the view matrix and M the model matrix. 1451 * 1452 * @type array 1453 * 1454 * @see modelViewMatrixInverseTranspose$ 1455 */ 1456 get modelViewMatrixInverseTranspose() { 1457 return SpiderGL.Math.Mat4.dup(this.modelViewMatrixInverseTranspose$); 1458 }, 1459 1460 /** 1461 * Gets a reference to the matrix T = P * V, where P is the projection matrix and V the view matrix. 1462 * The returned array MUST NOT be changed. 1463 * 1464 * @type array 1465 * 1466 * @see viewProjectionMatrix 1467 */ 1468 get viewProjectionMatrix$() { 1469 return (this._vp.m || (this._vp.m = SpiderGL.Math.Mat4.mul(this.projectionMatrix$, this.viewMatrix$))); 1470 }, 1471 1472 /** 1473 * Gets a copy of the matrix T = P * V, where P is the projection matrix and V the view matrix. 1474 * 1475 * @type array 1476 * 1477 * @see viewProjectionMatrix$ 1478 */ 1479 get viewProjectionMatrix() { 1480 return SpiderGL.Math.Mat4.dup(this.viewProjectionMatrix$); 1481 }, 1482 1483 /** 1484 * Gets a reference to the inverse of the matrix T = P * V, where P is the projection matrix and V the view matrix. 1485 * The returned array MUST NOT be changed. 1486 * 1487 * @type array 1488 * 1489 * @see viewProjectionMatrixInverse 1490 */ 1491 get viewProjectionMatrixInverse$() { 1492 return (this._vp.i || (this._vp.i = SpiderGL.Math.Mat4.mul(this.viewMatrixInverse$, this.projectionMatrixInverse$))); 1493 }, 1494 1495 /** 1496 * Gets a copy of the inverse of the matrix T = P * V, where P is the projection matrix and V the view matrix. 1497 * 1498 * @type array 1499 * 1500 * @see viewProjectionMatrixInverse$ 1501 */ 1502 get viewProjectionMatrixInverse() { 1503 return SpiderGL.Math.Mat4.dup(this.viewProjectionMatrixInverse$); 1504 }, 1505 1506 /** 1507 * Gets a reference to the transpose of the matrix T = P * V, where P is the projection matrix and V the view matrix. 1508 * The returned array MUST NOT be changed. 1509 * 1510 * @type array 1511 * 1512 * @see viewProjectionMatrixTranspose 1513 */ 1514 get viewProjectionMatrixTranspose$() { 1515 return (this._vp.t || (this._vp.t = SpiderGL.Math.Mat4.transpose(this.viewProjectionMatrix$))); 1516 }, 1517 1518 /** 1519 * Gets a copy of the transpose of the matrix T = P * V, where P is the projection matrix and V the view matrix. 1520 * 1521 * @type array 1522 * 1523 * @see viewProjectionMatrixTranspose$ 1524 */ 1525 get viewProjectionMatrixTranspose() { 1526 return SpiderGL.Math.Mat4.dup(this.viewProjectionMatrixTranspose$); 1527 }, 1528 1529 /** 1530 * Gets a reference to the transpose of the inverse of the matrix T = P * V, where P is the projection matrix and V the view matrix. 1531 * The returned array MUST NOT be changed. 1532 * 1533 * @type array 1534 * 1535 * @see viewProjectionMatrixInverseTranspose 1536 */ 1537 get viewProjectionMatrixInverseTranspose$() { 1538 return (this._vp.it || (this._vp.it = SpiderGL.Math.Mat4.transpose(this.viewProjectionMatrixInverse$))); 1539 }, 1540 1541 /** 1542 * Gets a copy of the transpose of the inverse of the matrix T = P * V, where P is the projection matrix and V the view matrix. 1543 * 1544 * @type array 1545 * 1546 * @see viewProjectionMatrixInverseTranspose$ 1547 */ 1548 get viewProjectionMatrixInverseTranspose() { 1549 return SpiderGL.Math.Mat4.dup(this.viewProjectionMatrixInverseTranspose$); 1550 }, 1551 1552 /** 1553 * Gets a reference to the matrix T = P * V * M, where P is the projection matrix, V the view matrix and M the model matrix. 1554 * The returned array MUST NOT be changed. 1555 * 1556 * @type array 1557 * 1558 * @see modelViewProjectionMatrix 1559 */ 1560 get modelViewProjectionMatrix$() { 1561 return (this._mvp.m || (this._mvp.m = SpiderGL.Math.Mat4.mul(this.viewProjectionMatrix$, this.modelMatrix$))); 1562 }, 1563 1564 /** 1565 * Gets a copy of the matrix T = P * V * M, where P is the projection matrix, V the view matrix and M the model matrix. 1566 * 1567 * @type array 1568 * 1569 * @see modelViewProjectionMatrix$ 1570 */ 1571 get modelViewProjectionMatrix() { 1572 return SpiderGL.Math.Mat4.dup(this.modelViewProjectionMatrix$); 1573 }, 1574 1575 /** 1576 * Gets a reference to the inverse of the matrix T = P * V * M, where P is the projection matrix, V the view matrix and M the model matrix. 1577 * The returned array MUST NOT be changed. 1578 * 1579 * @type array 1580 * 1581 * @see modelViewProjectionMatrix 1582 */ 1583 get modelViewProjectionMatrixInverse$() { 1584 return (this._mvp.i || (this._mvp.i = SpiderGL.Math.Mat4.inverse(this.modelViewProjectionMatrix$))); 1585 }, 1586 1587 /** 1588 * Gets a copy of the inverse of the matrix T = P * V * M, where P is the projection matrix, V the view matrix and M the model matrix. 1589 * 1590 * @type array 1591 * 1592 * @see modelViewProjectionMatrix$ 1593 */ 1594 get modelViewProjectionMatrixInverse() { 1595 return SpiderGL.Math.Mat4.dup(this.modelViewProjectionMatrixInverse$); 1596 }, 1597 1598 /** 1599 * Gets a reference to the transpose of the matrix T = P * V * M, where P is the projection matrix, V the view matrix and M the model matrix. 1600 * The returned array MUST NOT be changed. 1601 * 1602 * @type array 1603 * 1604 * @see modelViewProjectionMatrixTranspose 1605 */ 1606 get modelViewProjectionMatrixTranspose$() { 1607 return (this._mvp.t || (this._mvp.t = SpiderGL.Math.Mat4.transpose(this.modelViewProjectionMatrix$))); 1608 }, 1609 1610 /** 1611 * Gets a copy of the transpose of the matrix T = P * V * M, where P is the projection matrix, V the view matrix and M the model matrix. 1612 * 1613 * @type array 1614 * 1615 * @see modelViewProjectionMatrixTranspose$ 1616 */ 1617 get modelViewProjectionMatrixTranspose() { 1618 return SpiderGL.Math.Mat4.dup(this.modelViewProjectionMatrixTranspose$); 1619 }, 1620 1621 /** 1622 * Gets a reference to the transpose of the inverse of the matrix T = P * V * M, where P is the projection matrix, V the view matrix and M the model matrix. 1623 * The returned array MUST NOT be changed. 1624 * 1625 * @type array 1626 * 1627 * @see modelViewProjectionMatrixInverseTranspose 1628 */ 1629 get modelViewProjectionMatrixInverseTranspose$() { 1630 return (this._mvp.it || (this._mvp.it = SpiderGL.Math.Mat4.transpose(this.modelViewProjectionMatrixInverse$))); 1631 }, 1632 1633 /** 1634 * Gets a copy of the transpose of the inverse of the matrix T = P * V * M, where P is the projection matrix, V the view matrix and M the model matrix. 1635 * 1636 * @type array 1637 * 1638 * @see modelViewProjectionMatrixInverseTranspose$ 1639 */ 1640 get modelViewProjectionMatrixInverseTranspose() { 1641 return SpiderGL.Math.Mat4.dup(this.modelViewProjectionMatrixInverseTranspose$); 1642 }, 1643 1644 /** 1645 * Gets a reference to the transpose of the inverse of the upper-left 3x3 matrix of the model matrix. 1646 * The returned array MUST NOT be changed. 1647 * 1648 * @type array 1649 * 1650 * @see worldSpaceNormalMatrix 1651 * @see viewSpaceNormalMatrix$ 1652 */ 1653 get worldSpaceNormalMatrix$() { 1654 return (this._n.m || (this._n.m = SpiderGL.Math.Mat4.inverseTranspose33(this.modelMatrix$))); 1655 }, 1656 1657 /** 1658 * Gets a copy of the transpose of the inverse of the upper-left 3x3 matrix of the model matrix. 1659 * 1660 * @type array 1661 * 1662 * @see worldSpaceNormalMatrix$ 1663 * @see viewSpaceNormalMatrix 1664 */ 1665 get worldSpaceNormalMatrix() { 1666 return SpiderGL.Math.Mat4.dup(this.worldSpaceNormalMatrix$); 1667 }, 1668 1669 /** 1670 * Gets a reference to the transpose of the inverse of the upper-left 3x3 matrix of the model-view matrix. 1671 * The returned array MUST NOT be changed. 1672 * 1673 * @type array 1674 * 1675 * @see viewSpaceNormalMatrix 1676 * @see worldSpaceNormalMatrix$ 1677 */ 1678 get viewSpaceNormalMatrix$() { 1679 return (this._n.v || (this._n.v = SpiderGL.Math.Mat4.inverseTranspose33(this.modelViewMatrix$))); 1680 }, 1681 1682 /** 1683 * Gets a copy of the transpose of the inverse of the upper-left 3x3 matrix of the model matrix. 1684 * 1685 * @type array 1686 * 1687 * @see viewSpaceNormalMatrix$ 1688 * @see worldSpaceNormalMatrix 1689 */ 1690 get viewSpaceNormalMatrix() { 1691 return SpiderGL.Math.Mat4.dup(this.viewSpaceNormalMatrix$); 1692 }, 1693 1694 /** 1695 * Gets a reference to the 3-dimensional vector representing the 4th column of the inverse of the model-view matrix. 1696 * The returned array MUST NOT be changed. 1697 * 1698 * @type array 1699 * 1700 * @see modelSpaceViewerPosition 1701 * @see modelSpaceViewDirection$ 1702 * @see worldSpaceViewerPosition$ 1703 */ 1704 get modelSpaceViewerPosition$() { 1705 return (this._c.mp || (this._c.mp = SpiderGL.Math.Vec4.to3(SpiderGL.Math.Mat4.col(this.modelViewMatrixInverse$, 3)))); 1706 }, 1707 1708 /** 1709 * Gets a copy of the 3-dimensional vector representing the 4th column of the inverse of the model-view matrix. 1710 * 1711 * @type array 1712 * 1713 * @see modelSpaceViewerPosition$ 1714 * @see modelSpaceViewDirection$ 1715 * @see worldSpaceViewerPosition 1716 */ 1717 get modelSpaceViewerPosition() { 1718 return SpiderGL.Math.Vec3.dup(this.modelSpaceViewerPosition$); 1719 }, 1720 1721 /** 1722 * Gets a reference to the 3-dimensional vector representing the 4th column of the inverse of the view matrix. 1723 * The returned array MUST NOT be changed. 1724 * 1725 * @type array 1726 * 1727 * @see worldSpaceViewerPosition 1728 * @see worldSpaceViewDirection$ 1729 * @see modelSpaceViewerPosition$ 1730 */ 1731 get worldSpaceViewerPosition$() { 1732 return (this._c.wp || (this._c.wp = SpiderGL.Math.Vec4.to3(SpiderGL.Math.Mat4.col(this.viewMatrixInverse$, 3)))); 1733 }, 1734 1735 /** 1736 * Gets a copy of the 3-dimensional vector representing the 4th column of the inverse of the model-view matrix. 1737 * 1738 * @type array 1739 * 1740 * @see worldSpaceViewerPosition$ 1741 * @see worldSpaceViewDirection 1742 * @see modelSpaceViewerPosition 1743 */ 1744 get worldSpaceViewerPosition() { 1745 return SpiderGL.Math.Vec3.dup(this.worldSpaceViewerPosition$); 1746 }, 1747 1748 /** 1749 * Gets a reference to the 3-dimensional vector representing the negated 3rd row of the inverse of the model-view matrix. 1750 * The returned array MUST NOT be changed. 1751 * 1752 * @type array 1753 * 1754 * @see modelSpaceViewDirection 1755 * @see modelSpaceViewerPosition$ 1756 * @see worldSpaceViewDirection$ 1757 */ 1758 get modelSpaceViewDirection$() { 1759 return (this._c.md || (this._c.md = SpiderGL.Math.Vec3.normalize$(SpiderGL.Math.Vec3.neg$(SpiderGL.Math.Vec4.to3(SpiderGL.Math.Mat4.row(this.modelViewMatrixInverse$, 2)))))); 1760 }, 1761 1762 /** 1763 * Gets a copy of the 3-dimensional vector representing the negated 3rd row of the inverse of the model-view matrix. 1764 * 1765 * @type array 1766 * 1767 * @see modelSpaceViewDirection$ 1768 * @see modelSpaceViewerPosition 1769 * @see worldSpaceViewDirection 1770 */ 1771 get modelSpaceViewDirection() { 1772 return SpiderGL.Math.Vec3.dup(this.modelSpaceViewDirection$); 1773 }, 1774 1775 /** 1776 * Gets a reference to the 3-dimensional vector representing the negated 3rd row of the inverse of the view matrix. 1777 * The returned array MUST NOT be changed. 1778 * 1779 * @type array 1780 * 1781 * @see worldSpaceViewDirection 1782 * @see worldSpaceViewerPosition$ 1783 * @see modelSpaceViewDirection$ 1784 */ 1785 get worldSpaceViewDirection$() { 1786 return (this._c.wd || (this._c.wd = SpiderGL.Math.Vec3.normalize$(SpiderGL.Math.Vec3.neg$(SpiderGL.Math.Vec4.to3(SpiderGL.Math.Mat4.row(this.viewMatrixInverse$, 2)))))); 1787 }, 1788 1789 /** 1790 * Gets a reference to the 3-dimensional vector representing the negated 3rd row of the inverse of the model-view matrix. 1791 * 1792 * @type array 1793 * 1794 * @see worldSpaceViewDirection$ 1795 * @see worldSpaceViewerPosition 1796 * @see modelSpaceViewDirection 1797 */ 1798 get worldSpaceViewDirection() { 1799 return SpiderGL.Math.Vec3.dup(this.worldSpaceViewDirection$); 1800 }, 1801 1802 project : function(xyzw) { 1803 return SpiderGL.Math.project(xyzw, this.modelViewProjectionMatrix$, this.viewportRect$, this.depthRange$); 1804 }, 1805 1806 unproject : function(xyz) { 1807 return SpiderGL.Math.unproject(xyz, this.modelViewProjectionMatrixInverse$, this.viewportRect$, this.depthRange$); 1808 } 1809 }; 1810 1811 SpiderGL.Type.extend(SpiderGL.Space.TransformationStack, SpiderGL.Core.ObjectBase); 1812 1813