|
@@ -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 );
|
|
|
|