1 /*
  2   Copyright (c) 2008 Seneca College
  3   Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/)
  4 */
  5 
  6 // the stacks
  7 c3dl.ModelView = [];
  8 c3dl.Projection = [];
  9 
 10 // to reduce code in the functions for cheking which stack we are 
 11 // changing, just keep a reference variable to the current one.
 12 // start with the modelview.
 13 c3dl.CurrentStackPointer = c3dl.ModelView;
 14 
 15 // like Opengl, our stack starts off with an identity matrix. Here, we 
 16 // have to access the stacks directly since at this point we don't 
 17 // have access to the functions since they aren't defined yet.
 18 c3dl.ModelView.push(c3dl.makeIdentityMatrix());
 19 c3dl.Projection.push(c3dl.makeIdentityMatrix());
 20 
 21 
 22 /**
 23   Change the matrix mode to either model view or projection.
 24 
 25   @param {c3dl.PROJECTION | c3dl.MODELVIEW} mode
 26 */
 27 c3dl.matrixMode = function(mode)
 28 {
 29   if( mode == c3dl.PROJECTION )
 30   {
 31     c3dl.CurrentStackPointer = c3dl.Projection;
 32   }
 33   else if( mode == c3dl.MODELVIEW)
 34   {
 35     c3dl.CurrentStackPointer = c3dl.ModelView;
 36   }
 37 }
 38 
 39 
 40 /**
 41   create a copy of the top element and push on that copy. This results
 42   in the first two element being identical. This is simply emulating what
 43   OpenGL does.
 44 */
 45 c3dl.pushMatrix = function()
 46 {
 47   c3dl.CurrentStackPointer.push(c3dl.peekMatrix());
 48 }
 49 
 50 
 51 /**
 52   Replace the top matrix with a specified matrix. If paramter is
 53   not provided, an identity matrix will replace the top matrix.
 54   
 55   @param {Array} [matrix] The matrix which will replace the 
 56   element at the top of the stack. If omitted, it will replace the
 57   top element with an identity matrix.
 58 */
 59 c3dl.loadMatrix = function(matrix)
 60 {
 61   if( matrix ){
 62     c3dl.CurrentStackPointer[c3dl.getMatrixStackHeight()-1] = matrix;
 63   }
 64   
 65   // in Opengl if nothing is passed in it loads an identity matrix, 
 66   // so emulate that.
 67   else
 68   {
 69     // recursive, makes the first conditional our base case.
 70     c3dl.loadMatrix(c3dl.makeIdentityMatrix());
 71   }
 72 }
 73 
 74 /**
 75   Replace the top matrix with an identity matrix. This can also
 76   be accomplished by calling C3DL.loadMatrix() passing in zero
 77   arguments.
 78 */
 79 c3dl.loadIdentity = function()
 80 {
 81   c3dl.loadMatrix(c3dl.makeIdentityMatrix())
 82 }
 83 
 84 /**
 85   Pop the top matrix off the stack.  If there is only one matrix
 86   left in the stack, this function does nothing.
 87 */
 88 c3dl.popMatrix = function()
 89 {
 90   if( c3dl.getMatrixStackHeight() > 1)
 91   {
 92     c3dl.CurrentStackPointer.pop();
 93   }
 94 }
 95 
 96 
 97 /**
 98   Post multiply the matrix at the top of the stack with the 
 99   parameter 'matrix' and replace the top element with the product.
100   
101   @param {Array} matrix The matrix which will be post multiplied 
102   with the top matrix.
103 */
104 c3dl.multMatrix = function(matrix)
105 {
106   c3dl.loadMatrix(c3dl.multiplyMatrixByMatrix(c3dl.peekMatrix(), matrix));
107 }
108 
109 
110 /**
111   Get the matrix at the top of the stack.
112   
113   @returns {Array} The matrix at the top of the matrix stack.
114 */
115 c3dl.peekMatrix = function()
116 {
117   return c3dl.CurrentStackPointer[c3dl.getMatrixStackHeight()-1];
118 }
119 
120 
121 /**
122   Get the number of elements in the matrix stack.
123 
124   @returns {int} The number of elements in the current matrix stack.
125 */
126 c3dl.getMatrixStackHeight = function()
127 {  
128   return c3dl.CurrentStackPointer.length;
129 }
130 
131 
132 /**
133   Create a translate matrix and call C3DL.multMatrix() passing in the
134   translate matrix.
135 
136   @param {float} translateX The translation for the x component.
137   @param {float} translateY The translation for the y component.
138   @param {float} translateZ The translation for the z component.
139 */
140 c3dl.translate = function(translateX, translateY, translateZ)
141 {  
142   var translateMatrix = c3dl.makePoseMatrix([1,0,0], [0,1,0], [0,0,1], [translateX,translateY,translateZ]);
143 
144   c3dl.multMatrix(translateMatrix);
145 }
146 
147 
148 /**
149   @private until implemented
150   Create a rotation matrix and call multMatrix() with this matrix.
151 
152   @param {float} angle 
153   @param {float} rotationX 
154   @param {float} rotationY 
155   @param {float} rotationZ 
156 */
157 c3dl.rotate = function(angle, rotationX, rotationY, rotationZ)
158 {
159   //implement me!
160 }
161 
162 
163 /**
164   Create a scale matrix from the parameters provided and call multMatrix()
165   with this matrix.
166 
167   @param {float} scaleX Scaling factor for the x component.
168   @param {float} scaleY Scaling factor for the y component.
169   @param {float} scaleZ Scaling factor for the z component. 
170 */
171 c3dl.scale = function(scaleX, scaleY, scaleZ)
172 {
173   var scaleMatrix = c3dl.makeIdentityMatrix();
174   scaleMatrix[0] = scaleX;
175   scaleMatrix[5] = scaleY;
176   scaleMatrix[10] = scaleZ;
177 
178   c3dl.multMatrix(scaleMatrix);
179 }
180