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