UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

173 lines (151 loc) 5.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ShapeGeometry = void 0; var _BufferGeometry = require("../core/BufferGeometry.js"); var _BufferAttribute = require("../core/BufferAttribute.js"); var _Shape = require("../extras/core/Shape.js"); var _ShapeUtils = require("../extras/ShapeUtils.js"); var _Vector = require("../math/Vector2.js"); /** * Creates an one-sided polygonal geometry from one or more path shapes. * * ```js * const arcShape = new THREE.Shape() * .moveTo( 5, 1 ) * .absarc( 1, 1, 4, 0, Math.PI * 2, false ); * * const geometry = new THREE.ShapeGeometry( arcShape ); * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00, side: THREE.DoubleSide } ); * const mesh = new THREE.Mesh( geometry, material ) ; * scene.add( mesh ); * ``` * * @augments BufferGeometry */ class ShapeGeometry extends _BufferGeometry.BufferGeometry { /** * Constructs a new shape geometry. * * @param {Shape|Array<Shape>} [shapes] - A shape or an array of shapes. * @param {number} [curveSegments=12] - Number of segments per shape. */ constructor(shapes = new _Shape.Shape([new _Vector.Vector2(0, 0.5), new _Vector.Vector2(-0.5, -0.5), new _Vector.Vector2(0.5, -0.5)]), curveSegments = 12) { super(); this.type = 'ShapeGeometry'; /** * Holds the constructor parameters that have been * used to generate the geometry. Any modification * after instantiation does not change the geometry. * * @type {Object} */ this.parameters = { shapes: shapes, curveSegments: curveSegments }; // buffers const indices = []; const vertices = []; const normals = []; const uvs = []; // helper variables let groupStart = 0; let groupCount = 0; // allow single and array values for "shapes" parameter if (Array.isArray(shapes) === false) { addShape(shapes); } else { for (let i = 0; i < shapes.length; i++) { addShape(shapes[i]); this.addGroup(groupStart, groupCount, i); // enables MultiMaterial support groupStart += groupCount; groupCount = 0; } } // build geometry this.setIndex(indices); this.setAttribute('position', new _BufferAttribute.Float32BufferAttribute(vertices, 3)); this.setAttribute('normal', new _BufferAttribute.Float32BufferAttribute(normals, 3)); this.setAttribute('uv', new _BufferAttribute.Float32BufferAttribute(uvs, 2)); // helper functions function addShape(shape) { const indexOffset = vertices.length / 3; const points = shape.extractPoints(curveSegments); let shapeVertices = points.shape; const shapeHoles = points.holes; // check direction of vertices if (_ShapeUtils.ShapeUtils.isClockWise(shapeVertices) === false) { shapeVertices = shapeVertices.reverse(); } for (let i = 0, l = shapeHoles.length; i < l; i++) { const shapeHole = shapeHoles[i]; if (_ShapeUtils.ShapeUtils.isClockWise(shapeHole) === true) { shapeHoles[i] = shapeHole.reverse(); } } const faces = _ShapeUtils.ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array for (let i = 0, l = shapeHoles.length; i < l; i++) { const shapeHole = shapeHoles[i]; shapeVertices = shapeVertices.concat(shapeHole); } // vertices, normals, uvs for (let i = 0, l = shapeVertices.length; i < l; i++) { const vertex = shapeVertices[i]; vertices.push(vertex.x, vertex.y, 0); normals.push(0, 0, 1); uvs.push(vertex.x, vertex.y); // world uvs } // indices for (let i = 0, l = faces.length; i < l; i++) { const face = faces[i]; const a = face[0] + indexOffset; const b = face[1] + indexOffset; const c = face[2] + indexOffset; indices.push(a, b, c); groupCount += 3; } } } copy(source) { super.copy(source); this.parameters = Object.assign({}, source.parameters); return this; } toJSON() { const data = super.toJSON(); const shapes = this.parameters.shapes; return toJSON(shapes, data); } /** * Factory method for creating an instance of this class from the given * JSON object. * * @param {Object} data - A JSON object representing the serialized geometry. * @param {Array<Shape>} shapes - An array of shapes. * @return {ShapeGeometry} A new instance. */ static fromJSON(data, shapes) { const geometryShapes = []; for (let j = 0, jl = data.shapes.length; j < jl; j++) { const shape = shapes[data.shapes[j]]; geometryShapes.push(shape); } return new ShapeGeometry(geometryShapes, data.curveSegments); } } exports.ShapeGeometry = ShapeGeometry; function toJSON(shapes, data) { data.shapes = []; if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; data.shapes.push(shape.uuid); } } else { data.shapes.push(shapes.uuid); } return data; }