@openhps/core
Version:
Open Hybrid Positioning System - Core component
173 lines (151 loc) • 5.17 kB
JavaScript
;
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;
}