@openhps/core
Version:
Open Hybrid Positioning System - Core component
147 lines (140 loc) • 5.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.EdgesGeometry = void 0;
var _BufferGeometry = require("../core/BufferGeometry.js");
var _BufferAttribute = require("../core/BufferAttribute.js");
var _MathUtils = require("../math/MathUtils.js");
var _Triangle = require("../math/Triangle.js");
var _Vector = require("../math/Vector3.js");
const _v0 = /*@__PURE__*/new _Vector.Vector3();
const _v1 = /*@__PURE__*/new _Vector.Vector3();
const _normal = /*@__PURE__*/new _Vector.Vector3();
const _triangle = /*@__PURE__*/new _Triangle.Triangle();
/**
* Can be used as a helper object to view the edges of a geometry.
*
* ```js
* const geometry = new THREE.BoxGeometry();
* const edges = new THREE.EdgesGeometry( geometry );
* const line = new THREE.LineSegments( edges );
* scene.add( line );
* ```
*
* Note: It is not yet possible to serialize/deserialize instances of this class.
*
* @augments BufferGeometry
*/
class EdgesGeometry extends _BufferGeometry.BufferGeometry {
/**
* Constructs a new edges geometry.
*
* @param {?BufferGeometry} [geometry=null] - The geometry.
* @param {number} [thresholdAngle=1] - An edge is only rendered if the angle (in degrees)
* between the face normals of the adjoining faces exceeds this value.
*/
constructor(geometry = null, thresholdAngle = 1) {
super();
this.type = 'EdgesGeometry';
/**
* 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 = {
geometry: geometry,
thresholdAngle: thresholdAngle
};
if (geometry !== null) {
const precisionPoints = 4;
const precision = Math.pow(10, precisionPoints);
const thresholdDot = Math.cos(_MathUtils.DEG2RAD * thresholdAngle);
const indexAttr = geometry.getIndex();
const positionAttr = geometry.getAttribute('position');
const indexCount = indexAttr ? indexAttr.count : positionAttr.count;
const indexArr = [0, 0, 0];
const vertKeys = ['a', 'b', 'c'];
const hashes = new Array(3);
const edgeData = {};
const vertices = [];
for (let i = 0; i < indexCount; i += 3) {
if (indexAttr) {
indexArr[0] = indexAttr.getX(i);
indexArr[1] = indexAttr.getX(i + 1);
indexArr[2] = indexAttr.getX(i + 2);
} else {
indexArr[0] = i;
indexArr[1] = i + 1;
indexArr[2] = i + 2;
}
const {
a,
b,
c
} = _triangle;
a.fromBufferAttribute(positionAttr, indexArr[0]);
b.fromBufferAttribute(positionAttr, indexArr[1]);
c.fromBufferAttribute(positionAttr, indexArr[2]);
_triangle.getNormal(_normal);
// create hashes for the edge from the vertices
hashes[0] = `${Math.round(a.x * precision)},${Math.round(a.y * precision)},${Math.round(a.z * precision)}`;
hashes[1] = `${Math.round(b.x * precision)},${Math.round(b.y * precision)},${Math.round(b.z * precision)}`;
hashes[2] = `${Math.round(c.x * precision)},${Math.round(c.y * precision)},${Math.round(c.z * precision)}`;
// skip degenerate triangles
if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) {
continue;
}
// iterate over every edge
for (let j = 0; j < 3; j++) {
// get the first and next vertex making up the edge
const jNext = (j + 1) % 3;
const vecHash0 = hashes[j];
const vecHash1 = hashes[jNext];
const v0 = _triangle[vertKeys[j]];
const v1 = _triangle[vertKeys[jNext]];
const hash = `${vecHash0}_${vecHash1}`;
const reverseHash = `${vecHash1}_${vecHash0}`;
if (reverseHash in edgeData && edgeData[reverseHash]) {
// if we found a sibling edge add it into the vertex array if
// it meets the angle threshold and delete the edge from the map.
if (_normal.dot(edgeData[reverseHash].normal) <= thresholdDot) {
vertices.push(v0.x, v0.y, v0.z);
vertices.push(v1.x, v1.y, v1.z);
}
edgeData[reverseHash] = null;
} else if (!(hash in edgeData)) {
// if we've already got an edge here then skip adding a new one
edgeData[hash] = {
index0: indexArr[j],
index1: indexArr[jNext],
normal: _normal.clone()
};
}
}
}
// iterate over all remaining, unmatched edges and add them to the vertex array
for (const key in edgeData) {
if (edgeData[key]) {
const {
index0,
index1
} = edgeData[key];
_v0.fromBufferAttribute(positionAttr, index0);
_v1.fromBufferAttribute(positionAttr, index1);
vertices.push(_v0.x, _v0.y, _v0.z);
vertices.push(_v1.x, _v1.y, _v1.z);
}
}
this.setAttribute('position', new _BufferAttribute.Float32BufferAttribute(vertices, 3));
}
}
copy(source) {
super.copy(source);
this.parameters = Object.assign({}, source.parameters);
return this;
}
}
exports.EdgesGeometry = EdgesGeometry;