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