Преглед изворни кода

sprite.raycast use ray.intersectTriangle to check

06wj пре 7 година
родитељ
комит
42fa96828e
1 измењених фајлова са 49 додато и 15 уклоњено
  1. 49 15
      src/objects/Sprite.js

+ 49 - 15
src/objects/Sprite.js

@@ -30,24 +30,24 @@ Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
 	raycast: ( function () {
 
 		var intersectPoint = new Vector3();
-		var worldPosition = new Vector3();
 		var worldScale = new Vector3();
+		var mvPosition = new Vector3();
 
 		var alignedPosition = new Vector2();
 		var rotatedPosition = new Vector2();
-		var modelViewInverseMatrix = new Matrix4();
+		var viewWorldMatrix = new Matrix4();
 
-		return function raycast( raycaster, intersects ) {
+		var vA = new Vector3();
+		var vB = new Vector3();
+		var vC = new Vector3();
 
-			worldScale.setFromMatrixScale( this.matrixWorld );
+		function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
 
 			// compute position in camera space
-			alignedPosition.set( ( 0.5 - this.center.x ) * worldScale.x, ( 0.5 - this.center.y ) * worldScale.y );
+			alignedPosition.set( ( vertexPosition.x - center.x ) * scale.x, ( vertexPosition.y - center.y ) * scale.y );
 
-			var rotation = this.material.rotation;
-			if ( rotation !== 0 ) {
+			if ( sin !== undefined ) {
 
-				var cos = Math.cos( rotation ), sin = Math.sin( rotation );
 				rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y );
 				rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y );
 
@@ -57,18 +57,52 @@ Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 			}
 
-			worldPosition.setFromMatrixPosition( this.modelViewMatrix );
-			worldPosition.x += rotatedPosition.x;
-			worldPosition.y += rotatedPosition.y;
+
+			vertexPosition.copy( mvPosition );
+			vertexPosition.x += rotatedPosition.x;
+			vertexPosition.y += rotatedPosition.y;
 
 			// transform to world space
-			worldPosition.applyMatrix4( modelViewInverseMatrix.getInverse( this.modelViewMatrix ) ).applyMatrix4( this.matrixWorld );
+			vertexPosition.applyMatrix4( viewWorldMatrix );
+
+		}
+
+		return function raycast( raycaster, intersects ) {
+
+			worldScale.setFromMatrixScale( this.matrixWorld );
+			viewWorldMatrix.getInverse( this.modelViewMatrix ).premultiply( this.matrixWorld );
+			mvPosition.setFromMatrixPosition( this.modelViewMatrix );
+
+			var rotation = this.material.rotation;
+			var sin, cos;
+			if ( rotation !== 0 ) {
+
+				cos = Math.cos( rotation );
+				sin = Math.sin( rotation );
+
+			}
+
+			var center = this.center;
 
-			raycaster.ray.closestPointToPoint( worldPosition, intersectPoint );
+			transformVertex( vA.set( 0, 0, 1 ), mvPosition, center, worldScale, sin, cos );
+			transformVertex( vB.set( 0, 1, 1 ), mvPosition, center, worldScale, sin, cos );
+			transformVertex( vC.set( 1, 0, 1 ), mvPosition, center, worldScale, sin, cos );
 
-			var guessSizeSq = worldScale.x * worldScale.y / 4;
+			// check first triangle
+			var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint );
 
-			if ( worldPosition.distanceToSquared( intersectPoint ) > guessSizeSq ) return;
+			if ( intersect === null ) {
+
+				// check second triangle
+				transformVertex( vA.set( 1, 1, 1 ), mvPosition, center, worldScale, sin, cos );
+				intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint );
+				if ( intersect === null ) {
+
+					return;
+
+				}
+
+			}
 
 			var distance = raycaster.ray.origin.distanceTo( intersectPoint );