source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/src/core/BufferGeometry.js@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

File size: 11.6 KB
Line 
1/**
2 * @author alteredq / http://alteredqualia.com/
3 */
4
5THREE.BufferGeometry = function () {
6
7 this.id = THREE.GeometryIdCount ++;
8 this.uuid = THREE.Math.generateUUID();
9
10 this.name = '';
11
12 // attributes
13
14 this.attributes = {};
15
16 // attributes typed arrays are kept only if dynamic flag is set
17
18 this.dynamic = true;
19
20 // offsets for chunks when using indexed elements
21
22 this.offsets = [];
23
24 // boundings
25
26 this.boundingBox = null;
27 this.boundingSphere = null;
28
29 this.hasTangents = false;
30
31 // for compatibility
32
33 this.morphTargets = [];
34
35};
36
37THREE.BufferGeometry.prototype = {
38
39 constructor: THREE.BufferGeometry,
40
41 addAttribute: function( name, type, numItems, itemSize ) {
42
43 this.attributes[ name ] = {
44
45 itemSize: itemSize,
46 array: new type( numItems * itemSize )
47
48 };
49
50 },
51
52 applyMatrix: function ( matrix ) {
53
54 var positionArray;
55 var normalArray;
56
57 if ( this.attributes[ "position" ] ) positionArray = this.attributes[ "position" ].array;
58 if ( this.attributes[ "normal" ] ) normalArray = this.attributes[ "normal" ].array;
59
60 if ( positionArray !== undefined ) {
61
62 matrix.multiplyVector3Array( positionArray );
63 this.verticesNeedUpdate = true;
64
65 }
66
67 if ( normalArray !== undefined ) {
68
69 var normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
70
71 normalMatrix.multiplyVector3Array( normalArray );
72
73 this.normalizeNormals();
74
75 this.normalsNeedUpdate = true;
76
77 }
78
79 },
80
81 computeBoundingBox: function () {
82
83 if ( this.boundingBox === null ) {
84
85 this.boundingBox = new THREE.Box3();
86
87 }
88
89 var positions = this.attributes[ "position" ].array;
90
91 if ( positions ) {
92
93 var bb = this.boundingBox;
94 var x, y, z;
95
96 if( positions.length >= 3 ) {
97 bb.min.x = bb.max.x = positions[ 0 ];
98 bb.min.y = bb.max.y = positions[ 1 ];
99 bb.min.z = bb.max.z = positions[ 2 ];
100 }
101
102 for ( var i = 3, il = positions.length; i < il; i += 3 ) {
103
104 x = positions[ i ];
105 y = positions[ i + 1 ];
106 z = positions[ i + 2 ];
107
108 // bounding box
109
110 if ( x < bb.min.x ) {
111
112 bb.min.x = x;
113
114 } else if ( x > bb.max.x ) {
115
116 bb.max.x = x;
117
118 }
119
120 if ( y < bb.min.y ) {
121
122 bb.min.y = y;
123
124 } else if ( y > bb.max.y ) {
125
126 bb.max.y = y;
127
128 }
129
130 if ( z < bb.min.z ) {
131
132 bb.min.z = z;
133
134 } else if ( z > bb.max.z ) {
135
136 bb.max.z = z;
137
138 }
139
140 }
141
142 }
143
144 if ( positions === undefined || positions.length === 0 ) {
145
146 this.boundingBox.min.set( 0, 0, 0 );
147 this.boundingBox.max.set( 0, 0, 0 );
148
149 }
150
151 },
152
153 computeBoundingSphere: function () {
154
155 var box = new THREE.Box3();
156 var vector = new THREE.Vector3();
157
158 return function () {
159
160 if ( this.boundingSphere === null ) {
161
162 this.boundingSphere = new THREE.Sphere();
163
164 }
165
166 var positions = this.attributes[ "position" ].array;
167
168 if ( positions ) {
169
170 box.makeEmpty();
171
172 var center = this.boundingSphere.center;
173
174 for ( var i = 0, il = positions.length; i < il; i += 3 ) {
175
176 vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
177 box.addPoint( vector );
178
179 }
180
181 box.center( center );
182
183 var maxRadiusSq = 0;
184
185 for ( var i = 0, il = positions.length; i < il; i += 3 ) {
186
187 vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
188 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
189
190 }
191
192 this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
193
194 }
195
196 }
197
198 }(),
199
200 computeVertexNormals: function () {
201
202 if ( this.attributes[ "position" ] ) {
203
204 var i, il;
205 var j, jl;
206
207 var nVertexElements = this.attributes[ "position" ].array.length;
208
209 if ( this.attributes[ "normal" ] === undefined ) {
210
211 this.attributes[ "normal" ] = {
212
213 itemSize: 3,
214 array: new Float32Array( nVertexElements )
215
216 };
217
218 } else {
219
220 // reset existing normals to zero
221
222 for ( i = 0, il = this.attributes[ "normal" ].array.length; i < il; i ++ ) {
223
224 this.attributes[ "normal" ].array[ i ] = 0;
225
226 }
227
228 }
229
230 var positions = this.attributes[ "position" ].array;
231 var normals = this.attributes[ "normal" ].array;
232
233 var vA, vB, vC, x, y, z,
234
235 pA = new THREE.Vector3(),
236 pB = new THREE.Vector3(),
237 pC = new THREE.Vector3(),
238
239 cb = new THREE.Vector3(),
240 ab = new THREE.Vector3();
241
242 // indexed elements
243
244 if ( this.attributes[ "index" ] ) {
245
246 var indices = this.attributes[ "index" ].array;
247
248 var offsets = this.offsets;
249
250 for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
251
252 var start = offsets[ j ].start;
253 var count = offsets[ j ].count;
254 var index = offsets[ j ].index;
255
256 for ( i = start, il = start + count; i < il; i += 3 ) {
257
258 vA = index + indices[ i ];
259 vB = index + indices[ i + 1 ];
260 vC = index + indices[ i + 2 ];
261
262 x = positions[ vA * 3 ];
263 y = positions[ vA * 3 + 1 ];
264 z = positions[ vA * 3 + 2 ];
265 pA.set( x, y, z );
266
267 x = positions[ vB * 3 ];
268 y = positions[ vB * 3 + 1 ];
269 z = positions[ vB * 3 + 2 ];
270 pB.set( x, y, z );
271
272 x = positions[ vC * 3 ];
273 y = positions[ vC * 3 + 1 ];
274 z = positions[ vC * 3 + 2 ];
275 pC.set( x, y, z );
276
277 cb.subVectors( pC, pB );
278 ab.subVectors( pA, pB );
279 cb.cross( ab );
280
281 normals[ vA * 3 ] += cb.x;
282 normals[ vA * 3 + 1 ] += cb.y;
283 normals[ vA * 3 + 2 ] += cb.z;
284
285 normals[ vB * 3 ] += cb.x;
286 normals[ vB * 3 + 1 ] += cb.y;
287 normals[ vB * 3 + 2 ] += cb.z;
288
289 normals[ vC * 3 ] += cb.x;
290 normals[ vC * 3 + 1 ] += cb.y;
291 normals[ vC * 3 + 2 ] += cb.z;
292
293 }
294
295 }
296
297 // non-indexed elements (unconnected triangle soup)
298
299 } else {
300
301 for ( i = 0, il = positions.length; i < il; i += 9 ) {
302
303 x = positions[ i ];
304 y = positions[ i + 1 ];
305 z = positions[ i + 2 ];
306 pA.set( x, y, z );
307
308 x = positions[ i + 3 ];
309 y = positions[ i + 4 ];
310 z = positions[ i + 5 ];
311 pB.set( x, y, z );
312
313 x = positions[ i + 6 ];
314 y = positions[ i + 7 ];
315 z = positions[ i + 8 ];
316 pC.set( x, y, z );
317
318 cb.subVectors( pC, pB );
319 ab.subVectors( pA, pB );
320 cb.cross( ab );
321
322 normals[ i ] = cb.x;
323 normals[ i + 1 ] = cb.y;
324 normals[ i + 2 ] = cb.z;
325
326 normals[ i + 3 ] = cb.x;
327 normals[ i + 4 ] = cb.y;
328 normals[ i + 5 ] = cb.z;
329
330 normals[ i + 6 ] = cb.x;
331 normals[ i + 7 ] = cb.y;
332 normals[ i + 8 ] = cb.z;
333
334 }
335
336 }
337
338 this.normalizeNormals();
339
340 this.normalsNeedUpdate = true;
341
342 }
343
344 },
345
346 normalizeNormals: function () {
347
348 var normals = this.attributes[ "normal" ].array;
349
350 var x, y, z, n;
351
352 for ( var i = 0, il = normals.length; i < il; i += 3 ) {
353
354 x = normals[ i ];
355 y = normals[ i + 1 ];
356 z = normals[ i + 2 ];
357
358 n = 1.0 / Math.sqrt( x * x + y * y + z * z );
359
360 normals[ i ] *= n;
361 normals[ i + 1 ] *= n;
362 normals[ i + 2 ] *= n;
363
364 }
365
366 },
367
368 computeTangents: function () {
369
370 // based on http://www.terathon.com/code/tangent.html
371 // (per vertex tangents)
372
373 if ( this.attributes[ "index" ] === undefined ||
374 this.attributes[ "position" ] === undefined ||
375 this.attributes[ "normal" ] === undefined ||
376 this.attributes[ "uv" ] === undefined ) {
377
378 console.warn( "Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()" );
379 return;
380
381 }
382
383 var indices = this.attributes[ "index" ].array;
384 var positions = this.attributes[ "position" ].array;
385 var normals = this.attributes[ "normal" ].array;
386 var uvs = this.attributes[ "uv" ].array;
387
388 var nVertices = positions.length / 3;
389
390 if ( this.attributes[ "tangent" ] === undefined ) {
391
392 var nTangentElements = 4 * nVertices;
393
394 this.attributes[ "tangent" ] = {
395
396 itemSize: 4,
397 array: new Float32Array( nTangentElements )
398
399 };
400
401 }
402
403 var tangents = this.attributes[ "tangent" ].array;
404
405 var tan1 = [], tan2 = [];
406
407 for ( var k = 0; k < nVertices; k ++ ) {
408
409 tan1[ k ] = new THREE.Vector3();
410 tan2[ k ] = new THREE.Vector3();
411
412 }
413
414 var xA, yA, zA,
415 xB, yB, zB,
416 xC, yC, zC,
417
418 uA, vA,
419 uB, vB,
420 uC, vC,
421
422 x1, x2, y1, y2, z1, z2,
423 s1, s2, t1, t2, r;
424
425 var sdir = new THREE.Vector3(), tdir = new THREE.Vector3();
426
427 function handleTriangle( a, b, c ) {
428
429 xA = positions[ a * 3 ];
430 yA = positions[ a * 3 + 1 ];
431 zA = positions[ a * 3 + 2 ];
432
433 xB = positions[ b * 3 ];
434 yB = positions[ b * 3 + 1 ];
435 zB = positions[ b * 3 + 2 ];
436
437 xC = positions[ c * 3 ];
438 yC = positions[ c * 3 + 1 ];
439 zC = positions[ c * 3 + 2 ];
440
441 uA = uvs[ a * 2 ];
442 vA = uvs[ a * 2 + 1 ];
443
444 uB = uvs[ b * 2 ];
445 vB = uvs[ b * 2 + 1 ];
446
447 uC = uvs[ c * 2 ];
448 vC = uvs[ c * 2 + 1 ];
449
450 x1 = xB - xA;
451 x2 = xC - xA;
452
453 y1 = yB - yA;
454 y2 = yC - yA;
455
456 z1 = zB - zA;
457 z2 = zC - zA;
458
459 s1 = uB - uA;
460 s2 = uC - uA;
461
462 t1 = vB - vA;
463 t2 = vC - vA;
464
465 r = 1.0 / ( s1 * t2 - s2 * t1 );
466
467 sdir.set(
468 ( t2 * x1 - t1 * x2 ) * r,
469 ( t2 * y1 - t1 * y2 ) * r,
470 ( t2 * z1 - t1 * z2 ) * r
471 );
472
473 tdir.set(
474 ( s1 * x2 - s2 * x1 ) * r,
475 ( s1 * y2 - s2 * y1 ) * r,
476 ( s1 * z2 - s2 * z1 ) * r
477 );
478
479 tan1[ a ].add( sdir );
480 tan1[ b ].add( sdir );
481 tan1[ c ].add( sdir );
482
483 tan2[ a ].add( tdir );
484 tan2[ b ].add( tdir );
485 tan2[ c ].add( tdir );
486
487 }
488
489 var i, il;
490 var j, jl;
491 var iA, iB, iC;
492
493 var offsets = this.offsets;
494
495 for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
496
497 var start = offsets[ j ].start;
498 var count = offsets[ j ].count;
499 var index = offsets[ j ].index;
500
501 for ( i = start, il = start + count; i < il; i += 3 ) {
502
503 iA = index + indices[ i ];
504 iB = index + indices[ i + 1 ];
505 iC = index + indices[ i + 2 ];
506
507 handleTriangle( iA, iB, iC );
508
509 }
510
511 }
512
513 var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
514 var n = new THREE.Vector3(), n2 = new THREE.Vector3();
515 var w, t, test;
516
517 function handleVertex( v ) {
518
519 n.x = normals[ v * 3 ];
520 n.y = normals[ v * 3 + 1 ];
521 n.z = normals[ v * 3 + 2 ];
522
523 n2.copy( n );
524
525 t = tan1[ v ];
526
527 // Gram-Schmidt orthogonalize
528
529 tmp.copy( t );
530 tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
531
532 // Calculate handedness
533
534 tmp2.crossVectors( n2, t );
535 test = tmp2.dot( tan2[ v ] );
536 w = ( test < 0.0 ) ? -1.0 : 1.0;
537
538 tangents[ v * 4 ] = tmp.x;
539 tangents[ v * 4 + 1 ] = tmp.y;
540 tangents[ v * 4 + 2 ] = tmp.z;
541 tangents[ v * 4 + 3 ] = w;
542
543 }
544
545 for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
546
547 var start = offsets[ j ].start;
548 var count = offsets[ j ].count;
549 var index = offsets[ j ].index;
550
551 for ( i = start, il = start + count; i < il; i += 3 ) {
552
553 iA = index + indices[ i ];
554 iB = index + indices[ i + 1 ];
555 iC = index + indices[ i + 2 ];
556
557 handleVertex( iA );
558 handleVertex( iB );
559 handleVertex( iC );
560
561 }
562
563 }
564
565 this.hasTangents = true;
566 this.tangentsNeedUpdate = true;
567
568 },
569
570 clone: function () {
571
572 var geometry = new THREE.BufferGeometry();
573
574 var types = [ Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array ];
575
576 for ( var attr in this.attributes ) {
577
578 var sourceAttr = this.attributes[ attr ];
579 var sourceArray = sourceAttr.array;
580
581 var attribute = {
582
583 itemSize: sourceAttr.itemSize,
584 numItems: sourceAttr.numItems,
585 array: null
586
587 };
588
589 for ( var i = 0, il = types.length; i < il; i ++ ) {
590
591 var type = types[ i ];
592
593 if ( sourceArray instanceof type ) {
594
595 attribute.array = new type( sourceArray );
596 break;
597
598 }
599
600 }
601
602 geometry.attributes[ attr ] = attribute;
603
604 }
605
606 for ( var i = 0, il = this.offsets.length; i < il; i ++ ) {
607
608 var offset = this.offsets[ i ];
609
610 geometry.offsets.push( {
611
612 start: offset.start,
613 index: offset.index,
614 count: offset.count
615
616 } );
617
618 }
619
620 return geometry;
621
622 },
623
624 dispose: function () {
625
626 this.dispatchEvent( { type: 'dispose' } );
627
628 }
629
630};
631
632THREE.EventDispatcher.prototype.apply( THREE.BufferGeometry.prototype );
Note: See TracBrowser for help on using the repository browser.