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