Line.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. THREE.Line = function ( geometry, material, mode ) {
  5. THREE.Object3D.call( this );
  6. this.type = 'Line';
  7. this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();
  8. this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
  9. this.mode = ( mode !== undefined ) ? mode : THREE.LineStrip;
  10. };
  11. THREE.LineStrip = 0;
  12. THREE.LinePieces = 1;
  13. THREE.Line.prototype = Object.create( THREE.Object3D.prototype );
  14. THREE.Line.prototype.constructor = THREE.Line;
  15. THREE.Line.prototype.raycast = ( function () {
  16. var inverseMatrix = new THREE.Matrix4();
  17. var ray = new THREE.Ray();
  18. var sphere = new THREE.Sphere();
  19. return function ( raycaster, intersects ) {
  20. var precision = raycaster.linePrecision;
  21. var precisionSq = precision * precision;
  22. var geometry = this.geometry;
  23. if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
  24. // Checking boundingSphere distance to ray
  25. sphere.copy( geometry.boundingSphere );
  26. sphere.applyMatrix4( this.matrixWorld );
  27. if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
  28. return;
  29. }
  30. inverseMatrix.getInverse( this.matrixWorld );
  31. ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
  32. var vStart = new THREE.Vector3();
  33. var vEnd = new THREE.Vector3();
  34. var interSegment = new THREE.Vector3();
  35. var interRay = new THREE.Vector3();
  36. var step = this.mode === THREE.LineStrip ? 1 : 2;
  37. if ( geometry instanceof THREE.BufferGeometry ) {
  38. var attributes = geometry.attributes;
  39. if ( attributes.index !== undefined ) {
  40. var indices = attributes.index.array;
  41. var positions = attributes.position.array;
  42. var offsets = geometry.offsets;
  43. if ( offsets.length === 0 ) {
  44. offsets = [ { start: 0, count: indices.length, index: 0 } ];
  45. }
  46. for ( var oi = 0; oi < offsets.length; oi++){
  47. var start = offsets[ oi ].start;
  48. var count = offsets[ oi ].count;
  49. var index = offsets[ oi ].index;
  50. for ( var i = start; i < start + count - 1; i += step ) {
  51. var a = index + indices[ i ];
  52. var b = index + indices[ i + 1 ];
  53. vStart.fromArray( positions, a * 3 );
  54. vEnd.fromArray( positions, b * 3 );
  55. var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
  56. if ( distSq > precisionSq ) continue;
  57. var distance = ray.origin.distanceTo( interRay );
  58. if ( distance < raycaster.near || distance > raycaster.far ) continue;
  59. intersects.push( {
  60. distance: distance,
  61. // What do we want? intersection point on the ray or on the segment??
  62. // point: raycaster.ray.at( distance ),
  63. point: interSegment.clone().applyMatrix4( this.matrixWorld ),
  64. index: i,
  65. offsetIndex: oi,
  66. face: null,
  67. faceIndex: null,
  68. object: this
  69. } );
  70. }
  71. }
  72. } else {
  73. var positions = attributes.position.array;
  74. for ( var i = 0; i < positions.length / 3 - 1; i += step ) {
  75. vStart.fromArray( positions, 3 * i );
  76. vEnd.fromArray( positions, 3 * i + 3 );
  77. var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
  78. if ( distSq > precisionSq ) continue;
  79. var distance = ray.origin.distanceTo( interRay );
  80. if ( distance < raycaster.near || distance > raycaster.far ) continue;
  81. intersects.push( {
  82. distance: distance,
  83. // What do we want? intersection point on the ray or on the segment??
  84. // point: raycaster.ray.at( distance ),
  85. point: interSegment.clone().applyMatrix4( this.matrixWorld ),
  86. index: i,
  87. face: null,
  88. faceIndex: null,
  89. object: this
  90. } );
  91. }
  92. }
  93. } else if ( geometry instanceof THREE.Geometry ) {
  94. var vertices = geometry.vertices;
  95. var nbVertices = vertices.length;
  96. for ( var i = 0; i < nbVertices - 1; i += step ) {
  97. var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
  98. if ( distSq > precisionSq ) continue;
  99. var distance = ray.origin.distanceTo( interRay );
  100. if ( distance < raycaster.near || distance > raycaster.far ) continue;
  101. intersects.push( {
  102. distance: distance,
  103. // What do we want? intersection point on the ray or on the segment??
  104. // point: raycaster.ray.at( distance ),
  105. point: interSegment.clone().applyMatrix4( this.matrixWorld ),
  106. index: i,
  107. face: null,
  108. faceIndex: null,
  109. object: this
  110. } );
  111. }
  112. }
  113. };
  114. }() );
  115. THREE.Line.prototype.clone = function ( object ) {
  116. if ( object === undefined ) object = new THREE.Line( this.geometry, this.material, this.mode );
  117. THREE.Object3D.prototype.clone.call( this, object );
  118. return object;
  119. };