Browse Source

added raycasting to lines with buffered geometry

mschuetz 10 years ago
parent
commit
37db3e5a35
1 changed files with 94 additions and 6 deletions
  1. 94 6
      src/objects/Line.js

+ 94 - 6
src/objects/Line.js

@@ -49,16 +49,104 @@ THREE.Line.prototype.raycast = ( function () {
 
 
 		inverseMatrix.getInverse( this.matrixWorld );
 		inverseMatrix.getInverse( this.matrixWorld );
 		ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
 		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 ),
+							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 ),
+						face: null,
+						faceIndex: null,
+						object: this
+
+					} );
+				
+				}
+				
+			}
 
 
-		/* if ( geometry instanceof THREE.BufferGeometry ) {
-
-		} else */ if ( geometry instanceof THREE.Geometry ) {
+		} else if ( geometry instanceof THREE.Geometry ) {
 
 
 			var vertices = geometry.vertices;
 			var vertices = geometry.vertices;
 			var nbVertices = vertices.length;
 			var nbVertices = vertices.length;
-			var interSegment = new THREE.Vector3();
-			var interRay = new THREE.Vector3();
-			var step = this.mode === THREE.LineStrip ? 1 : 2;
 
 
 			for ( var i = 0; i < nbVertices - 1; i = i + step ) {
 			for ( var i = 0; i < nbVertices - 1; i = i + step ) {