Subversion Repositories Applications.papyrus

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 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
}