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