193 lines
4.6 KiB
JavaScript
193 lines
4.6 KiB
JavaScript
/**
|
|
* @author mrdoob / http://mrdoob.com/
|
|
*/
|
|
|
|
THREE.Line = function ( geometry, material, mode ) {
|
|
|
|
THREE.Object3D.call( this );
|
|
|
|
this.type = 'Line';
|
|
|
|
this.geometry = geometry !== undefined ? geometry : new THREE.Geometry();
|
|
this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
|
|
|
|
this.mode = mode !== undefined ? mode : THREE.LineStrip;
|
|
|
|
};
|
|
|
|
THREE.LineStrip = 0;
|
|
THREE.LinePieces = 1;
|
|
|
|
THREE.Line.prototype = Object.create( THREE.Object3D.prototype );
|
|
THREE.Line.prototype.constructor = THREE.Line;
|
|
|
|
THREE.Line.prototype.raycast = ( function () {
|
|
|
|
var inverseMatrix = new THREE.Matrix4();
|
|
var ray = new THREE.Ray();
|
|
var sphere = new THREE.Sphere();
|
|
|
|
return function ( raycaster, intersects ) {
|
|
|
|
var precision = raycaster.linePrecision;
|
|
var precisionSq = precision * precision;
|
|
|
|
var geometry = this.geometry;
|
|
|
|
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
|
|
|
|
// Checking boundingSphere distance to ray
|
|
|
|
sphere.copy( geometry.boundingSphere );
|
|
sphere.applyMatrix4( this.matrixWorld );
|
|
|
|
if ( raycaster.ray.isIntersectionSphere( sphere ) === false ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
inverseMatrix.getInverse( this.matrixWorld );
|
|
ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
|
|
|
|
var vStart = new THREE.Vector3();
|
|
var vEnd = new THREE.Vector3();
|
|
var interSegment = new THREE.Vector3();
|
|
var interRay = new THREE.Vector3();
|
|
var step = this.mode === THREE.LineStrip ? 1 : 2;
|
|
|
|
if ( geometry instanceof THREE.BufferGeometry ) {
|
|
|
|
var attributes = geometry.attributes;
|
|
|
|
if ( attributes.index !== undefined ) {
|
|
|
|
var indices = attributes.index.array;
|
|
var positions = attributes.position.array;
|
|
var offsets = geometry.offsets;
|
|
|
|
if ( offsets.length === 0 ) {
|
|
|
|
offsets = [ { start: 0, count: indices.length, index: 0 } ];
|
|
|
|
}
|
|
|
|
for ( var oi = 0; oi < offsets.length; oi ++) {
|
|
|
|
var start = offsets[ oi ].start;
|
|
var count = offsets[ oi ].count;
|
|
var index = offsets[ oi ].index;
|
|
|
|
for ( var i = start; i < start + count - 1; i += step ) {
|
|
|
|
var a = index + indices[ i ];
|
|
var b = index + indices[ i + 1 ];
|
|
|
|
vStart.fromArray( positions, a * 3 );
|
|
vEnd.fromArray( positions, b * 3 );
|
|
|
|
var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
|
|
|
|
if ( distSq > precisionSq ) continue;
|
|
|
|
var distance = ray.origin.distanceTo( interRay );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) continue;
|
|
|
|
intersects.push( {
|
|
|
|
distance: distance,
|
|
// What do we want? intersection point on the ray or on the segment??
|
|
// point: raycaster.ray.at( distance ),
|
|
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
|
|
index: i,
|
|
offsetIndex: oi,
|
|
face: null,
|
|
faceIndex: null,
|
|
object: this
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var positions = attributes.position.array;
|
|
|
|
for ( var i = 0; i < positions.length / 3 - 1; i += step ) {
|
|
|
|
vStart.fromArray( positions, 3 * i );
|
|
vEnd.fromArray( positions, 3 * i + 3 );
|
|
|
|
var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
|
|
|
|
if ( distSq > precisionSq ) continue;
|
|
|
|
var distance = ray.origin.distanceTo( interRay );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) continue;
|
|
|
|
intersects.push( {
|
|
|
|
distance: distance,
|
|
// What do we want? intersection point on the ray or on the segment??
|
|
// point: raycaster.ray.at( distance ),
|
|
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
|
|
index: i,
|
|
face: null,
|
|
faceIndex: null,
|
|
object: this
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( geometry instanceof THREE.Geometry ) {
|
|
|
|
var vertices = geometry.vertices;
|
|
var nbVertices = vertices.length;
|
|
|
|
for ( var i = 0; i < nbVertices - 1; i += step ) {
|
|
|
|
var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
|
|
|
|
if ( distSq > precisionSq ) continue;
|
|
|
|
var distance = ray.origin.distanceTo( interRay );
|
|
|
|
if ( distance < raycaster.near || distance > raycaster.far ) continue;
|
|
|
|
intersects.push( {
|
|
|
|
distance: distance,
|
|
// What do we want? intersection point on the ray or on the segment??
|
|
// point: raycaster.ray.at( distance ),
|
|
point: interSegment.clone().applyMatrix4( this.matrixWorld ),
|
|
index: i,
|
|
face: null,
|
|
faceIndex: null,
|
|
object: this
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}() );
|
|
|
|
THREE.Line.prototype.clone = function ( object ) {
|
|
|
|
if ( object === undefined ) object = new THREE.Line( this.geometry, this.material, this.mode );
|
|
|
|
THREE.Object3D.prototype.clone.call( this, object );
|
|
|
|
return object;
|
|
|
|
};
|