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 Type
 31  */
 32 
 33 /**
 34  * The SpiderGL.Type namespace.
 35  *
 36  * @namespace The SpiderGL.Type namespace.
 37  */
 38 SpiderGL.Type = { };
 39 
 40 /**
 41  * Little-Endian flag.
 42  * It is true if the host system is little endian, false otherwise.
 43  *
 44  * @constant
 45  * @type bool
 46  *
 47  * @see SpiderGL.Type.BIG_ENDIAN
 48  */
 49 SpiderGL.Type.LITTLE_ENDIAN = (function(){
 50 	var a = new Uint8Array([0x12, 0x34]);
 51 	var b = new Uint16Array(a.buffer);
 52 	return (b[0] == 0x3412);
 53 })();
 54 
 55 /**
 56  * Big-Endian flag.
 57  * It is true if the host system is big endian, false otherwise.
 58  *
 59  * @constant
 60  * @type bool
 61  *
 62  * @see SpiderGL.Type.LITTLE_ENDIAN
 63  */
 64 SpiderGL.Type.BIG_ENDIAN = !SpiderGL.Type.BIG_ENDIAN;
 65 
 66 /**
 67  * Constant for undefined (void) type.
 68  *
 69  * @constant
 70  * @type number
 71  */
 72 SpiderGL.Type.NO_TYPE = 0;
 73 
 74 /**
 75  * Constant for 8-bit signed integer type.
 76  *
 77  * @constant
 78  * @type number
 79  */
 80 SpiderGL.Type.INT8 = 1;
 81 
 82 /**
 83  * Constant for 8-bit unsigned integer type.
 84  *
 85  * @constant
 86  * @type number
 87  */
 88 SpiderGL.Type.UINT8 = 2;
 89 
 90 /**
 91  * Constant for 16-bit signed integer type.
 92  *
 93  * @constant
 94  * @type number
 95  */
 96 SpiderGL.Type.INT16 = 3;
 97 
 98 /**
 99  * Constant for 16-bit unsigned integer type.
100  *
101  * @constant
102  * @type number
103  */
104 SpiderGL.Type.UINT16 = 4;
105 
106 /**
107  * Constant for 32-bit signed integer type.
108  *
109  * @constant
110  * @type number
111  */
112 SpiderGL.Type.INT32 = 5;
113 
114 /**
115  * Constant for 32-bit unsigned integer type.
116  *
117  * @constant
118  * @type number
119  */
120 SpiderGL.Type.UINT32 = 6;
121 
122 /**
123  * Constant for 32-bit floating point type.
124  *
125  * @constant
126  * @type number
127  */
128 SpiderGL.Type.FLOAT32 = 7;
129 
130 /**
131  * Alias for Int8Array.BYTES_PER_ELEMENT.
132  *
133  * @constant
134  * @type number
135  */
136 SpiderGL.Type.SIZEOF_INT8 = Int8Array.BYTES_PER_ELEMENT;
137 
138 /**
139  * Alias for Uint8Array.BYTES_PER_ELEMENT.
140  *
141  * @constant
142  * @type number
143  */
144 SpiderGL.Type.SIZEOF_UINT8 = Uint8Array.BYTES_PER_ELEMENT;
145 
146 /**
147  * Alias for Int16Array.BYTES_PER_ELEMENT.
148  *
149  * @constant
150  * @type number
151  */
152 SpiderGL.Type.SIZEOF_INT16 = Int16Array.BYTES_PER_ELEMENT;
153 
154 /**
155  * Alias for Uint16Array.BYTES_PER_ELEMENT.
156  *
157  * @constant
158  * @type number
159  */
160 SpiderGL.Type.SIZEOF_UINT16 = Uint16Array.BYTES_PER_ELEMENT;
161 
162 /**
163  * Alias for Int32Array.BYTES_PER_ELEMENT.
164  *
165  * @constant
166  * @type number
167  */
168 SpiderGL.Type.SIZEOF_INT32 = Int32Array.BYTES_PER_ELEMENT;
169 
170 /**
171  * Alias for Uint32Array.BYTES_PER_ELEMENT.
172  *
173  * @constant
174  * @type number
175  */
176 SpiderGL.Type.SIZEOF_UINT32 = Uint32Array.BYTES_PER_ELEMENT;
177 
178 /**
179  * Alias for Float32Array.BYTES_PER_ELEMENT.
180  *
181  * @constant
182  * @type number
183  */
184 SpiderGL.Type.SIZEOF_FLOAT32 = Float32Array.BYTES_PER_ELEMENT;
185 
186 /* *
187  * Alias for Float64Array.BYTES_PER_ELEMENT.
188  *
189  * @constant
190  * @type number
191  */
192 //var SpiderGL.Type.SIZEOF_FLOAT64 = Float64Array.BYTES_PER_ELEMENT;
193 
194 /**
195  * Returns the size of the type expressed by the passed symbolic constant.
196  *
197  * @param {number} sglType A SpiderGL type symbolic constants, i.e. SpiderGL.Type.UINT8.
198  * @return {number} The size in bytes of the type.
199  */
200 SpiderGL.Type.typeSize = (function(){
201 	var typeMap = { };
202 	typeMap[SpiderGL.Type.NO_TYPE] = 0;
203 	typeMap[SpiderGL.Type.INT8   ] = SpiderGL.Type.SIZEOF_INT8;
204 	typeMap[SpiderGL.Type.UINT8  ] = SpiderGL.Type.SIZEOF_UINT8;
205 	typeMap[SpiderGL.Type.INT16  ] = SpiderGL.Type.SIZEOF_INT16;
206 	typeMap[SpiderGL.Type.UINT16 ] = SpiderGL.Type.SIZEOF_UINT16;
207 	typeMap[SpiderGL.Type.INT32  ] = SpiderGL.Type.SIZEOF_INT32;
208 	typeMap[SpiderGL.Type.UINT32 ] = SpiderGL.Type.SIZEOF_UINT32;
209 	typeMap[SpiderGL.Type.FLOAT32] = SpiderGL.Type.SIZEOF_FLOAT32;
210 	return function (sglType) {
211 		return typeMap[sglType];
212 	};
213 })();
214 
215 /**
216  * Maps a SpiderGL type symbolic constant to a WebGL type constant.
217  * For example, calling this function with SpiderGL.Type.UINT8 as argument will return WebGLRenderingContext.UNSIGNED_BYTE.
218  *
219  * @param {number} sglType A SpiderGL type symbolic constants, i.e. SpiderGL.Type.UINT8.
220  * @return {number} The corresponding WebGLRenderingContext type constant, i.e. WebGLRenderingContext.UNSIGNED_BYTE.
221  */
222 SpiderGL.Type.typeToGL = (function(){
223 	var typeMap = { };
224 	typeMap[SpiderGL.Type.NO_TYPE] = WebGLRenderingContext.NONE;
225 	typeMap[SpiderGL.Type.INT8   ] = WebGLRenderingContext.BYTE;
226 	typeMap[SpiderGL.Type.UINT8  ] = WebGLRenderingContext.UNSIGNED_BYTE;
227 	typeMap[SpiderGL.Type.INT16  ] = WebGLRenderingContext.SHORT;
228 	typeMap[SpiderGL.Type.UINT16 ] = WebGLRenderingContext.UNSIGNED_SHORT;
229 	typeMap[SpiderGL.Type.INT32  ] = WebGLRenderingContext.INT;
230 	typeMap[SpiderGL.Type.UINT32 ] = WebGLRenderingContext.UNSIGNED_INT;
231 	typeMap[SpiderGL.Type.FLOAT32] = WebGLRenderingContext.FLOAT;
232 	return function (sglType) {
233 		return typeMap[sglType];
234 	};
235 })();
236 
237 /**
238  * Maps a WebGL type constant to a WebGL type constant.
239  * For example, calling this function with WebGLRenderingContext.UNSIGNED_BYTE as argument will return SpiderGL.Type.UINT8.
240  *
241  * @param {number} glType A WebGL type symbolic constants, i.e. WebGLRenderingContext.UNSIGNED_BYTE.
242  * @return {number} The corresponding SpiderGL type constant, i.e. SpiderGL.Type.UINT8.
243  */
244 SpiderGL.Type.typeFromGL = (function(){
245 	var typeMap = { };
246 	typeMap[WebGLRenderingContext.NONE          ] = SpiderGL.Type.NO_TYPE;
247 	typeMap[WebGLRenderingContext.BYTE          ] = SpiderGL.Type.INT8;
248 	typeMap[WebGLRenderingContext.UNSIGNED_BYTE ] = SpiderGL.Type.UINT8;
249 	typeMap[WebGLRenderingContext.SHORT         ] = SpiderGL.Type.INT16;
250 	typeMap[WebGLRenderingContext.UNSIGNED_SHORT] = SpiderGL.Type.UINT16;
251 	typeMap[WebGLRenderingContext.INT           ] = SpiderGL.Type.INT32;
252 	typeMap[WebGLRenderingContext.UNSIGNED_INT  ] = SpiderGL.Type.UINT32;
253 	typeMap[WebGLRenderingContext.FLOAT         ] = SpiderGL.Type.FLOAT32;
254 	return function (glType) {
255 		return typeMap[glType];
256 	};
257 })();
258 
259 /**
260  * Returns the size of the type expressed by the passed WebGL type symbolic constant.
261  *
262  * @param {number} glType A WebGL type symbolic constants, i.e. WebGLRenderingContext.UNSIGNED_BYTE.
263  * @return {number} The size in bytes of the type.
264  */
265 SpiderGL.Type.typeSizeFromGL = function (glType) {
266 	var sglType = SpiderGL.Type.typeFromGL(glType);
267 	return SpiderGL.Type.typeSize(sglType);
268 };
269 
270 /**
271  * Maps a SpiderGL type symbolic constant to a TypedArray constructor.
272  * For example, calling this function with SpiderGL.Type.UINT8 as argument will return Uint8Array.
273  *
274  * @param {number} sglType A SpiderGL type symbolic constants, i.e. SpiderGL.Type.UINT8.
275  * @return {function} The corresponding TypedArray constructor function, i.e. Uint8Array.
276  */
277 SpiderGL.Type.typeToTypedArrayConstructor = (function(){
278 	var typeMap = { };
279 	typeMap[SpiderGL.Type.NO_TYPE] = ArrayBuffer;
280 	typeMap[SpiderGL.Type.INT8   ] = Int8Array;
281 	typeMap[SpiderGL.Type.UINT8  ] = Uint8Array;
282 	typeMap[SpiderGL.Type.INT16  ] = Int16Array;
283 	typeMap[SpiderGL.Type.UINT16 ] = Uint16Array;
284 	typeMap[SpiderGL.Type.INT32  ] = Int32Array;
285 	typeMap[SpiderGL.Type.UINT32 ] = Uint32Array;
286 	typeMap[SpiderGL.Type.FLOAT32] = Float32Array;
287 	return function (sglType) {
288 		return typeMap[sglType];
289 	};
290 })();
291 
292 SpiderGL.Type.POINTS         = 0;
293 SpiderGL.Type.LINES          = 1;
294 SpiderGL.Type.LINE_LOOP      = 2;
295 SpiderGL.Type.LINE_STRIP     = 3;
296 SpiderGL.Type.TRIANGLES      = 4;
297 SpiderGL.Type.TRIANGLE_FAN   = 5;
298 SpiderGL.Type.TRIANGLE_STRIP = 6;
299 
300 SpiderGL.Type.primitiveToGL = (function(){
301 	var enumMap = { };
302 	enumMap[SpiderGL.Type.POINTS        ] = WebGLRenderingContext.POINTS;
303 	enumMap[SpiderGL.Type.LINES         ] = WebGLRenderingContext.LINES;
304 	enumMap[SpiderGL.Type.LINE_LOOP     ] = WebGLRenderingContext.LINE_LOOP;
305 	enumMap[SpiderGL.Type.LINE_STRIP    ] = WebGLRenderingContext.LINE_STRIP;
306 	enumMap[SpiderGL.Type.TRIANGLES     ] = WebGLRenderingContext.TRIANGLES;
307 	enumMap[SpiderGL.Type.TRIANGLE_FAN  ] = WebGLRenderingContext.TRIANGLE_FAN;
308 	enumMap[SpiderGL.Type.TRIANGLE_STRIP] = WebGLRenderingContext.TRIANGLE_STRIP;
309 	return function (sglEnum) {
310 		return enumMap[sglEnum];
311 	};
312 })();
313 
314 /**
315  * Tests the instance.
316  *
317  * The arg is tested to belong to a ctor function constructor.
318  *
319  * @param {any} arg The object to check.
320  * @param {constructor} ctor The class (i.e. the function constructor) that is tested for creating the object.
321  * @return {bool} True if arg is an instance of ctor, false otherwise.
322  */
323 SpiderGL.Type.instanceOf = function (arg, ctor) {
324 	return (arg instanceof ctor);
325 }
326 
327 /**
328  * Tests whether the argument is a number.
329  *
330  * @param {any} arg The object to check.
331  * @return {bool} True if arg is a number, false otherwise.
332  */
333 SpiderGL.Type.isNumber = function (arg) {
334 	return (typeof arg == "number");
335 }
336 
337 /**
338  * Tests whether the argument is a string.
339  *
340  * @param {any} arg The object to check.
341  * @return {bool} True if arg is a string, false otherwise.
342  */
343 SpiderGL.Type.isString = function (arg) {
344 	return (typeof arg == "string");
345 }
346 
347 /**
348  * Tests whether the argument is a function.
349  *
350  * @param {any} arg The object to check.
351  * @return {bool} True if arg is a function, false otherwise.
352  */
353 SpiderGL.Type.isFunction = function (arg) {
354 	return (typeof arg == "function");
355 }
356 
357 /**
358  * Tests whether the argument is an array.
359  *
360  * @param {any} arg The object to check.
361  * @return {bool} True if arg is an array, false otherwise.
362  */
363 SpiderGL.Type.isArray = function (arg) {
364 	return (arg && arg.constructor === Array);
365 }
366 
367 /**
368  * Tests whether the argument is a typed array.
369  *
370  * @param {any} arg The object to check.
371  * @return {bool} True if arg is a typed array, false otherwise.
372  */
373 SpiderGL.Type.isTypedArray = function (arg) {
374 	return (arg && (typeof arg.buffer != "undefined") && (arg.buffer instanceof ArrayBuffer));
375 }
376 
377 /**
378  * Implements inheritance.
379  *
380  * A class derivation is established between derived and base. The derived object can be successfully tested as being a base instance and inherits base properties and methods.
381  * It is possible to override base properties and methods by redefining them.
382  * This function must be called after assigning the derived prototype object.
383  *
384  * @param {constructor} derived The derived class.
385  * @param {constructor} base The base class.
386  *
387  * @example
388  * function Base(x, y) {
389  *   this.x = x;
390  *   this.y = y;
391  * };
392  *
393  * Base.prototype = {
394  *   alertX : function () { alert("Base X: " + this.x); },
395  *   alertY : function () { alert("Base Y: " + this.y); }
396  * };
397  *
398  * function Derived(x, y, z) {
399  *   Base.call(this, x, y);
400  *   this.z = z;
401  * };
402  *
403  * Derived.prototype = {
404  *   alertY : function () { alert("Derived Y: " + this.y); },
405  *   alertZ : function () { alert("Derived Z: " + this.z); },
406  * };
407  *
408  * SpiderGL.Type.extend(base, derived);
409  *
410  * var b = new Base(1, 2);
411  * b.alertX(); // alerts "Base X: 1"
412  * b.alertY(); // alerts "Base Y: 2"
413  *
414  * var d = new Base(3, 4, 5);
415  * d.alertX(); // alerts "Base X: 3"     (base method is kept)
416  * d.alertY(); // alerts "Derived Y: 4"  (base method is overridden)
417  * d.alertZ(); // alerts "Derived Y: 5"  (new derived method is called)
418  */
419 SpiderGL.Type.extend = function(derived, base /*, installBaseInfo*/) {
420 	function inheritance() { }
421 	inheritance.prototype = base.prototype;
422 
423 	var dproto = derived.prototype;
424 	var iproto = new inheritance();
425 	iproto.constructor = derived;
426 
427 	var getter = null;
428 	var setter = null;
429 	for (var p in dproto) {
430 		getter = dproto.__lookupGetter__(p);
431 		if (getter) { iproto.__defineGetter__(p, getter); }
432 
433 		setter = dproto.__lookupSetter__(p);
434 		if (setter) { iproto.__defineSetter__(p, setter); }
435 
436 		if (!getter && !setter) { iproto[p] = dproto[p]; }
437 	}
438 
439 	derived.prototype = iproto;
440 
441 	/*
442 	if (installBaseInfo) {
443 		derived.superConstructor = base;
444 		derived.superClass       = base.prototype;
445 	}
446 	*/
447 }
448 
449 SpiderGL.Type.defineClassGetter = function(ctor, name, func) {
450 	ctor.prototype.__defineGetter__(name, func);
451 }
452 
453 SpiderGL.Type.defineClassSetter = function(ctor, name, func) {
454 	ctor.prototype.__defineSetter__(name, func);
455 }
456 
457 SpiderGL.Type.defineObjectGetter = function(obj, name, func) {
458 	obj.__defineGetter__(name, func);
459 }
460 
461 SpiderGL.Type.defineObjectSetter = function(obj, name, func) {
462 	obj.__defineSetter__(name, func);
463 }
464 
465