2
0
Эх сурвалжийг харах

added raycasting of pointclouds with BufferGeometry

added optional parameter intersectPoint to Ray.distanceToPoint()

fixed Ray.distanceToPoint()
mschuetz 11 жил өмнө
parent
commit
6d68ecf181
2 өөрчлөгдсөн 155 нэмэгдсэн , 21 устгасан
  1. 145 15
      src/core/Raycaster.js
  2. 10 6
      src/math/Ray.js

+ 145 - 15
src/core/Raycaster.js

@@ -14,6 +14,12 @@
 		this.near = near || 0;
 		this.far = far || Infinity;
 
+		this.params = {};
+		this.params.Sprite = {};
+		this.params.Mesh = {};
+		this.params.PointCloud = {threshold: 1};
+		this.params.LOD = {};
+		this.params.Line = {};
 	};
 
 	var sphere = new THREE.Sphere();
@@ -59,30 +65,154 @@
 
 
 		} else if ( object instanceof THREE.PointCloud ) {
+		
+			var geometry = object.geometry;
+			var threshold = raycaster.params.PointCloud.threshold;
 
-			var vertices = object.geometry.vertices;
-
-			for ( var i = 0; i < vertices.length; i ++ ) {
-
-				var v = vertices[ i ];
-
-				matrixPosition.copy( v ).applyMatrix4( object.matrixWorld );
+			inverseMatrix.getInverse( object.matrixWorld );  
+			localRay.copy( raycaster.ray ).applyMatrix4( inverseMatrix );
+			
+			if ( geometry.boundingBox !== null ) {
+			
+				if ( localRay.isIntersectionBox( geometry.boundingBox ) === false )  {
+				
+					return intersects;
+					
+				}
+				
+			}
+			
+			var pos = new THREE.Vector3();
+			var intersectPoint = new THREE.Vector3();
 
-				var distance = raycaster.ray.distanceToPoint( matrixPosition );
+			if ( geometry instanceof THREE.BufferGeometry ) {
+			
+				var attributes = geometry.attributes;
+				var positions = attributes.position.array;
+				
+				if ( attributes.index !== undefined ) {
+				
+					var indices = attributes.index.array;
+					var offsets = geometry.offsets;
+					
+					if ( offsets.length === 0 ) {
 
-				if ( distance < 1 ) { // needs a better test; particle size?
+						var offset = { 
+							start: 0, 
+							count: indices.length, 
+							index: 0
+						};
+						
+						offsets = [ offset ];
 
-					intersects.push( {
+					}
+					
+					for ( var oi = 0, ol = offsets.length; oi < ol; ++oi ) {
 
-						distance: distance,
-						index: i,
-						face: null,
-						object: object
+						var start = offsets[ oi ].start;
+						var count = offsets[ oi ].count;
+						var index = offsets[ oi ].index;
 
-					} );
+						for ( var i = start, il = start + count; i < il; i++ ) {
+						
+							var a = index + indices[ i ];
+						
+							pos.set(
+								positions[ a * 3 ],
+								positions[ a * 3 + 1 ],
+								positions[ a * 3 + 2 ]
+							);
+							
+							var rayPointDistance = localRay.distanceToPoint( pos, intersectPoint );
+							
+							if ( rayPointDistance < threshold ) {
+							
+								intersectPoint.applyMatrix4( object.matrixWorld );
+								var distance = raycaster.ray.origin.distanceTo( intersectPoint );
+							
+								intersects.push( {
+							
+									distance: distance,
+									distanceToRay: rayPointDistance,
+									point: intersectPoint.clone(),
+									index: a,
+									face: null,
+									object: object
+									
+								} );
+							
+							}
+						
+						}
+						
+					}
+				
+				}else{
+				
+					var pointCount = positions.length / 3;
+
+					for (var i = 0; i < pointCount; i++ ) {
+					
+						pos.set(
+							positions[ 3 * i ], 
+							positions[ 3 * i + 1 ], 
+							positions[ 3 * i + 2 ]
+						);
+						
+						var rayPointDistance = localRay.distanceToPoint( pos, intersectPoint );
 
+						if ( rayPointDistance < threshold ) {
+						
+							intersectPoint.applyMatrix4( object.matrixWorld );
+							var distance = raycaster.ray.origin.distanceTo( intersectPoint );
+							
+							intersects.push( {
+							
+								distance: distance,
+								distanceToRay: rayPointDistance,
+								point: intersectPoint.clone(),
+								index: i,
+								face: null,
+								object: object
+								
+							} );
+							
+						}
+						
+					}
+					
 				}
+				
+			} else {
+			
+				var vertices = object.geometry.vertices;
+
+				for ( var i = 0; i < vertices.length; i ++ ) {
+
+					var v = vertices[ i ];
+					
+					var rayPointDistance = localRay.distanceToPoint( v, intersectPoint );
+					
+					if ( rayPointDistance < threshold ) {
+					
+						intersectPoint.applyMatrix4( object.matrixWorld );
+						var distance = raycaster.ray.origin.distanceTo( intersectPoint );
+						
+						intersects.push( {
+						
+							distance: distance,
+							distanceToRay: rayPointDistance,
+							point: intersectPoint.clone(),
+							index: i,
+							face: null,
+							object: object
+							
+						} );
+						
+					}
 
+				}
+				
 			}
 
 		} else if ( object instanceof THREE.LOD ) {

+ 10 - 6
src/math/Ray.js

@@ -73,21 +73,25 @@ THREE.Ray.prototype = {
 
 		var v1 = new THREE.Vector3();
 
-		return function ( point ) {
+		return function ( point, optionalIntersectionPoint ) {
+		
+			var v = ( optionalIntersectionPoint !== undefined ) ? optionalIntersectionPoint : v1;
 
-			var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );
+			var directionDistance = v.subVectors( point, this.origin ).dot( this.direction );
 
 			// point behind the ray
 
 			if ( directionDistance < 0 ) {
 
-				return this.origin.distanceTo( point );
+				v.copy( this.origin );
 
+			} else {
+			
+				v.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
+			
 			}
 
-			v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
-
-			return v1.distanceTo( point );
+			return v.distanceTo( point );
 
 		};