]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojox/gfx3d/matrix.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojox / gfx3d / matrix.js
1 if(!dojo._hasResource["dojox.gfx3d.matrix"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.gfx3d.matrix"] = true;
3 dojo.provide("dojox.gfx3d.matrix");
4
5 // candidates for dojox.math:
6 dojox.gfx3d.matrix._degToRad = function(degree){ return Math.PI * degree / 180; };
7 dojox.gfx3d.matrix._radToDeg = function(radian){ return radian / Math.PI * 180; };
8
9 dojox.gfx3d.matrix.Matrix3D = function(arg){
10         // summary: a 3D matrix object
11         // description: Normalizes a 3D matrix-like object. If arrays is passed, 
12         //              all objects of the array are normalized and multiplied sequentially.
13         // arg: Object
14         //              a 3D matrix-like object, a number, or an array of such objects
15         if(arg){
16                 if(typeof arg == "number"){
17                         this.xx = this.yy = this.zz = arg;
18                 }else if(arg instanceof Array){
19                         if(arg.length > 0){
20                                 var m = dojox.gfx3d.matrix.normalize(arg[0]);
21                                 // combine matrices
22                                 for(var i = 1; i < arg.length; ++i){
23                                         var l = m;
24                                         var r = dojox.gfx3d.matrix.normalize(arg[i]);
25                                         m = new dojox.gfx3d.matrix.Matrix3D();
26                                         m.xx = l.xx * r.xx + l.xy * r.yx + l.xz * r.zx;
27                                         m.xy = l.xx * r.xy + l.xy * r.yy + l.xz * r.zy;
28                                         m.xz = l.xx * r.xz + l.xy * r.yz + l.xz * r.zz;
29                                         m.yx = l.yx * r.xx + l.yy * r.yx + l.yz * r.zx;
30                                         m.yy = l.yx * r.xy + l.yy * r.yy + l.yz * r.zy;
31                                         m.yz = l.yx * r.xz + l.yy * r.yz + l.yz * r.zz;
32                                         m.zx = l.zx * r.xx + l.zy * r.yx + l.zz * r.zx;
33                                         m.zy = l.zx * r.xy + l.zy * r.yy + l.zz * r.zy;
34                                         m.zz = l.zx * r.xz + l.zy * r.yz + l.zz * r.zz;
35                                         m.dx = l.xx * r.dx + l.xy * r.dy + l.xz * r.dz + l.dx;
36                                         m.dy = l.yx * r.dx + l.yy * r.dy + l.yz * r.dz + l.dy;
37                                         m.dz = l.zx * r.dx + l.zy * r.dy + l.zz * r.dz + l.dz;
38                                 }
39                                 dojo.mixin(this, m);
40                         }
41                 }else{
42                         dojo.mixin(this, arg);
43                 }
44         }
45 };
46
47 // the default (identity) matrix, which is used to fill in missing values
48 dojo.extend(dojox.gfx3d.matrix.Matrix3D, {xx: 1, xy: 0, xz: 0, yx: 0, yy: 1, yz: 0, zx: 0, zy: 0, zz: 1, dx: 0, dy: 0, dz: 0});
49
50 dojo.mixin(dojox.gfx3d.matrix, {
51         // summary: class constants, and methods of dojox.gfx3d.matrix
52         
53         // matrix constants
54         
55         // identity: dojox.gfx3d.matrix.Matrix3D
56         //              an identity matrix constant: identity * (x, y, z) == (x, y, z)
57         identity: new dojox.gfx3d.matrix.Matrix3D(),
58         
59         // matrix creators
60         
61         translate: function(a, b, c){
62                 // summary: forms a translation matrix
63                 // description: The resulting matrix is used to translate (move) points by specified offsets.
64                 // a: Number: an x coordinate value
65                 // b: Number: a y coordinate value
66                 // c: Number: a z coordinate value
67                 if(arguments.length > 1){
68                         return new dojox.gfx3d.matrix.Matrix3D({dx: a, dy: b, dz: c}); // dojox.gfx3d.matrix.Matrix3D
69                 }
70                 // branch
71                 // a: Object: a point-like object, which specifies offsets for 3 dimensions
72                 // b: null
73                 return new dojox.gfx3d.matrix.Matrix3D({dx: a.x, dy: a.y, dz: a.z}); // dojox.gfx3d.matrix.Matrix3D
74         },
75         scale: function(a, b, c){
76                 // summary: forms a scaling matrix
77                 // description: The resulting matrix is used to scale (magnify) points by specified offsets.
78                 // a: Number: a scaling factor used for the x coordinate
79                 // b: Number: a scaling factor used for the y coordinate
80                 // c: Number: a scaling factor used for the z coordinate
81                 if(arguments.length > 1){
82                         return new dojox.gfx3d.matrix.Matrix3D({xx: a, yy: b, zz: c}); // dojox.gfx3d.matrix.Matrix3D
83                 }
84                 if(typeof a == "number"){
85                         // branch
86                         // a: Number: a uniform scaling factor used for the all coordinates
87                         // b: null
88                         return new dojox.gfx3d.matrix.Matrix3D({xx: a, yy: a, zz: a}); // dojox.gfx3d.matrix.Matrix3D
89                 }
90                 // branch
91                 // a: Object: a point-like object, which specifies scale factors for 3 dimensions
92                 // b: null
93                 return new dojox.gfx3d.matrix.Matrix3D({xx: a.x, yy: a.y, zz: a.z}); // dojox.gfx3d.matrix.Matrix3D
94         },
95         rotateX: function(angle){
96                 // summary: forms a rotating matrix (about the x axis)
97                 // description: The resulting matrix is used to rotate points 
98                 //              around the origin of coordinates (0, 0) by specified angle.
99                 // angle: Number: an angle of rotation in radians (>0 for CW)
100                 var c = Math.cos(angle);
101                 var s = Math.sin(angle);
102                 return new dojox.gfx3d.matrix.Matrix3D({yy: c, yz: -s, zy: s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
103         },
104         rotateXg: function(degree){
105                 // summary: forms a rotating matrix (about the x axis)
106                 // description: The resulting matrix is used to rotate points
107                 //              around the origin of coordinates (0, 0) by specified degree.
108                 //              See dojox.gfx3d.matrix.rotateX() for comparison.
109                 // degree: Number: an angle of rotation in degrees (>0 for CW)
110                 return dojox.gfx3d.matrix.rotateX(dojox.gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
111         },
112         rotateY: function(angle){
113                 // summary: forms a rotating matrix (about the y axis)
114                 // description: The resulting matrix is used to rotate points 
115                 //              around the origin of coordinates (0, 0) by specified angle.
116                 // angle: Number: an angle of rotation in radians (>0 for CW)
117                 var c = Math.cos(angle);
118                 var s = Math.sin(angle);
119                 return new dojox.gfx3d.matrix.Matrix3D({xx: c, xz: s, zx: -s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
120         },
121         rotateYg: function(degree){
122                 // summary: forms a rotating matrix (about the y axis)
123                 // description: The resulting matrix is used to rotate points
124                 //              around the origin of coordinates (0, 0) by specified degree.
125                 //              See dojox.gfx3d.matrix.rotateY() for comparison.
126                 // degree: Number: an angle of rotation in degrees (>0 for CW)
127                 return dojox.gfx3d.matrix.rotateY(dojox.gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
128         },
129         rotateZ: function(angle){
130                 // summary: forms a rotating matrix (about the z axis)
131                 // description: The resulting matrix is used to rotate points 
132                 //              around the origin of coordinates (0, 0) by specified angle.
133                 // angle: Number: an angle of rotation in radians (>0 for CW)
134                 var c = Math.cos(angle);
135                 var s = Math.sin(angle);
136                 return new dojox.gfx3d.matrix.Matrix3D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx3d.matrix.Matrix3D
137         },
138         rotateZg: function(degree){
139                 // summary: forms a rotating matrix (about the z axis)
140                 // description: The resulting matrix is used to rotate points
141                 //              around the origin of coordinates (0, 0) by specified degree.
142                 //              See dojox.gfx3d.matrix.rotateZ() for comparison.
143                 // degree: Number: an angle of rotation in degrees (>0 for CW)
144                 return dojox.gfx3d.matrix.rotateZ(dojox.gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
145         },
146
147         // camera transformation
148         cameraTranslate: function(a, b, c){
149                 // summary: forms a translation matrix
150                 // description: The resulting matrix is used to translate (move) points by specified offsets.
151                 // a: Number: an x coordinate value
152                 // b: Number: a y coordinate value
153                 // c: Number: a z coordinate value
154                 if(arguments.length > 1){
155                         return new dojox.gfx3d.matrix.Matrix3D({dx: -a, dy: -b, dz: -c}); // dojox.gfx3d.matrix.Matrix3D
156                 }
157                 // branch
158                 // a: Object: a point-like object, which specifies offsets for 3 dimensions
159                 // b: null
160                 return new dojox.gfx3d.matrix.Matrix3D({dx: -a.x, dy: -a.y, dz: -a.z}); // dojox.gfx3d.matrix.Matrix3D
161         },
162         cameraRotateX: function(angle){
163                 // summary: forms a rotating matrix (about the x axis) in cameraTransform manner
164                 // description: The resulting matrix is used to rotate points 
165                 //              around the origin of coordinates (0, 0) by specified angle.
166                 // angle: Number: an angle of rotation in radians (>0 for CW)
167                 var c = Math.cos(-angle);
168                 var s = Math.sin(-angle);
169                 return new dojox.gfx3d.matrix.Matrix3D({yy: c, yz: -s, zy: s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
170         },
171         cameraRotateXg: function(degree){
172                 // summary: forms a rotating matrix (about the x axis)in cameraTransform manner
173                 // description: The resulting matrix is used to rotate points
174                 //              around the origin of coordinates (0, 0) by specified degree.
175                 //              See dojox.gfx3d.matrix.rotateX() for comparison.
176                 // degree: Number: an angle of rotation in degrees (>0 for CW)
177                 return dojox.gfx3d.matrix.rotateX(dojox.gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
178         },
179         cameraRotateY: function(angle){
180                 // summary: forms a rotating matrix (about the y axis) in cameraTransform manner
181                 // description: The resulting matrix is used to rotate points 
182                 //              around the origin of coordinates (0, 0) by specified angle.
183                 // angle: Number: an angle of rotation in radians (>0 for CW)
184                 var c = Math.cos(-angle);
185                 var s = Math.sin(-angle);
186                 return new dojox.gfx3d.matrix.Matrix3D({xx: c, xz: s, zx: -s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
187         },
188         cameraRotateYg: function(degree){
189                 // summary: forms a rotating matrix (about the y axis) in cameraTransform manner
190                 // description: The resulting matrix is used to rotate points
191                 //              around the origin of coordinates (0, 0) by specified degree.
192                 //              See dojox.gfx3d.matrix.rotateY() for comparison.
193                 // degree: Number: an angle of rotation in degrees (>0 for CW)
194                 return dojox.gfx3d.matrix.rotateY(dojox.gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
195         },
196         cameraRotateZ: function(angle){
197                 // summary: forms a rotating matrix (about the z axis) in cameraTransform manner
198                 // description: The resulting matrix is used to rotate points 
199                 //              around the origin of coordinates (0, 0) by specified angle.
200                 // angle: Number: an angle of rotation in radians (>0 for CW)
201                 var c = Math.cos(-angle);
202                 var s = Math.sin(-angle);
203                 return new dojox.gfx3d.matrix.Matrix3D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx3d.matrix.Matrix3D
204         },
205         cameraRotateZg: function(degree){
206                 // summary: forms a rotating matrix (about the z axis) in cameraTransform manner
207                 // description: The resulting matrix is used to rotate points
208                 //              around the origin of coordinates (0, 0) by specified degree.
209                 //              See dojox.gfx3d.matrix.rotateZ() for comparison.
210                 // degree: Number: an angle of rotation in degrees (>0 for CW)
211                 return dojox.gfx3d.matrix.rotateZ(dojox.gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
212         },
213
214         // ensure matrix 3D conformance
215         normalize: function(matrix){
216                 // summary: converts an object to a matrix, if necessary
217                 // description: Converts any 3D matrix-like object or an array of
218                 //              such objects to a valid dojox.gfx3d.matrix.Matrix3D object.
219                 // matrix: Object: an object, which is converted to a matrix, if necessary
220                 return (matrix instanceof dojox.gfx3d.matrix.Matrix3D) ? matrix : new dojox.gfx3d.matrix.Matrix3D(matrix); // dojox.gfx3d.matrix.Matrix3D
221         },
222         
223         // common operations
224         
225         clone: function(matrix){
226                 // summary: creates a copy of a 3D matrix
227                 // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix-like object to be cloned
228                 var obj = new dojox.gfx3d.matrix.Matrix3D();
229                 for(var i in matrix){
230                         if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i];
231                 }
232                 return obj; // dojox.gfx3d.matrix.Matrix3D
233         },
234         invert: function(matrix){
235                 // summary: inverts a 2D matrix
236                 // matrix: dojox.gfx.matrix.Matrix3D: a 2D matrix-like object to be inverted
237                 var m = dojox.gfx3d.matrix.normalize(matrix);
238                 var D = m.xx * m.yy * m.zz + m.xy * m.yz * m.zx + m.xz * m.yx * m.zy - m.xx * m.yz * m.zy - m.xy * m.yx * m.zz - m.xz * m.yy * m.zx;
239                 var M = new dojox.gfx3d.matrix.Matrix3D({
240                         xx: (m.yy * m.zz - m.yz * m.zy) / D,
241                         xy: (m.xz * m.zy - m.xy * m.zz) / D,
242                         xz: (m.xy * m.yz - m.xz * m.yy) / D,
243                         yx: (m.yz * m.zx - m.yx * m.zz) / D,
244                         yy: (m.xx * m.zz - m.xz * m.zx) / D,
245                         yz: (m.xz * m.yx - m.xx * m.yz) / D,
246                         zx: (m.yx * m.zy - m.yy * m.zx) / D,
247                         zy: (m.xy * m.zx - m.xx * m.zy) / D,
248                         zz: (m.xx * m.yy - m.xy * m.yx) / D,
249                         dx: -1 * (m.xy * m.yz * m.dz + m.xz * m.dy * m.zy + m.dx * m.yy * m.zz - m.xy * m.dy * m.zz - m.xz * m.yy * m.dz - m.dx * m.yz * m.zy) / D,
250                         dy: (m.xx * m.yz * m.dz + m.xz * m.dy * m.zx + m.dx * m.yx * m.zz - m.xx * m.dy * m.zz - m.xz * m.yx * m.dz - m.dx * m.yz * m.zx) / D,
251                         dz: -1 * (m.xx * m.yy * m.dz + m.xy * m.dy * m.zx + m.dx * m.yx * m.zy - m.xx * m.dy * m.zy - m.xy * m.yx * m.dz - m.dx * m.yy * m.zx) / D
252                 });
253                 return M; // dojox.gfx3d.matrix.Matrix3D
254         },
255         _multiplyPoint: function(m, x, y, z){
256                 // summary: applies a matrix to a point
257                 // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
258                 // x: Number: an x coordinate of a point
259                 // y: Number: a y coordinate of a point
260                 // z: Number: a z coordinate of a point
261                 return {x: m.xx * x + m.xy * y + m.xz * z + m.dx, y: m.yx * x + m.yy * y + m.yz * z + m.dy, z: m.zx * x + m.zy * y + m.zz * z + m.dz}; // Object
262         },
263         multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b, /* Number, optional */ c){
264                 // summary: applies a matrix to a point
265                 // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
266                 // a: Number: an x coordinate of a point
267                 // b: Number: a y coordinate of a point
268                 // c: Number: a z coordinate of a point
269                 var m = dojox.gfx3d.matrix.normalize(matrix);
270                 if(typeof a == "number" && typeof b == "number" && typeof c == "number"){
271                         return dojox.gfx3d.matrix._multiplyPoint(m, a, b, c); // Object
272                 }
273                 // branch
274                 // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
275                 // a: Object: a point
276                 // b: null
277                 // c: null
278                 return dojox.gfx3d.matrix._multiplyPoint(m, a.x, a.y, a.z); // Object
279         },
280         multiply: function(matrix){
281                 // summary: combines matrices by multiplying them sequentially in the given order
282                 // matrix: dojox.gfx3d.matrix.Matrix3D...: a 3D matrix-like object, 
283                 //              all subsequent arguments are matrix-like objects too
284                 var m = dojox.gfx3d.matrix.normalize(matrix);
285                 // combine matrices
286                 for(var i = 1; i < arguments.length; ++i){
287                         var l = m;
288                         var r = dojox.gfx3d.matrix.normalize(arguments[i]);
289                         m = new dojox.gfx3d.matrix.Matrix3D();
290                         m.xx = l.xx * r.xx + l.xy * r.yx + l.xz * r.zx;
291                         m.xy = l.xx * r.xy + l.xy * r.yy + l.xz * r.zy;
292                         m.xz = l.xx * r.xz + l.xy * r.yz + l.xz * r.zz;
293                         m.yx = l.yx * r.xx + l.yy * r.yx + l.yz * r.zx;
294                         m.yy = l.yx * r.xy + l.yy * r.yy + l.yz * r.zy;
295                         m.yz = l.yx * r.xz + l.yy * r.yz + l.yz * r.zz;
296                         m.zx = l.zx * r.xx + l.zy * r.yx + l.zz * r.zx;
297                         m.zy = l.zx * r.xy + l.zy * r.yy + l.zz * r.zy;
298                         m.zz = l.zx * r.xz + l.zy * r.yz + l.zz * r.zz;
299                         m.dx = l.xx * r.dx + l.xy * r.dy + l.xz * r.dz + l.dx;
300                         m.dy = l.yx * r.dx + l.yy * r.dy + l.yz * r.dz + l.dy;
301                         m.dz = l.zx * r.dx + l.zy * r.dy + l.zz * r.dz + l.dz;
302                 }
303                 return m; // dojox.gfx3d.matrix.Matrix3D
304         },
305
306         _project: function(m, x, y, z){
307                 // summary: applies a matrix to a point
308                 // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
309                 // x: Number: an x coordinate of a point
310                 // y: Number: a y coordinate of a point
311                 // z: Number: a z coordinate of a point
312                 return {        // Object
313                         x: m.xx * x + m.xy * y + m.xz * z + m.dx, 
314                         y: m.yx * x + m.yy * y + m.yz * z + m.dy, 
315                         z: m.zx * x + m.zy * y + m.zz * z + m.dz};
316         },
317         project: function(matrix, /* Number||Point */ a, /* Number, optional */ b, /* Number, optional */ c){
318                 // summary: applies a matrix to a point
319                 // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
320                 // a: Number: an x coordinate of a point
321                 // b: Number: a y coordinate of a point
322                 // c: Number: a z coordinate of a point
323                 var m = dojox.gfx3d.matrix.normalize(matrix);
324                 if(typeof a == "number" && typeof b == "number" && typeof c == "number"){
325                         return dojox.gfx3d.matrix._project(m, a, b, c); // Object
326                 }
327                 // branch
328                 // matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
329                 // a: Object: a point
330                 // b: null
331                 // c: null
332                 return dojox.gfx3d.matrix._project(m, a.x, a.y, a.z); // Object
333         }
334 });
335
336 // propagate matrix up
337 dojox.gfx3d.Matrix3D = dojox.gfx3d.matrix.Matrix3D;
338
339 }