@openhps/core
Version:
Open Hybrid Positioning System - Core component
176 lines (166 loc) • 6.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Sprite = void 0;
var _Vector = require("../math/Vector2.js");
var _Vector2 = require("../math/Vector3.js");
var _Matrix = require("../math/Matrix4.js");
var _Triangle = require("../math/Triangle.js");
var _Object3D = require("../core/Object3D.js");
var _BufferGeometry = require("../core/BufferGeometry.js");
var _InterleavedBuffer = require("../core/InterleavedBuffer.js");
var _InterleavedBufferAttribute = require("../core/InterleavedBufferAttribute.js");
var _SpriteMaterial = require("../materials/SpriteMaterial.js");
let _geometry;
const _intersectPoint = /*@__PURE__*/new _Vector2.Vector3();
const _worldScale = /*@__PURE__*/new _Vector2.Vector3();
const _mvPosition = /*@__PURE__*/new _Vector2.Vector3();
const _alignedPosition = /*@__PURE__*/new _Vector.Vector2();
const _rotatedPosition = /*@__PURE__*/new _Vector.Vector2();
const _viewWorldMatrix = /*@__PURE__*/new _Matrix.Matrix4();
const _vA = /*@__PURE__*/new _Vector2.Vector3();
const _vB = /*@__PURE__*/new _Vector2.Vector3();
const _vC = /*@__PURE__*/new _Vector2.Vector3();
const _uvA = /*@__PURE__*/new _Vector.Vector2();
const _uvB = /*@__PURE__*/new _Vector.Vector2();
const _uvC = /*@__PURE__*/new _Vector.Vector2();
/**
* A sprite is a plane that always faces towards the camera, generally with a
* partially transparent texture applied.
*
* Sprites do not cast shadows, setting {@link Object3D#castShadow} to `true` will
* have no effect.
*
* ```js
* const map = new THREE.TextureLoader().load( 'sprite.png' );
* const material = new THREE.SpriteMaterial( { map: map } );
*
* const sprite = new THREE.Sprite( material );
* scene.add( sprite );
* ```
*
* @augments Object3D
*/
class Sprite extends _Object3D.Object3D {
/**
* Constructs a new sprite.
*
* @param {SpriteMaterial} [material] - The sprite material.
*/
constructor(material = new _SpriteMaterial.SpriteMaterial()) {
super();
/**
* This flag can be used for type testing.
*
* @type {boolean}
* @readonly
* @default true
*/
this.isSprite = true;
this.type = 'Sprite';
if (_geometry === undefined) {
_geometry = new _BufferGeometry.BufferGeometry();
const 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]);
const interleavedBuffer = new _InterleavedBuffer.InterleavedBuffer(float32Array, 5);
_geometry.setIndex([0, 1, 2, 0, 2, 3]);
_geometry.setAttribute('position', new _InterleavedBufferAttribute.InterleavedBufferAttribute(interleavedBuffer, 3, 0, false));
_geometry.setAttribute('uv', new _InterleavedBufferAttribute.InterleavedBufferAttribute(interleavedBuffer, 2, 3, false));
}
/**
* The sprite geometry.
*
* @type {BufferGeometry}
*/
this.geometry = _geometry;
/**
* The sprite material.
*
* @type {SpriteMaterial}
*/
this.material = material;
/**
* The sprite's anchor point, and the point around which the sprite rotates.
* A value of `(0.5, 0.5)` corresponds to the midpoint of the sprite. A value
* of `(0, 0)` corresponds to the lower left corner of the sprite.
*
* @type {Vector2}
* @default (0.5,0.5)
*/
this.center = new _Vector.Vector2(0.5, 0.5);
}
/**
* Computes intersection points between a casted ray and this sprite.
*
* @param {Raycaster} raycaster - The raycaster.
* @param {Array<Object>} intersects - The target array that holds the intersection points.
*/
raycast(raycaster, intersects) {
if (raycaster.camera === null) {
console.error('THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.');
}
_worldScale.setFromMatrixScale(this.matrixWorld);
_viewWorldMatrix.copy(raycaster.camera.matrixWorld);
this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld);
_mvPosition.setFromMatrixPosition(this.modelViewMatrix);
if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) {
_worldScale.multiplyScalar(-_mvPosition.z);
}
const rotation = this.material.rotation;
let sin, cos;
if (rotation !== 0) {
cos = Math.cos(rotation);
sin = Math.sin(rotation);
}
const 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);
// check first triangle
let 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);
_uvB.set(0, 1);
intersect = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint);
if (intersect === null) {
return;
}
}
const distance = raycaster.ray.origin.distanceTo(_intersectPoint);
if (distance < raycaster.near || distance > raycaster.far) return;
intersects.push({
distance: distance,
point: _intersectPoint.clone(),
uv: _Triangle.Triangle.getInterpolation(_intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new _Vector.Vector2()),
face: null,
object: this
});
}
copy(source, recursive) {
super.copy(source, recursive);
if (source.center !== undefined) this.center.copy(source.center);
this.material = source.material;
return this;
}
}
exports.Sprite = Sprite;
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);
}