UNPKG

awv3

Version:
207 lines (172 loc) 6.43 kB
import _extends from "@babel/runtime/helpers/extends"; import _createClass from "@babel/runtime/helpers/createClass"; import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import * as THREE from 'three'; import cloneDeep from 'lodash/cloneDeep'; import { collectNestedIds } from '../session/helpers'; var SCALE = 6; var geometry = new THREE.SphereBufferGeometry(1, 6, 6); var inverseMatrix = new THREE.Matrix4(); var ray = new THREE.Ray(); var sphere = new THREE.Sphere(); /** * @class Region contains vertices from ClassCAD, which are not visible, but * can be selected through raycasting and then be created with the given * information {id, point, meta}. */ var Region = /*#__PURE__*/ function (_THREE$Object3D) { _inheritsLoose(Region, _THREE$Object3D); function Region() { var _this; _this = _THREE$Object3D.call(this) || this; _this.type = 'Region'; _this.boundingSphere = new THREE.Sphere(); _this.pointSphere = new THREE.Sphere(); _this.points = []; _this._visible = false; _this.viewFound().then(function (view) { _this.createInteraction().on(THREE.Object3D.Events.Lifecycle.Rendered, function () { _this.visible && _this.children.forEach(function (point) { var scaleFactor = view.calculateScaleFactor(_this.localToWorld(point.position.clone()), SCALE); point.scale.set(scaleFactor, scaleFactor, scaleFactor); }); }); }); return _this; } var _proto = Region.prototype; _proto.destroyPoints = function destroyPoints() { if (this.points) { this.points.forEach(function (point) { if (point.meta.ref) { point.meta.ref.destroy(); point.meta.ref = undefined; } }); } }; _proto.createPoint = function createPoint(point, factor) { if (!point || point.meta.ref) return; if (factor == undefined) { factor = point.meta.ref ? point.meta.ref.scale.x : this.view ? this.view.calculateScaleFactor(this.localToWorld(point.meta.position.clone()), SCALE) : 1; } var opacity = point.meta.static === true ? 0.1 : 0; var material = new THREE.MeshBasicMaterial({ color: 0, transparent: true, opacity: opacity }); material.meta = _extends({ id: point.id }, point.meta, { material: { opacity: opacity, color: new THREE.Color(0) } }); var mesh = new THREE.Mesh(geometry, material); mesh.type = 'RegionPoint'; mesh.position.copy(point.meta.position); mesh.interactive = false; mesh.measurable = false; mesh.renderOrder = 1000; mesh.scale.set(factor, factor, factor); point.meta.ref = mesh; this.add(mesh); // Generate a nested ID to make points assembly safe material.meta.nestedId = collectNestedIds(mesh).concat([material.meta.id]).join(','); }; _proto.addPoint = function addPoint(props) { if (!this.isDuplicatePoint(props.meta.position)) this.points.push(props); }; _proto.isDuplicatePoint = function isDuplicatePoint(position) { // TODO: making it more efficient for (var _iterator = this.points, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var _point = _ref; if (_point.meta.position.distanceToSquared(position) < 1e-4 * 1e-4) return true; } return false; }; /** * This code is mostly copied form THREE.Points.js and adjusted to the fact * that Region does not have geometry or graphical representation */ _proto.raycast = function raycast(raycaster, intersects) { var _this2 = this; if (!this.visible) return; // Checking boundingSphere distance to ray sphere.copy(this.boundingSphere); sphere.radius += raycaster.params.Points.threshold; sphere.applyMatrix4(this.matrixWorld); if (raycaster.ray.intersectsSphere(sphere) === false) return; inverseMatrix.getInverse(this.matrixWorld); ray.copy(raycaster.ray).applyMatrix4(inverseMatrix); //test each point this.points.forEach(function (point, index) { var child = point.meta.ref; var scaleFactor = child ? child.scale.x : _this2.view ? _this2.view.calculateScaleFactor(_this2.localToWorld(point.meta.position.clone()), SCALE) : 1; _this2.pointSphere.center = point.meta.position.clone(); _this2.pointSphere.radius = scaleFactor; var intersectPoint = ray.intersectSphere(_this2.pointSphere); if (intersectPoint === null) return; var rayPointDistanceSq = ray.distanceSqToPoint(_this2.pointSphere.center); // Move back to world space for distance calculation intersectPoint.applyMatrix4(_this2.matrixWorld); var distance = raycaster.ray.origin.distanceTo(intersectPoint); if (distance < raycaster.near || distance > raycaster.far) return; _this2.createPoint(point, scaleFactor); intersects.push({ distance: distance, point: intersectPoint.clone(), index: index, face: null, object: _this2, ref: point.meta.ref.material }); }); }; /** * Computes the bounding sphere of the points (in model coordinates). */ _proto.computeBoundingSphere = function computeBoundingSphere() { if (this.points) { this.boundingSphere.setFromPoints(this.points.map(function (entry) { return entry.meta.position; })); } }; _proto.clone = function clone() { this.destroyPoints(); var clone = _THREE$Object3D.prototype.clone.call(this); clone.points = cloneDeep(this.points); // TODO: WHY??? clone.visible = this.visible; clone.computeBoundingSphere(); return clone; }; _createClass(Region, [{ key: "visible", get: function get() { return this._visible; }, set: function set(value) { var _this3 = this; this._visible = value; if (this.points) { this.destroyPoints(); if (value === true) this.points.forEach(function (point, index) { return point.meta.static && _this3.createPoint(point); }); this.computeBoundingSphere(); } } }]); return Region; }(THREE.Object3D); export { Region as default };