1 /** 2 * @fileOverview 3 * primitive.gl.enchant.js 4 * @version 0.3.5 5 * @require gl.enchant.js v0.3.5+ 6 * @author UEI Corporation 7 * 8 * @description 9 */ 10 11 12 if (enchant.gl !== undefined) { 13 (function() { 14 enchant.gl.primitive = {}; 15 enchant.gl.primitive.Plane = enchant.Class.create(enchant.gl.Sprite3D, { 16 initialize: function(scale) { 17 enchant.gl.Sprite3D.call(this); 18 this.mesh = enchant.gl.Mesh.createPlane(scale); 19 } 20 }); 21 enchant.gl.primitive.PlaneXY = enchant.Class.create(enchant.gl.Sprite3D, { 22 initialize: function(scale) { 23 enchant.gl.Sprite3D.call(this); 24 this.mesh = enchant.gl.Mesh.createPlaneXY(scale); 25 } 26 }); 27 enchant.gl.primitive.PlaneYZ = enchant.Class.create(enchant.gl.Sprite3D, { 28 initialize: function(scale) { 29 enchant.gl.Sprite3D.call(this); 30 this.mesh = enchant.gl.Mesh.createPlaneYZ(scale); 31 } 32 }); 33 enchant.gl.primitive.PlaneXZ = enchant.Class.create(enchant.gl.Sprite3D, { 34 initialize: function(scale) { 35 enchant.gl.Sprite3D.call(this); 36 this.mesh = enchant.gl.Mesh.createPlaneXZ(scale); 37 } 38 }); 39 enchant.gl.primitive.Billboard = enchant.Class.create(enchant.gl.primitive.Plane, { 40 initialize: function(scale) { 41 var core = enchant.Core.instance; 42 enchant.gl.primitive.Plane.call(this, scale); 43 this.addEventListener('enterframe', function() { 44 if (core.currentScene3D._camera) { 45 this.rotation = core.currentScene3D._camera.invMat; 46 } 47 }); 48 } 49 }); 50 enchant.gl.primitive.BillboardAnimation = enchant.Class.create(enchant.gl.primitive.Billboard, { 51 initialize: function(divide, scale) { 52 enchant.gl.primitive.Billboard.call(this, scale); 53 if (typeof divide !== 'undefined') { 54 this.divide = divide; 55 } else { 56 this.divide = 4; 57 } 58 this.frame = 0; 59 }, 60 frame: { 61 get: function() { 62 return this._frame; 63 }, 64 set: function(frame) { 65 this._frame = frame; 66 var left = (frame % this.divide) / this.divide; 67 var top = 1 - ((frame / this.divide) | 0) / this.divide; 68 var right = left + (1 / this.divide); 69 var bottom = top - (1 / this.divide); 70 this.mesh.texCoords = [ 71 right, top, 72 left, top, 73 left, bottom, 74 right, bottom, 75 right, top, 76 left, top, 77 left, bottom, 78 right, bottom 79 ]; 80 } 81 } 82 }); 83 enchant.gl.primitive.BillboardY = enchant.Class.create(enchant.gl.primitive.Plane, { 84 initialize: function(scale) { 85 var core = enchant.Core.instance; 86 enchant.gl.primitive.Plane.call(this, scale); 87 this.addEventListener('render', function() { 88 if (core.currentScene3D._camera) { 89 this.rotation = core.currentScene3D._camera.invMatY; 90 } 91 }); 92 } 93 }); 94 enchant.gl.primitive.Box = enchant.Class.create(enchant.gl.Sprite3D, { 95 initialize: function(sx, sy, sz) { 96 enchant.gl.Sprite3D.call(this); 97 this.mesh = enchant.gl.Mesh.createBox(sx, sy, sz); 98 } 99 }); 100 enchant.gl.primitive.Cube = enchant.Class.create(enchant.gl.Sprite3D, { 101 initialize: function(scale) { 102 enchant.gl.Sprite3D.call(this); 103 this.mesh = enchant.gl.Mesh.createCube(scale); 104 } 105 }); 106 enchant.gl.primitive.Sphere = enchant.Class.create(enchant.gl.Sprite3D, { 107 initialize: function(r, v, h) { 108 enchant.gl.Sprite3D.call(this); 109 this.mesh = enchant.gl.Mesh.createSphere(r, v, h); 110 } 111 }); 112 enchant.gl.primitive.Cylinder = enchant.Class.create(enchant.gl.Sprite3D, { 113 initialize: function(r, h, v) { 114 enchant.gl.Sprite3D.call(this); 115 this.mesh = enchant.gl.Mesh.createCylinder(r, h, v); 116 } 117 }); 118 enchant.gl.primitive.Torus = enchant.Class.create(enchant.gl.Sprite3D, { 119 initialize: function(r, r2, v, v2) { 120 enchant.gl.Sprite3D.call(this); 121 this.mesh = enchant.gl.Mesh.createTorus(r, r2, v, v2); 122 } 123 }); 124 125 var proto = Object.getPrototypeOf(enchant.gl.Mesh); 126 proto._createPlane = function(type, scale) { 127 if (typeof scale === 'undefined') { 128 scale = 0.5; 129 } 130 var mesh = new enchant.gl.Mesh(); 131 var vertices; 132 if (type === 'yz') { 133 vertices = [ 134 0.0, 1.0, 1.0, 135 0.0, -1.0, 1.0, 136 0.0, -1.0, -1.0, 137 0.0, 1.0, -1.0, 138 139 0.0, 1.0, 1.0, 140 0.0, -1.0, 1.0, 141 0.0, -1.0, -1.0, 142 0.0, 1.0, -1.0 143 ]; 144 mesh.normals = [ 145 1.0, 0.0, 0.0, 146 1.0, 0.0, 0.0, 147 1.0, 0.0, 0.0, 148 1.0, 0.0, 0.0, 149 150 -1.0, 0.0, 0.0, 151 -1.0, 0.0, 0.0, 152 -1.0, 0.0, 0.0, 153 -1.0, 0.0, 0.0 154 ]; 155 } else if (type === 'xz') { 156 vertices = [ 157 1.0, 0.0, 1.0, 158 -1.0, 0.0, 1.0, 159 -1.0, 0.0, -1.0, 160 1.0, 0.0, -1.0, 161 162 1.0, 0.0, 1.0, 163 -1.0, 0.0, 1.0, 164 -1.0, 0.0, -1.0, 165 1.0, 0.0, -1.0 166 ]; 167 mesh.normals = [ 168 0.0, -1.0, 0.0, 169 0.0, -1.0, 0.0, 170 0.0, -1.0, 0.0, 171 0.0, -1.0, 0.0, 172 173 0.0, 1.0, 0.0, 174 0.0, 1.0, 0.0, 175 0.0, 1.0, 0.0, 176 0.0, 1.0, 0.0 177 ]; 178 } else { 179 vertices = [ 180 1.0, 1.0, 0.0, 181 -1.0, 1.0, 0.0, 182 -1.0, -1.0, 0.0, 183 1.0, -1.0, 0.0, 184 185 1.0, 1.0, 0.0, 186 -1.0, 1.0, 0.0, 187 -1.0, -1.0, 0.0, 188 1.0, -1.0, 0.0 189 ]; 190 mesh.normals = [ 191 0.0, 0.0, 1.0, 192 0.0, 0.0, 1.0, 193 0.0, 0.0, 1.0, 194 0.0, 0.0, 1.0, 195 196 0.0, 0.0, -1.0, 197 0.0, 0.0, -1.0, 198 0.0, 0.0, -1.0, 199 0.0, 0.0, -1.0 200 ]; 201 } 202 for (var i = 0, l = vertices.length; i < l; i++) { 203 vertices[i] *= scale; 204 } 205 mesh.vertices = vertices; 206 mesh.colors = [ 207 1.0, 1.0, 1.0, 1.0, 208 1.0, 1.0, 1.0, 1.0, 209 1.0, 1.0, 1.0, 1.0, 210 1.0, 1.0, 1.0, 1.0, 211 212 1.0, 1.0, 1.0, 1.0, 213 1.0, 1.0, 1.0, 1.0, 214 1.0, 1.0, 1.0, 1.0, 215 1.0, 1.0, 1.0, 1.0 216 ]; 217 mesh.texCoords = [ 218 1.0, 1.0, 219 0.0, 1.0, 220 0.0, 0.0, 221 1.0, 0.0, 222 223 1.0, 1.0, 224 0.0, 1.0, 225 0.0, 0.0, 226 1.0, 0.0 227 ]; 228 mesh.indices = [ 229 0, 1, 2, 230 2, 3, 0, 231 6, 5, 4, 232 4, 7, 6 233 ]; 234 return mesh; 235 }; 236 proto.createPlane = function(scale) { 237 return this._createPlane('xy', scale); 238 }; 239 proto.createPlaneXY = function(scale) { 240 return this._createPlane('xy', scale); 241 }; 242 proto.createPlaneYZ = function(scale) { 243 return this._createPlane('yz', scale); 244 }; 245 proto.createPlaneXZ = function(scale) { 246 return this._createPlane('xz', scale); 247 }; 248 proto.createBox = function(sx, sy, sz) { 249 if (typeof sx === 'undefined') { 250 sx = 0.5; 251 } 252 if (typeof sy === 'undefined') { 253 sy = 0.5; 254 } 255 if (typeof sz === 'undefined') { 256 sz = 0.5; 257 } 258 var mesh = new enchant.gl.Mesh(); 259 var vertices = [ 260 1.0, 1.0, 1.0, 261 -1.0, 1.0, 1.0, 262 -1.0, -1.0, 1.0, 263 1.0, -1.0, 1.0, 264 265 1.0, 1.0, -1.0, 266 -1.0, 1.0, -1.0, 267 -1.0, -1.0, -1.0, 268 1.0, -1.0, -1.0, 269 270 1.0, 1.0, 1.0, 271 -1.0, 1.0, 1.0, 272 -1.0, 1.0, -1.0, 273 1.0, 1.0, -1.0, 274 275 1.0, -1.0, 1.0, 276 -1.0, -1.0, 1.0, 277 -1.0, -1.0, -1.0, 278 1.0, -1.0, -1.0, 279 280 1.0, 1.0, 1.0, 281 1.0, -1.0, 1.0, 282 1.0, -1.0, -1.0, 283 1.0, 1.0, -1.0, 284 285 -1.0, 1.0, 1.0, 286 -1.0, -1.0, 1.0, 287 -1.0, -1.0, -1.0, 288 -1.0, 1.0, -1.0 289 ]; 290 for (var i = 0, l = vertices.length; i < l; i += 3) { 291 vertices[i] *= sx; 292 vertices[i + 1] *= sy; 293 vertices[i + 2] *= sz; 294 } 295 mesh.vertices = vertices; 296 297 mesh.colors = [ 298 1.0, 1.0, 1.0, 1.0, 299 1.0, 1.0, 1.0, 1.0, 300 1.0, 1.0, 1.0, 1.0, 301 1.0, 1.0, 1.0, 1.0, 302 303 1.0, 1.0, 1.0, 1.0, 304 1.0, 1.0, 1.0, 1.0, 305 1.0, 1.0, 1.0, 1.0, 306 1.0, 1.0, 1.0, 1.0, 307 308 1.0, 1.0, 1.0, 1.0, 309 1.0, 1.0, 1.0, 1.0, 310 1.0, 1.0, 1.0, 1.0, 311 1.0, 1.0, 1.0, 1.0, 312 313 1.0, 1.0, 1.0, 1.0, 314 1.0, 1.0, 1.0, 1.0, 315 1.0, 1.0, 1.0, 1.0, 316 1.0, 1.0, 1.0, 1.0, 317 318 1.0, 1.0, 1.0, 1.0, 319 1.0, 1.0, 1.0, 1.0, 320 1.0, 1.0, 1.0, 1.0, 321 1.0, 1.0, 1.0, 1.0, 322 323 1.0, 1.0, 1.0, 1.0, 324 1.0, 1.0, 1.0, 1.0, 325 1.0, 1.0, 1.0, 1.0, 326 1.0, 1.0, 1.0, 1.0 327 ]; 328 mesh.normals = [ 329 0.0, 0.0, 1.0, 330 0.0, 0.0, 1.0, 331 0.0, 0.0, 1.0, 332 0.0, 0.0, 1.0, 333 0.0, 0.0, -1.0, 334 0.0, 0.0, -1.0, 335 0.0, 0.0, -1.0, 336 0.0, 0.0, -1.0, 337 0.0, 1.0, 0.0, 338 0.0, 1.0, 0.0, 339 0.0, 1.0, 0.0, 340 0.0, 1.0, 0.0, 341 0.0, -1.0, 0.0, 342 0.0, -1.0, 0.0, 343 0.0, -1.0, 0.0, 344 0.0, -1.0, 0.0, 345 1.0, 0.0, 0.0, 346 1.0, 0.0, 0.0, 347 1.0, 0.0, 0.0, 348 1.0, 0.0, 0.0, 349 -1.0, 0.0, 0.0, 350 -1.0, 0.0, 0.0, 351 -1.0, 0.0, 0.0, 352 -1.0, 0.0, 0.0 353 ]; 354 mesh.texCoords = [ 355 1.0, 0.0, 356 0.0, 0.0, 357 0.0, 1.0, 358 1.0, 1.0, 359 360 1.0, 0.0, 361 0.0, 0.0, 362 0.0, 1.0, 363 1.0, 1.0, 364 365 1.0, 0.0, 366 0.0, 0.0, 367 0.0, 1.0, 368 1.0, 1.0, 369 370 1.0, 0.0, 371 0.0, 0.0, 372 0.0, 1.0, 373 1.0, 1.0, 374 375 1.0, 0.0, 376 0.0, 0.0, 377 0.0, 1.0, 378 1.0, 1.0, 379 380 1.0, 0.0, 381 0.0, 0.0, 382 0.0, 1.0, 383 1.0, 1.0 384 ]; 385 var a = [ 386 0, 1, 2, 387 2, 3, 0, 388 389 2, 1, 0, 390 0, 3, 2, 391 392 2, 1, 0, 393 0, 3, 2, 394 395 0, 1, 2, 396 2, 3, 0, 397 398 0, 1, 2, 399 2, 3, 0, 400 401 2, 1, 0, 402 0, 3, 2 403 ]; 404 for (i = 0; i < 6 * 6; i++) { 405 a[i] += Math.floor(i / 6) * 4; 406 } 407 mesh.indices = a; 408 return mesh; 409 }; 410 proto.createCube = function(s) { 411 return this.createBox(s, s, s); 412 }; 413 proto.createSphere = function(r, h, v) { 414 var i, j, l; 415 if (typeof r === 'undefined') { 416 r = 1; 417 } 418 if (typeof h === 'undefined') { 419 h = 20; 420 } 421 if (typeof v === 'undefined') { 422 v = 20; 423 } 424 var mesh = new enchant.gl.Mesh(); 425 var vertices = []; 426 var texCoords = []; 427 for (i = 0; i < v; i++) { 428 for (j = 0; j < h; j++) { 429 vertices[vertices.length] = Math.sin(Math.PI * i / (v - 1)) * Math.cos(Math.PI * 2 * j / (h - 1)) * r; 430 vertices[vertices.length] = Math.cos(Math.PI * i / (v - 1)) * r; 431 vertices[vertices.length] = Math.sin(Math.PI * i / (v - 1)) * Math.sin(Math.PI * 2 * j / (h - 1)) * r; 432 texCoords[texCoords.length] = 1.0 - j / (h - 1); 433 texCoords[texCoords.length] = 1.0 - i / (v - 1); 434 } 435 } 436 mesh.vertices = vertices; 437 mesh.texCoords = texCoords; 438 var colors = []; 439 for (i = 0, l = mesh.vertices.length / 3 * 4; i < l; i++) { 440 colors[colors.length] = 1.0; 441 } 442 mesh.colors = colors; 443 mesh.normals = vertices.slice(0); 444 var indices = []; 445 446 for (i = 0; i < v - 1; i++) { 447 for (j = 0; j < h; j++) { 448 indices[indices.length] = h * (i + 1) + j; 449 indices[indices.length] = h * i + j; 450 indices[indices.length] = h * (i + 1) + (1 + j) % h; 451 indices[indices.length] = h * i + (1 + j) % h; 452 indices[indices.length] = h * (i + 1) + (1 + j) % h; 453 indices[indices.length] = h * i + j; 454 } 455 } 456 mesh.indices = indices; 457 return mesh; 458 }; 459 proto.createCylinder = function(r, h, v) { 460 if (typeof r === 'undefined') { 461 r = 0.5; 462 } 463 if (typeof h === 'undefined') { 464 h = 1; 465 } 466 if (typeof v === 'undefined') { 467 v = 20; 468 } 469 var vertices = []; 470 var indices = []; 471 var texCoords = []; 472 var normals = []; 473 vertices[vertices.length] = 0; 474 vertices[vertices.length] = h; 475 vertices[vertices.length] = 0; 476 477 normals[normals.length] = 0; 478 normals[normals.length] = 1; 479 normals[normals.length] = 0; 480 481 texCoords[texCoords.length] = 0; 482 texCoords[texCoords.length] = 1; 483 484 vertices[vertices.length] = 0; 485 vertices[vertices.length] = -h; 486 vertices[vertices.length] = 0; 487 488 normals[normals.length] = 0; 489 normals[normals.length] = -1; 490 normals[normals.length] = 0; 491 492 texCoords[texCoords.length] = 0; 493 texCoords[texCoords.length] = 0; 494 495 var cos = 0; 496 var sin = 0; 497 for (var i = 0; i < v; i++) { 498 cos = Math.cos(Math.PI * 2 * i / (v - 1)); 499 sin = Math.sin(Math.PI * 2 * i / (v - 1)); 500 501 vertices[vertices.length] = cos * r; 502 vertices[vertices.length] = h; 503 vertices[vertices.length] = sin * r; 504 505 normals[normals.length] = 0; 506 normals[normals.length] = 1; 507 normals[normals.length] = 0; 508 509 texCoords[texCoords.length] = i / (v - 1); 510 texCoords[texCoords.length] = 1; 511 512 vertices[vertices.length] = cos * r; 513 vertices[vertices.length] = -h; 514 vertices[vertices.length] = sin * r; 515 516 normals[normals.length] = 0; 517 normals[normals.length] = -1; 518 normals[normals.length] = 0; 519 520 texCoords[texCoords.length] = i / (v - 1); 521 texCoords[texCoords.length] = 0; 522 523 vertices[vertices.length] = cos * r; 524 vertices[vertices.length] = h; 525 vertices[vertices.length] = sin * r; 526 527 normals[normals.length] = cos; 528 normals[normals.length] = 0; 529 normals[normals.length] = sin; 530 531 texCoords[texCoords.length] = i / (v - 1); 532 texCoords[texCoords.length] = 1; 533 534 vertices[vertices.length] = cos * r; 535 vertices[vertices.length] = -h; 536 vertices[vertices.length] = sin * r; 537 538 normals[normals.length] = cos; 539 normals[normals.length] = 0; 540 normals[normals.length] = sin; 541 542 texCoords[texCoords.length] = i / (v - 1); 543 texCoords[texCoords.length] = 0; 544 } 545 for (i = 0; i < v - 1; i++) { 546 indices[indices.length] = 0; 547 indices[indices.length] = 2 + i * 4 + 4; 548 indices[indices.length] = 2 + i * 4 + 0; 549 indices[indices.length] = 1; 550 indices[indices.length] = 2 + i * 4 + 1; 551 indices[indices.length] = 2 + i * 4 + 5; 552 553 indices[indices.length] = 2 + i * 4 + 2; 554 indices[indices.length] = 2 + i * 4 + 6; 555 indices[indices.length] = 2 + i * 4 + 3; 556 indices[indices.length] = 2 + i * 4 + 6; 557 indices[indices.length] = 2 + i * 4 + 7; 558 indices[indices.length] = 2 + i * 4 + 3; 559 } 560 561 var mesh = new enchant.gl.Mesh(); 562 mesh.vertices = vertices; 563 mesh.indices = indices; 564 mesh.texCoords = texCoords; 565 mesh.normals = normals; 566 mesh.setBaseColor('#ffffff'); 567 return mesh; 568 }; 569 proto.createTorus = function(r, r2, v, v2) { 570 var i, j; 571 if (typeof r === 'undefined') { 572 r = 1.0; 573 } 574 if (typeof r2 === 'undefined') { 575 r2 = 0.3; 576 } 577 if (typeof v === 'undefined') { 578 v = 20; 579 } 580 if (typeof v2 === 'undefined') { 581 v2 = 20; 582 } 583 var ring = []; 584 var norm = []; 585 var rad; 586 var cos; 587 var sin; 588 for (i = 0; i < v2; i++) { 589 rad = Math.PI * 2 * i / (v2 - 1); 590 cos = Math.cos(rad); 591 sin = Math.sin(rad); 592 ring[ring.length] = 0; 593 ring[ring.length] = sin * r2; 594 ring[ring.length] = cos * r2 + r - r2; 595 norm[norm.length] = 0; 596 norm[norm.length] = sin; 597 norm[norm.length] = cos; 598 } 599 var vertices = []; 600 var normals = []; 601 var texCoords = []; 602 for (i = 0; i < v; i++) { 603 rad = Math.PI * 2 * i / (v - 1); 604 cos = Math.cos(rad); 605 sin = Math.sin(rad); 606 for (j = 0; j < ring.length; j += 3) { 607 vertices[vertices.length] = ring[j] * cos - ring[j + 2] * sin; 608 vertices[vertices.length] = ring[j + 1]; 609 vertices[vertices.length] = ring[j + 2] * cos + ring[j] * sin; 610 normals[normals.length] = norm[j] * cos - ring[j + 2] * sin; 611 normals[normals.length] = norm[j + 1]; 612 normals[normals.length] = norm[j + 2] * cos + ring[j] + sin; 613 texCoords[texCoords.length] = 1.0 - i / (v - 1); 614 texCoords[texCoords.length] = j / (ring.length - 3); 615 } 616 } 617 var indices = []; 618 var c, c2; 619 for (i = 0; i < v - 1; i++) { 620 for (j = 0; j < v2 - 1; j++) { 621 c = v2 * i + j; 622 c2 = v2 * (i + 1) + j; 623 indices[indices.length] = c; 624 indices[indices.length] = c + 1; 625 indices[indices.length] = c2; 626 indices[indices.length] = c2 + 1; 627 indices[indices.length] = c2; 628 indices[indices.length] = c + 1; 629 } 630 } 631 var mesh = new enchant.gl.Mesh(); 632 mesh.vertices = vertices; 633 mesh.normals = normals; 634 mesh.texCoords = texCoords; 635 mesh.indices = indices; 636 mesh.setBaseColor('#ffffff'); 637 638 return mesh; 639 }; 640 }()); 641 } 642