| |
| |
| |
| |
|
|
| import { Vector2 } from '../math/Vector2.js'; |
| import { Vector3 } from '../math/Vector3.js'; |
| import { Matrix4 } from '../math/Matrix4.js'; |
| import { Triangle } from '../math/Triangle.js'; |
| import { Object3D } from '../core/Object3D.js'; |
| import { BufferGeometry } from '../core/BufferGeometry.js'; |
| import { InterleavedBuffer } from '../core/InterleavedBuffer.js'; |
| import { InterleavedBufferAttribute } from '../core/InterleavedBufferAttribute.js'; |
| import { SpriteMaterial } from '../materials/SpriteMaterial.js'; |
|
|
| var geometry; |
|
|
| function Sprite( material ) { |
|
|
| Object3D.call( this ); |
|
|
| this.type = 'Sprite'; |
|
|
| if ( geometry === undefined ) { |
|
|
| geometry = new BufferGeometry(); |
|
|
| var float32Array = new Float32Array( [ |
| - 0.5, - 0.5, 0, 0, 0, |
| 0.5, - 0.5, 0, 1, 0, |
| 0.5, 0.5, 0, 1, 1, |
| - 0.5, 0.5, 0, 0, 1 |
| ] ); |
|
|
| var interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); |
|
|
| geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); |
| geometry.addAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); |
| geometry.addAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); |
|
|
| } |
|
|
| this.geometry = geometry; |
| this.material = ( material !== undefined ) ? material : new SpriteMaterial(); |
|
|
| this.center = new Vector2( 0.5, 0.5 ); |
|
|
| } |
|
|
| Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), { |
|
|
| constructor: Sprite, |
|
|
| isSprite: true, |
|
|
| raycast: ( function () { |
|
|
| var intersectPoint = new Vector3(); |
| var worldScale = new Vector3(); |
| var mvPosition = new Vector3(); |
|
|
| var alignedPosition = new Vector2(); |
| var rotatedPosition = new Vector2(); |
| var viewWorldMatrix = new Matrix4(); |
|
|
| var vA = new Vector3(); |
| var vB = new Vector3(); |
| var vC = new Vector3(); |
|
|
| var uvA = new Vector2(); |
| var uvB = new Vector2(); |
| var uvC = new Vector2(); |
|
|
| function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { |
|
|
| |
| alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); |
|
|
| |
| 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; |
|
|
| |
| 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; |
|
|
| 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 ); |
|
|
| uvA.set( 0, 0 ); |
| uvB.set( 1, 0 ); |
| uvC.set( 1, 1 ); |
|
|
| |
| var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint ); |
|
|
| if ( intersect === null ) { |
|
|
| |
| transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos ); |
| uvB.set( 0, 1 ); |
|
|
| intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint ); |
| if ( intersect === null ) { |
|
|
| return; |
|
|
| } |
|
|
| } |
|
|
| var distance = raycaster.ray.origin.distanceTo( intersectPoint ); |
|
|
| if ( distance < raycaster.near || distance > raycaster.far ) return; |
|
|
| intersects.push( { |
|
|
| distance: distance, |
| point: intersectPoint.clone(), |
| uv: Triangle.getUV( intersectPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() ), |
| face: null, |
| object: this |
|
|
| } ); |
|
|
| }; |
|
|
| }() ), |
|
|
| clone: function () { |
|
|
| return new this.constructor( this.material ).copy( this ); |
|
|
| }, |
|
|
| copy: function ( source ) { |
|
|
| Object3D.prototype.copy.call( this, source ); |
|
|
| if ( source.center !== undefined ) this.center.copy( source.center ); |
|
|
| return this; |
|
|
| } |
|
|
|
|
| } ); |
|
|
| export { Sprite }; |
|
|