1/** 2 * @author mrdoob / http://mrdoob.com/ 3 * @author supereggbert / http://www.paulbrunt.co.uk/ 4 * @author julianwa / https://github.com/julianwa 5 */ 6 7THREEW.RenderableObject = function () { 8 9 this.id = 0; 10 11 this.object = null; 12 this.z = 0; 13 this.renderOrder = 0; 14 15}; 16 17// 18 19THREEW.RenderableFace = function () { 20 21 this.id = 0; 22 23 this.v1 = new THREEW.RenderableVertex(); 24 this.v2 = new THREEW.RenderableVertex(); 25 this.v3 = new THREEW.RenderableVertex(); 26 27 this.normalModel = new THREEW.Vector3(); 28 29 this.vertexNormalsModel = [ new THREEW.Vector3(), new THREEW.Vector3(), new THREEW.Vector3() ]; 30 this.vertexNormalsLength = 0; 31 32 this.color = new THREEW.Color(); 33 this.material = null; 34 this.uvs = [ new THREEW.Vector2(), new THREEW.Vector2(), new THREEW.Vector2() ]; 35 36 this.z = 0; 37 this.renderOrder = 0; 38 39}; 40 41// 42 43THREEW.RenderableVertex = function () { 44 45 this.position = new THREEW.Vector3(); 46 this.positionWorld = new THREEW.Vector3(); 47 this.positionScreen = new THREEW.Vector4(); 48 49 this.visible = true; 50 51}; 52 53THREEW.RenderableVertex.prototype.copy = function ( vertex ) { 54 55 this.positionWorld.copy( vertex.positionWorld ); 56 this.positionScreen.copy( vertex.positionScreen ); 57 58}; 59 60// 61 62THREEW.RenderableLine = function () { 63 64 this.id = 0; 65 66 this.v1 = new THREEW.RenderableVertex(); 67 this.v2 = new THREEW.RenderableVertex(); 68 69 this.vertexColors = [ new THREEW.Color(), new THREEW.Color() ]; 70 this.material = null; 71 72 this.z = 0; 73 this.renderOrder = 0; 74 75}; 76 77// 78 79THREEW.RenderableSprite = function () { 80 81 this.id = 0; 82 83 this.object = null; 84 85 this.x = 0; 86 this.y = 0; 87 this.z = 0; 88 89 this.rotation = 0; 90 this.scale = new THREEW.Vector2(); 91 92 this.material = null; 93 this.renderOrder = 0; 94 95}; 96 97// 98 99THREEW.Projector = function () { 100 101 var _object, _objectCount, _objectPool = [], _objectPoolLength = 0, 102 _vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0, 103 _face, _faceCount, _facePool = [], _facePoolLength = 0, 104 _line, _lineCount, _linePool = [], _linePoolLength = 0, 105 _sprite, _spriteCount, _spritePool = [], _spritePoolLength = 0, 106 107 _renderData = { objects: [], lights: [], elements: [] }, 108 109 _vector3 = new THREEW.Vector3(), 110 _vector4 = new THREEW.Vector4(), 111 112 _clipBox = new THREEW.Box3( new THREEW.Vector3( - 1, - 1, - 1 ), new THREEW.Vector3( 1, 1, 1 ) ), 113 _boundingBox = new THREEW.Box3(), 114 _points3 = new Array( 3 ), 115 116 _viewMatrix = new THREEW.Matrix4(), 117 _viewProjectionMatrix = new THREEW.Matrix4(), 118 119 _modelMatrix, 120 _modelViewProjectionMatrix = new THREEW.Matrix4(), 121 122 _normalMatrix = new THREEW.Matrix3(), 123 124 _frustum = new THREEW.Frustum(), 125 126 _clippedVertex1PositionScreen = new THREEW.Vector4(), 127 _clippedVertex2PositionScreen = new THREEW.Vector4(); 128 129 // 130 131 this.projectVector = function ( vector, camera ) { 132 133 console.warn( 'THREEW.Projector: .projectVector() is now vector.project().' ); 134 vector.project( camera ); 135 136 }; 137 138 this.unprojectVector = function ( vector, camera ) { 139 140 console.warn( 'THREEW.Projector: .unprojectVector() is now vector.unproject().' ); 141 vector.unproject( camera ); 142 143 }; 144 145 this.pickingRay = function () { 146 147 console.error( 'THREEW.Projector: .pickingRay() is now raycaster.setFromCamera().' ); 148 149 }; 150 151 // 152 153 var RenderList = function () { 154 155 var normals = []; 156 var colors = []; 157 var uvs = []; 158 159 var object = null; 160 var material = null; 161 162 var normalMatrix = new THREEW.Matrix3(); 163 164 function setObject( value ) { 165 166 object = value; 167 material = object.material; 168 169 normalMatrix.getNormalMatrix( object.matrixWorld ); 170 171 normals.length = 0; 172 colors.length = 0; 173 uvs.length = 0; 174 175 } 176 177 function projectVertex( vertex ) { 178 179 var position = vertex.position; 180 var positionWorld = vertex.positionWorld; 181 var positionScreen = vertex.positionScreen; 182 183 positionWorld.copy( position ).applyMatrix4( _modelMatrix ); 184 positionScreen.copy( positionWorld ).applyMatrix4( _viewProjectionMatrix ); 185 186 var invW = 1 / positionScreen.w; 187 188 positionScreen.x *= invW; 189 positionScreen.y *= invW; 190 positionScreen.z *= invW; 191 192 vertex.visible = positionScreen.x >= - 1 && positionScreen.x <= 1 && 193 positionScreen.y >= - 1 && positionScreen.y <= 1 && 194 positionScreen.z >= - 1 && positionScreen.z <= 1; 195 196 } 197 198 function pushVertex( x, y, z ) { 199 200 _vertex = getNextVertexInPool(); 201 _vertex.position.set( x, y, z ); 202
203 projectVertex( _vertex ); 204 205 } 206 207 function pushNormal( x, y, z ) { 208 209 normals.push( x, y, z ); 210 211 } 212 213 function pushColor( r, g, b ) { 214 215 colors.push( r, g, b ); 216 217 } 218 219 function pushUv( x, y ) { 220 221 uvs.push( x, y ); 222 223 } 224 225 function checkTriangleVisibility( v1, v2, v3 ) { 226 227 if ( v1.visible === true || v2.visible === true || v3.visible === true ) return true; 228 229 _points3[ 0 ] = v1.positionScreen; 230 _points3[ 1 ] = v2.positionScreen; 231 _points3[ 2 ] = v3.positionScreen; 232 233 return _clipBox.intersectsBox( _boundingBox.setFromPoints( _points3 ) ); 234 235 } 236 237 function checkBackfaceCulling( v1, v2, v3 ) { 238 239 return ( ( v3.positionScreen.x - v1.positionScreen.x ) * 240 ( v2.positionScreen.y - v1.positionScreen.y ) - 241 ( v3.positionScreen.y - v1.positionScreen.y ) * 242 ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0; 243 244 } 245 246 function pushLine( a, b ) { 247 248 var v1 = _vertexPool[ a ]; 249 var v2 = _vertexPool[ b ]; 250 251 // Clip 252 253 v1.positionScreen.copy( v1.position ).applyMatrix4( _modelViewProjectionMatrix ); 254 v2.positionScreen.copy( v2.position ).applyMatrix4( _modelViewProjectionMatrix ); 255 256 if ( clipLine( v1.positionScreen, v2.positionScreen ) === true ) { 257 258 // Perform the perspective divide 259 v1.positionScreen.multiplyScalar( 1 / v1.positionScreen.w ); 260 v2.positionScreen.multiplyScalar( 1 / v2.positionScreen.w ); 261 262 _line = getNextLineInPool(); 263 _line.id = object.id; 264 _line.v1.copy( v1 ); 265 _line.v2.copy( v2 ); 266 _line.z = Math.max( v1.positionScreen.z, v2.positionScreen.z ); 267 _line.renderOrder = object.renderOrder; 268 269 _line.material = object.material; 270 271 if ( object.material.vertexColors === THREEW.VertexColors ) { 272 273 _line.vertexColors[ 0 ].fromArray( colors, a * 3 ); 274 _line.vertexColors[ 1 ].fromArray( colors, b * 3 ); 275 276 } 277 278 _renderData.elements.push( _line ); 279 280 } 281 282 } 283 284 function pushTriangle( a, b, c, material ) { 285 286 var v1 = _vertexPool[ a ]; 287 var v2 = _vertexPool[ b ]; 288 var v3 = _vertexPool[ c ]; 289 290 if ( checkTriangleVisibility( v1, v2, v3 ) === false ) return; 291 292 if ( material.side === THREEW.DoubleSide || checkBackfaceCulling( v1, v2, v3 ) === true ) { 293 294 _face = getNextFaceInPool(); 295 296 _face.id = object.id; 297 _face.v1.copy( v1 ); 298 _face.v2.copy( v2 ); 299 _face.v3.copy( v3 ); 300 _face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3; 301 _face.renderOrder = object.renderOrder; 302 303 // face normal 304 _vector3.subVectors( v3.position, v2.position ); 305 _vector4.subVectors( v1.position, v2.position ); 306 _vector3.cross( _vector4 ); 307 _face.normalModel.copy( _vector3 ); 308 _face.normalModel.applyMatrix3( normalMatrix ).normalize(); 309 310 for ( var i = 0; i < 3; i ++ ) { 311 312 var normal = _face.vertexNormalsModel[ i ]; 313 normal.fromArray( normals, arguments[ i ] * 3 ); 314 normal.applyMatrix3( normalMatrix ).normalize(); 315 316 var uv = _face.uvs[ i ]; 317 uv.fromArray( uvs, arguments[ i ] * 2 ); 318 319 } 320 321 _face.vertexNormalsLength = 3; 322 323 _face.material = material; 324 325 if ( material.vertexColors === THREEW.FaceColors || material.vertexColors === THREEW.VertexColors ) { 326 327 _face.color.fromArray( colors, a * 3 ); 328 329 } 330 331 _renderData.elements.push( _face ); 332 333 } 334 335 } 336 337 return { 338 setObject: setObject, 339 projectVertex: projectVertex, 340 checkTriangleVisibility: checkTriangleVisibility, 341 checkBackfaceCulling: checkBackfaceCulling, 342 pushVertex: pushVertex, 343 pushNormal: pushNormal, 344 pushColor: pushColor, 345 pushUv: pushUv, 346 pushLine: pushLine, 347 pushTriangle: pushTriangle 348 }; 349 350 }; 351 352 var renderList = new RenderList(); 353 354 function projectObject( object ) { 355 356 if ( object.visible === false ) return; 357 358 if ( object instanceof THREEW.Light ) { 359 360 _renderData.lights.push( object ); 361 362 } else if ( object instanceof THREEW.Mesh || object instanceof THREEW.Line || object instanceof THREEW.Points ) { 363 364 if ( object.material.visible === false ) return; 365 if ( object.frustumCulled === true && _frustum.intersectsObject( object ) === false ) return; 366 367 addObject( object ); 368 369 } else if ( object instanceof THREEW.Sprite ) { 370 371 if ( object.material.visible === false ) return; 372 if ( object.frustumCulled === true && _frustum.intersectsSprite( object ) === false ) return; 373 374 addObject( object ); 375 376 } 377 378 var children = object.children; 379 380 for ( var i = 0, l = children.length; i < l; i ++ ) { 381 382 projectObject( children[ i ] ); 383 384 } 385 386 } 387 388 function addObject( object ) { 389 390 _object = getNextObjectInPool(); 391 _object.id = object.id; 392 _object.object = object; 393 394 _vector3.setFromMatrixPosition( object.matrixWorld );
395 _vector3.applyMatrix4( _viewProjectionMatrix ); 396 _object.z = _vector3.z; 397 _object.renderOrder = object.renderOrder; 398 399 _renderData.objects.push( _object ); 400 401 } 402 403 this.projectScene = function ( scene, camera, sortObjects, sortElements ) { 404 405 _faceCount = 0; 406 _lineCount = 0; 407 _spriteCount = 0; 408 409 _renderData.elements.length = 0; 410 411 if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); 412 if ( camera.parent === null ) camera.updateMatrixWorld(); 413 414 _viewMatrix.copy( camera.matrixWorldInverse ); 415 _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix ); 416 417 _frustum.setFromMatrix( _viewProjectionMatrix ); 418 419 // 420 421 _objectCount = 0; 422 423 _renderData.objects.length = 0; 424 _renderData.lights.length = 0; 425 426 projectObject( scene ); 427 428 if ( sortObjects === true ) { 429 430 _renderData.objects.sort( painterSort ); 431 432 } 433 434 // 435 436 var objects = _renderData.objects; 437 438 for ( var o = 0, ol = objects.length; o < ol; o ++ ) { 439 440 var object = objects[ o ].object; 441 var geometry = object.geometry; 442 443 renderList.setObject( object ); 444 445 _modelMatrix = object.matrixWorld; 446 447 _vertexCount = 0; 448 449 if ( object instanceof THREEW.Mesh ) { 450 451 if ( geometry instanceof THREEW.BufferGeometry ) { 452 453 var material = object.material; 454 455 var isMultiMaterial = Array.isArray( material ); 456 457 var attributes = geometry.attributes; 458 var groups = geometry.groups; 459 460 if ( attributes.position === undefined ) continue; 461 462 var positions = attributes.position.array; 463 464 for ( var i = 0, l = positions.length; i < l; i += 3 ) { 465 466 var x = positions[ i ]; 467 var y = positions[ i + 1 ]; 468 var z = positions[ i + 2 ]; 469 470 if ( material.morphTargets === true ) { 471 472 var morphTargets = geometry.morphAttributes.position; 473 var morphTargetsRelative = geometry.morphTargetsRelative; 474 var morphInfluences = object.morphTargetInfluences; 475 476 for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { 477 478 var influence = morphInfluences[ t ]; 479 480 if ( influence === 0 ) continue; 481 482 var target = morphTargets[ t ]; 483 484 if ( morphTargetsRelative ) { 485 486 x += target.getX( i / 3 ) * influence; 487 y += target.getY( i / 3 ) * influence; 488 z += target.getZ( i / 3 ) * influence; 489 490 } else { 491 492 x += ( target.getX( i / 3 ) - positions[ i ] ) * influence; 493 y += ( target.getY( i / 3 ) - positions[ i + 1 ] ) * influence; 494 z += ( target.getZ( i / 3 ) - positions[ i + 2 ] ) * influence; 495 496 } 497 498 } 499 500 } 501 502 renderList.pushVertex( x, y, z ); 503 504 } 505 506 if ( attributes.normal !== undefined ) { 507 508 var normals = attributes.normal.array; 509 510 for ( var i = 0, l = normals.length; i < l; i += 3 ) { 511 512 renderList.pushNormal( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ); 513 514 } 515 516 } 517 518 if ( attributes.color !== undefined ) { 519 520 var colors = attributes.color.array; 521 522 for ( var i = 0, l = colors.length; i < l; i += 3 ) { 523 524 renderList.pushColor( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ); 525 526 } 527 528 } 529 530 if ( attributes.uv !== undefined ) { 531 532 var uvs = attributes.uv.array; 533 534 for ( var i = 0, l = uvs.length; i < l; i += 2 ) { 535 536 renderList.pushUv( uvs[ i ], uvs[ i + 1 ] ); 537 538 } 539 540 } 541 542 if ( geometry.index !== null ) { 543 544 var indices = geometry.index.array; 545 546 if ( groups.length > 0 ) { 547 548 for ( var g = 0; g < groups.length; g ++ ) { 549 550 var group = groups[ g ]; 551 552 material = isMultiMaterial === true 553 ? object.material[ group.materialIndex ] 554 : object.material; 555 556 if ( material === undefined ) continue; 557 558 for ( var i = group.start, l = group.start + group.count; i < l; i += 3 ) { 559 560 renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ], material ); 561 562 } 563 564 } 565 566 } else { 567 568 for ( var i = 0, l = indices.length; i < l; i += 3 ) { 569 570 renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ], material ); 571 572 } 573 574 } 575 576 } else { 577 578 if ( groups.length > 0 ) { 579 580 for ( var g = 0; g < groups.length; g ++ ) { 581 582 var group = groups[ g ]; 583 584 material = isMultiMaterial === true 585 ? object.material[ group.materialIndex ] 586 : object.material; 587 588 if ( material === undefined ) continue; 589 590 for ( var i = group.start, l = group.start + group.count; i < l; i += 3 ) { 591 592 renderList.pushTriangle( i, i + 1, i + 2, material ); 593 594 } 595 596 } 597 598 } else { 599 600 for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) { 601 602 renderList.pushTriangle( i, i + 1, i + 2, material ); 603 604 } 605 606 } 607 608 } 609 610 } else if ( geometry instanceof THREEW.Geometry ) { 611 612 var vertices = geometry.vertices; 613 var faces = geometry.faces; 614 var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; 615 616 _normalMatrix.getNormalMatrix( _modelMatrix ); 617 618 var material = object.material; 619 620 var isMultiMaterial = Array.isArray( material ); 621 622 for ( var v = 0, vl = vertices.length; v < vl; v ++ ) { 623 624 var vertex = vertices[ v ]; 625 626 _vector3.copy( vertex ); 627 628 if ( material.morphTargets === true ) { 629 630 var morphTargets = geometry.morphTargets; 631 var morphInfluences = object.morphTargetInfluences; 632 633 for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { 634 635 var influence = morphInfluences[ t ]; 636 637 if ( influence === 0 ) continue; 638 639 var target = morphTargets[ t ]; 640 var targetVertex = target.vertices[ v ]; 641 642 _vector3.x += ( targetVertex.x - vertex.x ) * influence; 643 _vector3.y += ( targetVertex.y - vertex.y ) * influence; 644 _vector3.z += ( targetVertex.z - vertex.z ) * influence; 645 646 } 647 648 } 649 650 renderList.pushVertex( _vector3.x, _vector3.y, _vector3.z ); 651 652 } 653 654 for ( var f = 0, fl = faces.length; f < fl; f ++ ) { 655 656 var face = faces[ f ]; 657 658 material = isMultiMaterial === true 659 ? object.material[ face.materialIndex ] 660 : object.material; 661 662 if ( material === undefined ) continue; 663 664 var side = material.side; 665 666 var v1 = _vertexPool[ face.a ]; 667 var v2 = _vertexPool[ face.b ]; 668 var v3 = _vertexPool[ face.c ]; 669 670 if ( renderList.checkTriangleVisibility( v1, v2, v3 ) === false ) continue; 671
672 var visible = renderList.checkBackfaceCulling( v1, v2, v3 ); 673 674 if ( side !== THREEW.DoubleSide ) { 675 676 if ( side === THREEW.FrontSide && visible === false ) continue; 677 if ( side === THREEW.BackSide && visible === true ) continue; 678 679 } 680 681 _face = getNextFaceInPool(); 682 683 _face.id = object.id; 684 _face.v1.copy( v1 ); 685 _face.v2.copy( v2 ); 686 _face.v3.copy( v3 ); 687 688 _face.normalModel.copy( face.normal ); 689 690 if ( visible === false && ( side === THREEW.BackSide || side === THREEW.DoubleSide ) ) { 691 692 _face.normalModel.negate(); 693 694 } 695 696 _face.normalModel.applyMatrix3( _normalMatrix ).normalize(); 697 698 var faceVertexNormals = face.vertexNormals; 699 700 for ( var n = 0, nl = Math.min( faceVertexNormals.length, 3 ); n < nl; n ++ ) { 701 702 var normalModel = _face.vertexNormalsModel[ n ]; 703 normalModel.copy( faceVertexNormals[ n ] ); 704 705 if ( visible === false && ( side === THREEW.BackSide || side === THREEW.DoubleSide ) ) { 706 707 normalModel.negate(); 708 709 } 710 711 normalModel.applyMatrix3( _normalMatrix ).normalize(); 712 713 } 714 715 _face.vertexNormalsLength = faceVertexNormals.length; 716 717 var vertexUvs = faceVertexUvs[ f ]; 718 719 if ( vertexUvs !== undefined ) { 720 721 for ( var u = 0; u < 3; u ++ ) { 722 723 _face.uvs[ u ].copy( vertexUvs[ u ] ); 724 725 } 726 727 } 728 729 _face.color = face.color; 730 _face.material = material; 731 732 _face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3; 733 _face.renderOrder = object.renderOrder; 734 735 _renderData.elements.push( _face ); 736 737 } 738 739 } 740 741 } else if ( object instanceof THREEW.Line ) { 742 743 _modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix ); 744 745 if ( geometry instanceof THREEW.BufferGeometry ) { 746 747 var attributes = geometry.attributes; 748 749 if ( attributes.position !== undefined ) { 750 751 var positions = attributes.position.array; 752 753 for ( var i = 0, l = positions.length; i < l; i += 3 ) { 754 755 renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ); 756 757 } 758 759 if ( attributes.color !== undefined ) { 760 761 var colors = attributes.color.array; 762 763 for ( var i = 0, l = colors.length; i < l; i += 3 ) { 764 765 renderList.pushColor( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ); 766 767 } 768 769 } 770 771 if ( geometry.index !== null ) { 772 773 var indices = geometry.index.array; 774 775 for ( var i = 0, l = indices.length; i < l; i += 2 ) { 776 777 renderList.pushLine( indices[ i ], indices[ i + 1 ] ); 778 779 } 780 781 } else { 782 783 var step = object instanceof THREEW.LineSegments ? 2 : 1; 784 785 for ( var i = 0, l = ( positions.length / 3 ) - 1; i < l; i += step ) { 786 787 renderList.pushLine( i, i + 1 ); 788 789 } 790 791 } 792 793 } 794 795 } else if ( geometry instanceof THREEW.Geometry ) { 796 797 var vertices = object.geometry.vertices; 798 799 if ( vertices.length === 0 ) continue; 800 801 v1 = getNextVertexInPool(); 802 v1.positionScreen.copy( vertices[ 0 ] ).applyMatrix4( _modelViewProjectionMatrix ); 803 804 var step = object instanceof THREEW.LineSegments ? 2 : 1; 805 806 for ( var v = 1, vl = vertices.length; v < vl; v ++ ) { 807 808 v1 = getNextVertexInPool(); 809 v1.positionScreen.copy( vertices[ v ] ).applyMatrix4( _modelViewProjectionMatrix ); 810 811 if ( ( v + 1 ) % step > 0 ) continue; 812 813 v2 = _vertexPool[ _vertexCount - 2 ]; 814 815 _clippedVertex1PositionScreen.copy( v1.positionScreen ); 816 _clippedVertex2PositionScreen.copy( v2.positionScreen ); 817 818 if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) { 819 820 // Perform the perspective divide 821 _clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w ); 822 _clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w ); 823 824 _line = getNextLineInPool(); 825 826 _line.id = object.id; 827 _line.v1.positionScreen.copy( _clippedVertex1PositionScreen ); 828 _line.v2.positionScreen.copy( _clippedVertex2PositionScreen ); 829 830 _line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z ); 831 _line.renderOrder = object.renderOrder; 832 833 _line.material = object.material; 834 835 if ( object.material.vertexColors === THREEW.VertexColors ) { 836 837 _line.vertexColors[ 0 ].copy( object.geometry.colors[ v ] ); 838 _line.vertexColors[ 1 ].copy( object.geometry.colors[ v - 1 ] ); 839 840 } 841 842 _renderData.elements.push( _line ); 843 844 } 845 846 } 847 848 } 849 850 } else if ( object instanceof THREEW.Points ) { 851 852 _modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix ); 853 854 if ( geometry instanceof THREEW.Geometry ) { 855 856 var vertices = object.geometry.vertices; 857 858 for ( var v = 0, vl = vertices.length; v < vl; v ++ ) { 859 860 var vertex = vertices[ v ]; 861 862 _vector4.set( vertex.x, vertex.y, vertex.z, 1 );
863 _vector4.applyMatrix4( _modelViewProjectionMatrix ); 864 865 pushPoint( _vector4, object, camera ); 866 867 } 868 869 } else if ( geometry instanceof THREEW.BufferGeometry ) { 870 871 var attributes = geometry.attributes; 872 873 if ( attributes.position !== undefined ) { 874 875 var positions = attributes.position.array; 876 877 for ( var i = 0, l = positions.length; i < l; i += 3 ) { 878 879 _vector4.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ], 1 ); 880 _vector4.applyMatrix4( _modelViewProjectionMatrix ); 881 882 pushPoint( _vector4, object, camera ); 883 884 } 885 886 } 887 888 } 889 890 } else if ( object instanceof THREEW.Sprite ) { 891 892 object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); 893 _vector4.set( _modelMatrix.elements[ 12 ], _modelMatrix.elements[ 13 ], _modelMatrix.elements[ 14 ], 1 ); 894 _vector4.applyMatrix4( _viewProjectionMatrix ); 895 896 pushPoint( _vector4, object, camera ); 897 898 } 899 900 } 901 902 if ( sortElements === true ) { 903 904 _renderData.elements.sort( painterSort ); 905 906 } 907 908 return _renderData; 909 910 }; 911 912 function pushPoint( _vector4, object, camera ) { 913 914 var invW = 1 / _vector4.w; 915 916 _vector4.z *= invW; 917 918 if ( _vector4.z >= - 1 && _vector4.z <= 1 ) { 919 920 _sprite = getNextSpriteInPool(); 921 _sprite.id = object.id; 922 _sprite.x = _vector4.x * invW; 923 _sprite.y = _vector4.y * invW; 924 _sprite.z = _vector4.z; 925 _sprite.renderOrder = object.renderOrder; 926 _sprite.object = object; 927 928 _sprite.rotation = object.rotation; 929 930 _sprite.scale.x = object.scale.x * Math.abs( _sprite.x - ( _vector4.x + camera.projectionMatrix.elements[ 0 ] ) / ( _vector4.w + camera.projectionMatrix.elements[ 12 ] ) ); 931 _sprite.scale.y = object.scale.y * Math.abs( _sprite.y - ( _vector4.y + camera.projectionMatrix.elements[ 5 ] ) / ( _vector4.w + camera.projectionMatrix.elements[ 13 ] ) ); 932 933 _sprite.material = object.material; 934 935 _renderData.elements.push( _sprite ); 936 937 } 938 939 } 940 941 // Pools 942 943 function getNextObjectInPool() { 944 945 if ( _objectCount === _objectPoolLength ) { 946 947 var object = new THREEW.RenderableObject(); 948 _objectPool.push( object ); 949 _objectPoolLength ++; 950 _objectCount ++; 951 return object; 952 953 } 954 955 return _objectPool[ _objectCount ++ ]; 956 957 } 958 959 function getNextVertexInPool() { 960 961 if ( _vertexCount === _vertexPoolLength ) { 962 963 var vertex = new THREEW.RenderableVertex(); 964 _vertexPool.push( vertex ); 965 _vertexPoolLength ++; 966 _vertexCount ++; 967 return vertex; 968 969 } 970 971 return _vertexPool[ _vertexCount ++ ]; 972 973 } 974 975 function getNextFaceInPool() { 976 977 if ( _faceCount === _facePoolLength ) { 978 979 var face = new THREEW.RenderableFace(); 980 _facePool.push( face ); 981 _facePoolLength ++; 982 _faceCount ++; 983 return face; 984 985 } 986 987 return _facePool[ _faceCount ++ ]; 988 989 990 } 991 992 function getNextLineInPool() { 993 994 if ( _lineCount === _linePoolLength ) { 995 996 var line = new THREEW.RenderableLine(); 997 _linePool.push( line ); 998 _linePoolLength ++; 999 _lineCount ++; 1000 return line; 1001 1002 } 1003 1004 return _linePool[ _lineCount ++ ]; 1005 1006 } 1007 1008 function getNextSpriteInPool() { 1009 1010 if ( _spriteCount === _spritePoolLength ) { 1011 1012 var sprite = new THREEW.RenderableSprite(); 1013 _spritePool.push( sprite ); 1014 _spritePoolLength ++; 1015 _spriteCount ++; 1016 return sprite; 1017 1018 } 1019 1020 return _spritePool[ _spriteCount ++ ]; 1021 1022 } 1023 1024 // 1025 1026 function painterSort( a, b ) { 1027 1028 if ( a.renderOrder !== b.renderOrder ) { 1029 1030 return a.renderOrder - b.renderOrder; 1031 1032 } else if ( a.z !== b.z ) { 1033 1034 return b.z - a.z; 1035 1036 } else if ( a.id !== b.id ) { 1037 1038 return a.id - b.id; 1039 1040 } else { 1041 1042 return 0; 1043 1044 } 1045 1046 } 1047 1048 function clipLine( s1, s2 ) { 1049 1050 var alpha1 = 0, alpha2 = 1, 1051 1052 // Calculate the boundary coordinate of each vertex for the near and far clip planes, 1053 // Z = -1 and Z = +1, respectively. 1054 1055 bc1near = s1.z + s1.w, 1056 bc2near = s2.z + s2.w, 1057 bc1far = - s1.z + s1.w, 1058 bc2far = - s2.z + s2.w; 1059 1060 if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) { 1061 1062 // Both vertices lie entirely within all clip planes. 1063 return true; 1064 1065 } else if ( ( bc1near < 0 && bc2near < 0 ) || ( bc1far < 0 && bc2far < 0 ) ) { 1066
1067 // Both vertices lie entirely outside one of the clip planes. 1068 return false; 1069 1070 } else { 1071 1072 // The line segment spans at least one clip plane. 1073 1074 if ( bc1near < 0 ) { 1075 1076 // v1 lies outside the near plane, v2 inside 1077 alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) ); 1078 1079 } else if ( bc2near < 0 ) { 1080 1081 // v2 lies outside the near plane, v1 inside 1082 alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) ); 1083 1084 } 1085 1086 if ( bc1far < 0 ) { 1087 1088 // v1 lies outside the far plane, v2 inside 1089 alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) ); 1090 1091 } else if ( bc2far < 0 ) { 1092 1093 // v2 lies outside the far plane, v2 inside 1094 alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) ); 1095 1096 } 1097 1098 if ( alpha2 < alpha1 ) { 1099 1100 // The line segment spans two boundaries, but is outside both of them. 1101 // (This can't happen when we're only clipping against just near/far but good 1102 // to leave the check here for future usage if other clip planes are added.) 1103 return false; 1104 1105 } else { 1106 1107 // Update the s1 and s2 vertices to match the clipped line segment. 1108 s1.lerp( s2, alpha1 ); 1109 s2.lerp( s1, 1 - alpha2 ); 1110 1111 return true; 1112 1113 } 1114 1115 } 1116 1117 } 1118 1119};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.