source: Dev/trunk/src/client/dojox/gfx3d/matrix.js @ 529

Last change on this file since 529 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

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