1 /**
2 * @author mrdoob / http://mrdoob.com/
3 * @author supereggbert / http://www.paulbrunt.co.uk/
4 * @author julianwa / https://github.com/julianwa
5 */
6
7 /**@constructor*/
8 THREE.Projector = function() {
9
10 var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
11 _vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
12 _face, _face3Count, _face3Pool = [], _face3PoolLength = 0,
13 _face4Count, _face4Pool = [], _face4PoolLength = 0,
14 _line, _lineCount, _linePool = [], _linePoolLength = 0,
15 _particle, _particleCount, _particlePool = [], _particlePoolLength = 0,
16
17 _renderData = { objects: [], sprites: [], lights: [], elements: [] },
18
19 _vector3 = new THREE.Vector3(),
20 _vector4 = new THREE.Vector4(),
21
22 _viewProjectionMatrix = new THREE.Matrix4(),
23 _modelViewProjectionMatrix = new THREE.Matrix4(),
24 _normalMatrix = new THREE.Matrix3(),
25
26 _frustum = new THREE.Frustum(),
27
28 _clippedVertex1PositionScreen = new THREE.Vector4(),
29 _clippedVertex2PositionScreen = new THREE.Vector4(),
30
31 _face3VertexNormals;
32
33 this.projectVector = function ( vector, camera ) {
34
35 camera.matrixWorldInverse.getInverse( camera.matrixWorld );
36
37 _viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
38 _viewProjectionMatrix.multiplyVector3( vector );
39
40 return vector;
41
42 };
43
44 this.unprojectVector = function ( vector, camera ) {
45
46 camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
47
48 _viewProjectionMatrix.multiply( camera.matrixWorld, camera.projectionMatrixInverse );
49 _viewProjectionMatrix.multiplyVector3( vector );
50
51 return vector;
52
53 };
54
55 this.pickingRay = function ( vector, camera ) {
56
57 var end, ray, t;
58
59 // set two vectors with opposing z values
60 vector.z = -1.0;
61 end = new THREE.Vector3( vector.x, vector.y, 1.0 );
62
63 this.unprojectVector( vector, camera );
64 this.unprojectVector( end, camera );
65
66 // find direction from vector to end
67 end.subSelf( vector ).normalize();
68
69 return new THREE.Ray( vector, end );
70
71 };
72
73 var projectGraph = function ( root, sortObjects ) {
74
75 _objectCount = 0;
76
77 _renderData.objects.length = 0;
78 _renderData.sprites.length = 0;
79 _renderData.lights.length = 0;
80
81 var projectObject = function ( parent ) {
82
83 for ( var c = 0, cl = parent.children.length; c < cl; c ++ ) {
84
85 var object = parent.children[ c ];
86
87 if ( object.visible === false ) continue;
88
89 if ( object instanceof THREE.Light ) {
90
91 _renderData.lights.push( object );
92
93 } else if ( object instanceof THREE.Mesh || object instanceof THREE.Line ) {
94
95 if ( object.frustumCulled === false || _frustum.contains( object ) === true ) {
96
97 _object = getNextObjectInPool();
98 _object.object = object;
99
100 if ( object.renderDepth !== null ) {
101
102 _object.z = object.renderDepth;
103
104 } else {
105
106 _vector3.copy( object.matrixWorld.getPosition() );
107 _viewProjectionMatrix.multiplyVector3( _vector3 );
108 _object.z = _vector3.z;
109
110 }
111
112 _renderData.objects.push( _object );
113
114 }
115
116 } else if ( object instanceof THREE.Sprite || object instanceof THREE.Particle ) {
117
118 _object = getNextObjectInPool();
119 _object.object = object;
120
121 // TODO: Find an elegant and performant solution and remove this dupe code.
122
123 if ( object.renderDepth !== null ) {
124
125 _object.z = object.renderDepth;
126
127 } else {
128
129 _vector3.copy( object.matrixWorld.getPosition() );
130 _viewProjectionMatrix.multiplyVector3( _vector3 );
131 _object.z = _vector3.z;
132
133 }
134
135 _renderData.sprites.push( _object );
136
137 } else {
138
139 _object = getNextObjectInPool();
140 _object.object = object;
141
142 if ( object.renderDepth !== null ) {
143
144 _object.z = object.renderDepth;
145
146 } else {
147
148 _vector3.copy( object.matrixWorld.getPosition() );
149 _viewProjectionMatrix.multiplyVector3( _vector3 );
150 _object.z = _vector3.z;
151
152 }
153
154 _renderData.objects.push( _object );
155
156 }
157
158 projectObject( object );
159
160 }
161
162 };
163
164 projectObject( root );
165
166 if ( sortObjects === true ) _renderData.objects.sort( painterSort );
167
168 return _renderData;
169
170 };
171
172 this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
173
174 var near = camera.near, far = camera.far, visible = false,
175 o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object, modelMatrix,
176 geometry, vertices, vertex, vertexPositionScreen,
177 faces, face, faceVertexNormals, normal, faceVertexUvs, uvs,
178 v1, v2, v3, v4, isFaceMaterial, objectMaterials, material, side;
179
180 _face3Count = 0;
181 _face4Count = 0;
182 _lineCount = 0;
183 _particleCount = 0;
184
185 _renderData.elements.length = 0;
186
187 scene.updateMatrixWorld();
188
189 if ( camera.parent === undefined ) camera.updateMatrixWorld();
190
191 camera.matrixWorldInverse.getInverse( camera.matrixWorld );
192
193 _viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
194
195 _frustum.setFromMatrix( _viewProjectionMatrix );
196
197 _renderData = projectGraph( scene, sortObjects );
198
199 for ( o = 0, ol = _renderData.objects.length; o < ol; o ++ ) {
200
201 object = _renderData.objects[ o ].object;
202
203 modelMatrix = object.matrixWorld;
204
205 _vertexCount = 0;
206
207 if ( object instanceof THREE.Mesh ) {
208
209 geometry = object.geometry;
210
211 vertices = geometry.vertices;
212 faces = geometry.faces;
213 faceVertexUvs = geometry.faceVertexUvs;
214
215 _normalMatrix.getInverse( modelMatrix );
216 _normalMatrix.transpose();
217
218 isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
219 objectMaterials = isFaceMaterial === true ? object.material : null;
220
221 side = object.material.side;
222
223 for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
224
225 _vertex = getNextVertexInPool();
226 _vertex.positionWorld.copy( vertices[ v ] );
227
228 modelMatrix.multiplyVector3( _vertex.positionWorld );
229
230 _vertex.positionScreen.copy( _vertex.positionWorld );
231 _viewProjectionMatrix.multiplyVector4( _vertex.positionScreen );
232
233 _vertex.positionScreen.x /= _vertex.positionScreen.w;
234 _vertex.positionScreen.y /= _vertex.positionScreen.w;
235
236 _vertex.visible = _vertex.positionScreen.z > near && _vertex.positionScreen.z < far;
237
238 }
239
240 for ( f = 0, fl = faces.length; f < fl; f ++ ) {
241
242 face = faces[ f ];
243
244 material = isFaceMaterial === true ? objectMaterials.materials[ face.materialIndex ] : object.material;
245
246 if ( material === undefined ) continue;
247
248 side = material.side;
249
250 if ( face instanceof THREE.Face3 ) {
251
252 v1 = _vertexPool[ face.a ];
253 v2 = _vertexPool[ face.b ];
254 v3 = _vertexPool[ face.c ];
255
256 if ( v1.visible === true && v2.visible === true && v3.visible === true ) {
257
258 visible = ( ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
259 ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
260
261 if ( side === THREE.DoubleSide || visible === ( side === THREE.FrontSide ) ) {
262
263 _face = getNextFace3InPool();
264
265 _face.v1.copy( v1 );
266 _face.v2.copy( v2 );
267 _face.v3.copy( v3 );
268
269 } else {
270
271 continue;
272
273 }
274
275 } else {
276
277 continue;
278
279 }
280
281 } else if ( face instanceof THREE.Face4 ) {
282
283 v1 = _vertexPool[ face.a ];
284 v2 = _vertexPool[ face.b ];
285 v3 = _vertexPool[ face.c ];
286 v4 = _vertexPool[ face.d ];
287
288 if ( v1.visible === true && v2.visible === true && v3.visible === true && v4.visible === true ) {
289
290 visible = ( v4.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
291 ( v4.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ||
292 ( v2.positionScreen.x - v3.positionScreen.x ) * ( v4.positionScreen.y - v3.positionScreen.y ) -
293 ( v2.positionScreen.y - v3.positionScreen.y ) * ( v4.positionScreen.x - v3.positionScreen.x ) < 0;
294
295
296 if ( side === THREE.DoubleSide || visible === ( side === THREE.FrontSide ) ) {
297
298 _face = getNextFace4InPool();
299
300 _face.v1.copy( v1 );
301 _face.v2.copy( v2 );
302 _face.v3.copy( v3 );
303 _face.v4.copy( v4 );
304
305 } else {
306
307 continue;
308
309 }
310
311 } else {
312
313 continue;
314
315 }
316
317 }
318
319 _face.normalWorld.copy( face.normal );
320
321 if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) _face.normalWorld.negate();
322 _normalMatrix.multiplyVector3( _face.normalWorld ).normalize();
323
324 _face.centroidWorld.copy( face.centroid );
325 modelMatrix.multiplyVector3( _face.centroidWorld );
326
327 _face.centroidScreen.copy( _face.centroidWorld );
328 _viewProjectionMatrix.multiplyVector3( _face.centroidScreen );
329
330 faceVertexNormals = face.vertexNormals;
331
332 for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
333
334 normal = _face.vertexNormalsWorld[ n ];
335 normal.copy( faceVertexNormals[ n ] );
336
337 if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) normal.negate();
338
339 _normalMatrix.multiplyVector3( normal ).normalize();
340
341 }
342
343 _face.vertexNormalsLength = faceVertexNormals.length;
344
345 for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) {
346
347 uvs = faceVertexUvs[ c ][ f ];
348
349 if ( uvs === undefined ) continue;
350
351 for ( u = 0, ul = uvs.length; u < ul; u ++ ) {
352
353 _face.uvs[ c ][ u ] = uvs[ u ];
354
355 }
356
357 }
358
359 _face.color = face.color;
360 _face.material = material;
361
362 _face.z = _face.centroidScreen.z;
363
364 _renderData.elements.push( _face );
365
366 }
367
368 } else if ( object instanceof THREE.Line ) {
369
370 _modelViewProjectionMatrix.multiply( _viewProjectionMatrix, modelMatrix );
371
372 vertices = object.geometry.vertices;
373
374 v1 = getNextVertexInPool();
375 v1.positionScreen.copy( vertices[ 0 ] );
376 _modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
377
378 // Handle LineStrip and LinePieces
379 var step = object.type === THREE.LinePieces ? 2 : 1;
380
381 for ( v = 1, vl = vertices.length; v < vl; v ++ ) {
382
383 v1 = getNextVertexInPool();
384 v1.positionScreen.copy( vertices[ v ] );
385 _modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
386
387 if ( ( v + 1 ) % step > 0 ) continue;
388
389 v2 = _vertexPool[ _vertexCount - 2 ];
390
391 _clippedVertex1PositionScreen.copy( v1.positionScreen );
392 _clippedVertex2PositionScreen.copy( v2.positionScreen );
393
394 if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) {
395
396 // Perform the perspective divide
397 _clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
398 _clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
399
400 _line = getNextLineInPool();
401 _line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
402 _line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
403
404 _line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
405
406 _line.material = object.material;
407
408 _renderData.elements.push( _line );
409
410 }
411
412 }
413
414 }
415
416 }
417
418 for ( o = 0, ol = _renderData.sprites.length; o < ol; o++ ) {
419
420 object = _renderData.sprites[ o ].object;
421
422 modelMatrix = object.matrixWorld;
423
424 if ( object instanceof THREE.Particle ) {
425
426 _vector4.set( modelMatrix.elements[12], modelMatrix.elements[13], modelMatrix.elements[14], 1 );
427 _viewProjectionMatrix.multiplyVector4( _vector4 );
428
429 _vector4.z /= _vector4.w;
430
431 if ( _vector4.z > 0 && _vector4.z < 1 ) {
432
433 _particle = getNextParticleInPool();
434 _particle.object = object;
435 _particle.x = _vector4.x / _vector4.w;
436 _particle.y = _vector4.y / _vector4.w;
437 _particle.z = _vector4.z;
438
439 _particle.rotation = object.rotation.z;
440
441 _particle.scale.x = object.scale.x * Math.abs( _particle.x - ( _vector4.x + camera.projectionMatrix.elements[0] ) / ( _vector4.w + camera.projectionMatrix.elements[12] ) );
442 _particle.scale.y = object.scale.y * Math.abs( _particle.y - ( _vector4.y + camera.projectionMatrix.elements[5] ) / ( _vector4.w + camera.projectionMatrix.elements[13] ) );
443
444 _particle.material = object.material;
445
446 _renderData.elements.push( _particle );
447
448 }
449
450 }
451
452 }
453
454 if ( sortElements === true ) _renderData.elements.sort( painterSort );
455
456 return _renderData;
457
458 };
459
460 // Pools
461
462 function getNextObjectInPool() {
463
464 if ( _objectCount === _objectPoolLength ) {
465
466 var object = new THREE.RenderableObject();
467 _objectPool.push( object );
468 _objectPoolLength ++;
469 _objectCount ++;
470 return object;
471
472 }
473
474 return _objectPool[ _objectCount ++ ];
475
476 }
477
478 function getNextVertexInPool() {
479
480 if ( _vertexCount === _vertexPoolLength ) {
481
482 var vertex = new THREE.RenderableVertex();
483 _vertexPool.push( vertex );
484 _vertexPoolLength ++;
485 _vertexCount ++;
486 return vertex;
487
488 }
489
490 return _vertexPool[ _vertexCount ++ ];
491
492 }
493
494 function getNextFace3InPool() {
495
496 if ( _face3Count === _face3PoolLength ) {
497
498 var face = new THREE.RenderableFace3();
499 _face3Pool.push( face );
500 _face3PoolLength ++;
501 _face3Count ++;
502 return face;
503
504 }
505
506 return _face3Pool[ _face3Count ++ ];
507
508
509 }
510
511 function getNextFace4InPool() {
512
513 if ( _face4Count === _face4PoolLength ) {
514
515 var face = new THREE.RenderableFace4();
516 _face4Pool.push( face );
517 _face4PoolLength ++;
518 _face4Count ++;
519 return face;
520
521 }
522
523 return _face4Pool[ _face4Count ++ ];
524
525 }
526
527 function getNextLineInPool() {
528
529 if ( _lineCount === _linePoolLength ) {
530
531 var line = new THREE.RenderableLine();
532 _linePool.push( line );
533 _linePoolLength ++;
534 _lineCount ++
535 return line;
536
537 }
538
539 return _linePool[ _lineCount ++ ];
540
541 }
542
543 function getNextParticleInPool() {
544
545 if ( _particleCount === _particlePoolLength ) {
546
547 var particle = new THREE.RenderableParticle();
548 _particlePool.push( particle );
549 _particlePoolLength ++;
550 _particleCount ++
551 return particle;
552
553 }
554
555 return _particlePool[ _particleCount ++ ];
556
557 }
558
559 //
560
561 function painterSort( a, b ) {
562
563 return b.z - a.z;
564
565 }
566
567 function clipLine( s1, s2 ) {
568
569 var alpha1 = 0, alpha2 = 1,
570
571 // Calculate the boundary coordinate of each vertex for the near and far clip planes,
572 // Z = -1 and Z = +1, respectively.
573 bc1near = s1.z + s1.w,
574 bc2near = s2.z + s2.w,
575 bc1far = - s1.z + s1.w,
576 bc2far = - s2.z + s2.w;
577
578 if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
579
580 // Both vertices lie entirely within all clip planes.
581 return true;
582
583 } else if ( ( bc1near < 0 && bc2near < 0) || (bc1far < 0 && bc2far < 0 ) ) {
584
585 // Both vertices lie entirely outside one of the clip planes.
586 return false;
587
588 } else {
589
590 // The line segment spans at least one clip plane.
591
592 if ( bc1near < 0 ) {
593
594 // v1 lies outside the near plane, v2 inside
595 alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) );
596
597 } else if ( bc2near < 0 ) {
598
599 // v2 lies outside the near plane, v1 inside
600 alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) );
601
602 }
603
604 if ( bc1far < 0 ) {
605
606 // v1 lies outside the far plane, v2 inside
607 alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) );
608
609 } else if ( bc2far < 0 ) {
610
611 // v2 lies outside the far plane, v2 inside
612 alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) );
613
614 }
615
616 if ( alpha2 < alpha1 ) {
617
618 // The line segment spans two boundaries, but is outside both of them.
619 // (This can't happen when we're only clipping against just near/far but good
620 // to leave the check here for future usage if other clip planes are added.)
621 return false;
622
623 } else {
624
625 // Update the s1 and s2 vertices to match the clipped line segment.
626 s1.lerpSelf( s2, alpha1 );
627 s2.lerpSelf( s1, 1 - alpha2 );
628
629 return true;
630
631 }
632
633 }
634
635 }
636
637 };
638
nike free rn
new balance hombre baratas
cinturones gucci
ugg rebajas
cinturon gucci
ray ban baratas
nike cortez
peuterey mujer
christian louboutin madrid
mbt zapatos
gafas ray ban baratas
mbt ofertas
air max blancas
mbt barcelona
nike air max 90
woolrich barcelona
nike mujer
botas ugg
gafas de sol carrera aratas
air max 2016 baratas
oakley baratas
nike air max 2016