|
@@ -1,5 +1,6 @@
|
|
|
import { Vector2 } from '../math/Vector2.js';
|
|
|
import { Vector3 } from '../math/Vector3.js';
|
|
|
+import { Matrix4 } from '../math/Matrix4.js';
|
|
|
import { Object3D } from '../core/Object3D.js';
|
|
|
import { SpriteMaterial } from '../materials/SpriteMaterial.js';
|
|
|
|
|
@@ -29,18 +30,80 @@ 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();
|
|
|
|
|
|
- return function raycast( raycaster, intersects ) {
|
|
|
+ var alignedPosition = new Vector2();
|
|
|
+ var rotatedPosition = new Vector2();
|
|
|
+ var viewWorldMatrix = new Matrix4();
|
|
|
+
|
|
|
+ var vA = new Vector3();
|
|
|
+ var vB = new Vector3();
|
|
|
+ var vC = new Vector3();
|
|
|
+
|
|
|
+ function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
|
|
|
+
|
|
|
+ // compute position in camera space
|
|
|
+ alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );
|
|
|
+
|
|
|
+ // to check if rotation is not zero
|
|
|
+ if ( sin !== undefined ) {
|
|
|
+
|
|
|
+ rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y );
|
|
|
+ rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ rotatedPosition.copy( alignedPosition );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ vertexPosition.copy( mvPosition );
|
|
|
+ vertexPosition.x += rotatedPosition.x;
|
|
|
+ vertexPosition.y += rotatedPosition.y;
|
|
|
+
|
|
|
+ // transform to world space
|
|
|
+ vertexPosition.applyMatrix4( viewWorldMatrix );
|
|
|
|
|
|
- worldPosition.setFromMatrixPosition( this.matrixWorld );
|
|
|
- raycaster.ray.closestPointToPoint( worldPosition, intersectPoint );
|
|
|
+ }
|
|
|
+
|
|
|
+ return function raycast( raycaster, intersects ) {
|
|
|
|
|
|
worldScale.setFromMatrixScale( this.matrixWorld );
|
|
|
- var guessSizeSq = worldScale.x * worldScale.y / 4;
|
|
|
+ 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;
|
|
|
+
|
|
|
+ transformVertex( vA.set( - 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
|
|
|
+ transformVertex( vB.set( 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
|
|
|
+ transformVertex( vC.set( 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
|
|
|
+
|
|
|
+ // check first triangle
|
|
|
+ var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint );
|
|
|
+
|
|
|
+ if ( intersect === null ) {
|
|
|
+
|
|
|
+ // check second triangle
|
|
|
+ transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
|
|
|
+ intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint );
|
|
|
+ if ( intersect === null ) {
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- if ( worldPosition.distanceToSquared( intersectPoint ) > guessSizeSq ) return;
|
|
|
+ }
|
|
|
|
|
|
var distance = raycaster.ray.origin.distanceTo( intersectPoint );
|
|
|
|