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