UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

164 lines (154 loc) 5.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _NodeMaterial = _interopRequireDefault(require("./NodeMaterial.js")); var _Camera = require("../../nodes/accessors/Camera.js"); var _MaterialNode = require("../../nodes/accessors/MaterialNode.js"); var _ModelNode = require("../../nodes/accessors/ModelNode.js"); var _Position = require("../../nodes/accessors/Position.js"); var _RotateNode = require("../../nodes/utils/RotateNode.js"); var _TSLBase = require("../../nodes/tsl/TSLBase.js"); var _SpriteMaterial = require("../SpriteMaterial.js"); var _ReferenceBaseNode = require("../../nodes/accessors/ReferenceBaseNode.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const _defaultValues = /*@__PURE__*/new _SpriteMaterial.SpriteMaterial(); /** * Node material version of {@link SpriteMaterial}. * * @augments NodeMaterial */ class SpriteNodeMaterial extends _NodeMaterial.default { static get type() { return 'SpriteNodeMaterial'; } /** * Constructs a new sprite node material. * * @param {Object} [parameters] - The configuration parameter. */ constructor(parameters) { super(); /** * This flag can be used for type testing. * * @type {boolean} * @readonly * @default true */ this.isSpriteNodeMaterial = true; this._useSizeAttenuation = true; /** * This property makes it possible to define the position of the sprite with a * node. That can be useful when the material is used with instanced rendering * and node data are defined with an instanced attribute node: * ```js * const positionAttribute = new InstancedBufferAttribute( new Float32Array( positions ), 3 ); * material.positionNode = instancedBufferAttribute( positionAttribute ); * ``` * Another possibility is to compute the instanced data with a compute shader: * ```js * const positionBuffer = instancedArray( particleCount, 'vec3' ); * particleMaterial.positionNode = positionBuffer.toAttribute(); * ``` * * @type {?Node<vec2>} * @default null */ this.positionNode = null; /** * The rotation of sprite materials is by default inferred from the `rotation`, * property. This node property allows to overwrite the default and define * the rotation with a node instead. * * If you don't want to overwrite the rotation but modify the existing * value instead, use {@link materialRotation}. * * @type {?Node<float>} * @default null */ this.rotationNode = null; /** * This node property provides an additional way to scale sprites next to * `Object3D.scale`. The scale transformation based in `Object3D.scale` * is multiplied with the scale value of this node in the vertex shader. * * @type {?Node<vec2>} * @default null */ this.scaleNode = null; /** * In Sprites, the transparent property is enabled by default. * * @type {boolean} * @default true */ this.transparent = true; this.setDefaultValues(_defaultValues); this.setValues(parameters); } /** * Setups the position node in view space. This method implements * the sprite specific vertex shader. * * @param {NodeBuilder} builder - The current node builder. * @return {Node<vec3>} The position in view space. */ setupPositionView(builder) { const { object, camera } = builder; const sizeAttenuation = this.sizeAttenuation; const { positionNode, rotationNode, scaleNode } = this; const mvPosition = _ModelNode.modelViewMatrix.mul((0, _TSLBase.vec3)(positionNode || 0)); let scale = (0, _TSLBase.vec2)(_ModelNode.modelWorldMatrix[0].xyz.length(), _ModelNode.modelWorldMatrix[1].xyz.length()); if (scaleNode !== null) { scale = scale.mul((0, _TSLBase.vec2)(scaleNode)); } if (sizeAttenuation === false) { if (camera.isPerspectiveCamera) { scale = scale.mul(mvPosition.z.negate()); } else { const orthoScale = (0, _TSLBase.float)(2.0).div(_Camera.cameraProjectionMatrix.element(1).element(1)); scale = scale.mul(orthoScale.mul(2)); } } let alignedPosition = _Position.positionGeometry.xy; if (object.center && object.center.isVector2 === true) { const center = (0, _ReferenceBaseNode.reference)('center', 'vec2', object); alignedPosition = alignedPosition.sub(center.sub(0.5)); } alignedPosition = alignedPosition.mul(scale); const rotation = (0, _TSLBase.float)(rotationNode || _MaterialNode.materialRotation); const rotatedPosition = (0, _RotateNode.rotate)(alignedPosition, rotation); return (0, _TSLBase.vec4)(mvPosition.xy.add(rotatedPosition), mvPosition.zw); } copy(source) { this.positionNode = source.positionNode; this.rotationNode = source.rotationNode; this.scaleNode = source.scaleNode; return super.copy(source); } /** * Whether to use size attenuation or not. * * @type {boolean} * @default true */ get sizeAttenuation() { return this._useSizeAttenuation; } set sizeAttenuation(value) { if (this._useSizeAttenuation !== value) { this._useSizeAttenuation = value; this.needsUpdate = true; } } } var _default = exports.default = SpriteNodeMaterial;