Line.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. THREE.Line = function ( geometry, material, mode ) {
  5. if ( mode === 1 ) {
  6. console.error( 'THREE.Line: THREE.LinePieces mode has been removed. Use THREE.LineSegments instead.' );
  7. }
  8. THREE.Object3D.call( this );
  9. this.type = 'Line';
  10. this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();
  11. this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
  12. };
  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 raycast ( 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 instanceof THREE.LineSegments ? 2 : 1;
  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.drawcalls;
  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[ this.type ]( this.geometry, this.material );
  117. THREE.Object3D.prototype.clone.call( this, object );
  118. return object;
  119. };
  120. THREE.Line.prototype.toJSON = function ( meta ) {
  121. var data = THREE.Object3D.prototype.toJSON.call( this, meta );
  122. // only serialize if not in meta geometries cache
  123. if ( meta.geometries[ this.geometry.uuid ] === undefined ) {
  124. meta.geometries[ this.geometry.uuid ] = this.geometry.toJSON();
  125. }
  126. // only serialize if not in meta materials cache
  127. if ( meta.materials[ this.material.uuid ] === undefined ) {
  128. meta.materials[ this.material.uuid ] = this.material.toJSON();
  129. }
  130. data.object.geometry = this.geometry.uuid;
  131. data.object.material = this.material.uuid;
  132. return data;
  133. };
  134. // DEPRECATED
  135. THREE.LineStrip = 0;
  136. THREE.LinePieces = 1;