Sprite.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /**
  2. * @author mikael emtinger / http://gomo.se/
  3. * @author alteredq / http://alteredqualia.com/
  4. */
  5. import { Vector2 } from '../math/Vector2.js';
  6. import { Vector3 } from '../math/Vector3.js';
  7. import { Matrix4 } from '../math/Matrix4.js';
  8. import { Triangle } from '../math/Triangle.js';
  9. import { Object3D } from '../core/Object3D.js';
  10. import { BufferGeometry } from '../core/BufferGeometry.js';
  11. import { InterleavedBuffer } from '../core/InterleavedBuffer.js';
  12. import { InterleavedBufferAttribute } from '../core/InterleavedBufferAttribute.js';
  13. import { SpriteMaterial } from '../materials/SpriteMaterial.js';
  14. var geometry;
  15. function Sprite( material ) {
  16. Object3D.call( this );
  17. this.type = 'Sprite';
  18. if ( geometry === undefined ) {
  19. geometry = new BufferGeometry();
  20. var float32Array = new Float32Array( [
  21. - 0.5, - 0.5, 0, 0, 0,
  22. 0.5, - 0.5, 0, 1, 0,
  23. 0.5, 0.5, 0, 1, 1,
  24. - 0.5, 0.5, 0, 0, 1
  25. ] );
  26. var interleavedBuffer = new InterleavedBuffer( float32Array, 5 );
  27. geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] );
  28. geometry.addAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) );
  29. geometry.addAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) );
  30. }
  31. this.geometry = geometry;
  32. this.material = ( material !== undefined ) ? material : new SpriteMaterial();
  33. this.center = new Vector2( 0.5, 0.5 );
  34. }
  35. Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
  36. constructor: Sprite,
  37. isSprite: true,
  38. raycast: ( function () {
  39. var intersectPoint = new Vector3();
  40. var worldScale = new Vector3();
  41. var mvPosition = new Vector3();
  42. var alignedPosition = new Vector2();
  43. var rotatedPosition = new Vector2();
  44. var viewWorldMatrix = new Matrix4();
  45. var vA = new Vector3();
  46. var vB = new Vector3();
  47. var vC = new Vector3();
  48. var uvA = new Vector2();
  49. var uvB = new Vector2();
  50. var uvC = new Vector2();
  51. function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
  52. // compute position in camera space
  53. alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );
  54. // to check if rotation is not zero
  55. if ( sin !== undefined ) {
  56. rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y );
  57. rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y );
  58. } else {
  59. rotatedPosition.copy( alignedPosition );
  60. }
  61. vertexPosition.copy( mvPosition );
  62. vertexPosition.x += rotatedPosition.x;
  63. vertexPosition.y += rotatedPosition.y;
  64. // transform to world space
  65. vertexPosition.applyMatrix4( viewWorldMatrix );
  66. }
  67. return function raycast( raycaster, intersects ) {
  68. worldScale.setFromMatrixScale( this.matrixWorld );
  69. viewWorldMatrix.getInverse( this.modelViewMatrix ).premultiply( this.matrixWorld );
  70. mvPosition.setFromMatrixPosition( this.modelViewMatrix );
  71. var rotation = this.material.rotation;
  72. var sin, cos;
  73. if ( rotation !== 0 ) {
  74. cos = Math.cos( rotation );
  75. sin = Math.sin( rotation );
  76. }
  77. var center = this.center;
  78. transformVertex( vA.set( - 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
  79. transformVertex( vB.set( 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
  80. transformVertex( vC.set( 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
  81. uvA.set( 0, 0 );
  82. uvB.set( 1, 0 );
  83. uvC.set( 1, 1 );
  84. // check first triangle
  85. var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint );
  86. if ( intersect === null ) {
  87. // check second triangle
  88. transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
  89. uvB.set( 0, 1 );
  90. intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint );
  91. if ( intersect === null ) {
  92. return;
  93. }
  94. }
  95. var distance = raycaster.ray.origin.distanceTo( intersectPoint );
  96. if ( distance < raycaster.near || distance > raycaster.far ) return;
  97. intersects.push( {
  98. distance: distance,
  99. point: intersectPoint.clone(),
  100. uv: Triangle.getUV( intersectPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() ),
  101. face: null,
  102. object: this
  103. } );
  104. };
  105. }() ),
  106. clone: function () {
  107. return new this.constructor( this.material ).copy( this );
  108. },
  109. copy: function ( source ) {
  110. Object3D.prototype.copy.call( this, source );
  111. if ( source.center !== undefined ) this.center.copy( source.center );
  112. return this;
  113. }
  114. } );
  115. export { Sprite };
粤ICP备19079148号