awv3
Version:
⚡ AWV3 embedded CAD
329 lines (289 loc) • 14.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _three = require('three');
var THREE = _interopRequireWildcard(_three);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Raycaster = function (_THREE$Raycaster) {
(0, _inherits3.default)(Raycaster, _THREE$Raycaster);
function Raycaster(interaction) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { approach: Raycaster.Approach.FirstMatch };
(0, _classCallCheck3.default)(this, Raycaster);
var _this = (0, _possibleConstructorReturn3.default)(this, (Raycaster.__proto__ || (0, _getPrototypeOf2.default)(Raycaster)).call(this));
_this.interaction = interaction;
_this.view = interaction.view;
_this.linePrecision = 0.1;
_this._inverseMatrix = new THREE.Matrix4();
_this._ray = new THREE.Ray();
_this._sphere = new THREE.Sphere();
_this._vA = new THREE.Vector3();
_this._vB = new THREE.Vector3();
_this._vC = new THREE.Vector3();
_this._tempA = new THREE.Vector3();
_this._tempB = new THREE.Vector3();
_this._tempC = new THREE.Vector3();
_this._uvA = new THREE.Vector2();
_this._uvB = new THREE.Vector2();
_this._uvC = new THREE.Vector2();
_this._barycoord = new THREE.Vector3();
_this._intersectionPoint = new THREE.Vector3();
_this._intersectionPointWorld = new THREE.Vector3();
return _this;
}
(0, _createClass3.default)(Raycaster, [{
key: 'isActuallyVisible',
value: function isActuallyVisible(obj) {
while (obj) {
if (obj.visible === false) return false;
if (obj.material && obj.material.visible === false) return false;
obj = obj.parent;
}
return true;
}
}, {
key: 'castObjects',
value: function castObjects(coordinates, camera, objects) {
var intersects = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
var filter = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
this.setFromCamera(coordinates, camera);
for (var i = 0, l = objects.length, object; i < l; i++) {
object = objects[i];
if ( // No filter, filter is empty, or object is part of filter
(!filter || filter.length === 0 || filter.indexOf(object) >= 0) &&
// must be interactive
object.interactive
// must have interaction
&& object.interaction
// must be enabled
&& object.interaction.enabled
// muste be activ (have interaction related listeners)
&& object.interaction._active
// must be visible
&& this.isActuallyVisible(object)) {
// ... then we intersect
this.intersect(object, object.interaction.recursive, intersects, object.interaction.types, object);
}
}
intersects.sort(function (a, b) {
return b.receiver.interaction.priority - a.receiver.interaction.priority || a.distance - b.distance;
});
return intersects;
}
}, {
key: 'intersect',
value: function intersect(object, recursive, intersects, types, parent) {
var op = true;
// Inspect types
if (!!types) {
if (Array.isArray(types)) op = !(object.type !== 'Object3D' && types.indexOf(object.type) == -1);else if (typeof types === "function") op = types(object);
}
// false op stops operation right here, undefined op at least proceeds with childs
if (op == false) return;
var count = intersects.length;
// true op allows raycast
if (op == true) object.raycast(this, intersects, parent.interaction.approach);
if (intersects.length != count) {
for (var i = count, intersect, l = intersects.length; i < l; i++) {
intersect = intersects[i];
intersect.receiver = parent;
// If the parent/receiver is not recursive data.object should point back to it
if (!parent.interaction.recursive) {
intersect.receiver.object = parent;
}
}
}
// If the root is not recursive there's no point in iterating further
if (!parent.interaction.recursive) return;
for (var _i = 0, _l = object.children.length, child; _i < _l; _i++) {
child = object.children[_i];
if (child.visible && child.interactive) {
if (child.material) {
if (child.material.visible === true) {
this.intersect(child, true, intersects, types, parent);
}
} else if (child.materials && child.materials.all && child.materials.all.length > 0) {
if (child.materials.all[0].visible === true) {
this.intersect(child, true, intersects, types, parent);
}
} else {
this.intersect(child, true, intersects, types, parent);
}
}
}
}
}]);
return Raycaster;
}(THREE.Raycaster);
exports.default = Raycaster;
Raycaster.Approach = {
Default: 'Default', // Precision: +++, Speed: - , THREE.js default approach
First: 'First', // Precision: + , Speed: + , First vertex found, may be the back-side vertex (affects distance)
Bounds: 'Bounds' // Precision: - , Speed: +++, Checks bounds only
};
function uvIntersection(raycaster, point, p1, p2, p3, uv1, uv2, uv3) {
THREE.Triangle.barycoordFromPoint(point, p1, p2, p3, raycaster._barycoord);
uv1.multiplyScalar(raycaster._barycoord.x);
uv2.multiplyScalar(raycaster._barycoord.y);
uv3.multiplyScalar(raycaster._barycoord.z);
uv1.add(uv2).add(uv3);
return uv1.clone();
}
function checkIntersection(object, raycaster, ray, pA, pB, pC, point) {
var intersect;
var material = object.material;
if (material.side === THREE.BackSide) {
intersect = ray.intersectTriangle(pC, pB, pA, true, point);
} else {
intersect = ray.intersectTriangle(pA, pB, pC, material.side !== THREE.DoubleSide, point);
}
if (intersect === null) return null;
raycaster._intersectionPointWorld.copy(point);
raycaster._intersectionPointWorld.applyMatrix4(object.matrixWorld);
var distance = raycaster.ray.origin.distanceTo(raycaster._intersectionPointWorld);
if (distance < raycaster.near || distance > raycaster.far) return null;
return {
distance: distance,
point: raycaster._intersectionPointWorld.clone(),
object: object
};
}
function checkBufferGeometryIntersection(object, raycaster, ray, positions, uvs, a, b, c) {
raycaster._vA.fromArray(positions, a * 3);
raycaster._vB.fromArray(positions, b * 3);
raycaster._vC.fromArray(positions, c * 3);
var intersection = checkIntersection(object, raycaster, ray, raycaster._vA, raycaster._vB, raycaster._vC, raycaster._intersectionPoint);
if (intersection) {
if (uvs) {
raycaster._uvA.fromArray(uvs, a * 2);
raycaster._uvB.fromArray(uvs, b * 2);
raycaster._uvC.fromArray(uvs, c * 2);
intersection.uv = uvIntersection(raycaster, raycaster._intersectionPoint, raycaster._vA, raycaster._vB, raycaster._vC, raycaster._uvA, raycaster._uvB, raycaster._uvC);
}
intersection.face = new THREE.Face3(a, b, c, THREE.Triangle.normal(raycaster._vA, raycaster._vB, raycaster._vC));
intersection.faceIndex = a;
}
return intersection;
}
THREE.Mesh.prototype.raycast = function (raycaster, intersects, approach) {
var geometry = this.geometry;
var material = this.material;
var matrixWorld = this.matrixWorld;
if (material === undefined) return;
if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
raycaster._sphere.copy(geometry.boundingSphere);
raycaster._sphere.applyMatrix4(matrixWorld);
if (raycaster.ray.intersectsSphere(raycaster._sphere) === false) return;
raycaster._inverseMatrix.getInverse(matrixWorld);
raycaster._ray.copy(raycaster.ray).applyMatrix4(raycaster._inverseMatrix);
if (geometry.boundingBox !== null) {
if (raycaster._ray.intersectsBox(geometry.boundingBox) === false) return;
}
if (approach === Raycaster.Approach.Bounds) {
var _intersection = {
distance: raycaster.ray.origin.distanceTo(raycaster._sphere.center),
object: this,
point: raycaster._sphere.center.clone()
};
intersects.push(_intersection);
return;
}
var uvs, intersection;
if (geometry instanceof THREE.BufferGeometry) {
var a, b, c;
var index = geometry.index;
var attributes = geometry.attributes;
var positions = attributes.position.array;
if (attributes.uv !== undefined) {
uvs = attributes.uv.array;
}
if (index !== null) {
var indices = index.array;
for (var i = 0, l = indices.length; i < l; i += 3) {
a = indices[i];
b = indices[i + 1];
c = indices[i + 2];
intersection = checkBufferGeometryIntersection(this, raycaster, raycaster._ray, positions, uvs, a, b, c);
if (intersection) {
intersection.faceIndex = Math.floor(i / 3); // triangle number in indices buffer semantics
intersects.push(intersection);
if (approach === Raycaster.Approach.First) return;
}
}
} else {
for (var i = 0, l = positions.length; i < l; i += 9) {
a = i / 3;
b = a + 1;
c = a + 2;
intersection = checkBufferGeometryIntersection(this, raycaster, raycaster._ray, positions, uvs, a, b, c);
if (intersection) {
intersection.index = a; // triangle number in positions buffer semantics
intersects.push(intersection);
if (approach === Raycaster.Approach.First) return;
}
}
}
} else if (geometry instanceof THREE.Geometry) {
var fvA, fvB, fvC;
var isFaceMaterial = material instanceof THREE.MultiMaterial;
var materials = isFaceMaterial === true ? material.materials : null;
var vertices = geometry.vertices;
var faces = geometry.faces;
var faceVertexUvs = geometry.faceVertexUvs[0];
if (faceVertexUvs.length > 0) uvs = faceVertexUvs;
for (var f = 0, fl = faces.length; f < fl; f++) {
var face = faces[f];
var faceMaterial = isFaceMaterial === true ? materials[face.materialIndex] : material;
if (faceMaterial === undefined) continue;
fvA = vertices[face.a];
fvB = vertices[face.b];
fvC = vertices[face.c];
if (faceMaterial.morphTargets === true) {
var morphTargets = geometry.morphTargets;
var morphInfluences = this.morphTargetInfluences;
raycaster._vA.set(0, 0, 0);
raycaster._vB.set(0, 0, 0);
raycaster._vC.set(0, 0, 0);
for (var t = 0, tl = morphTargets.length; t < tl; t++) {
var influence = morphInfluences[t];
if (influence === 0) continue;
var targets = morphTargets[t].vertices;
raycaster._vA.addScaledVector(raycaster._tempA.subVectors(targets[face.a], fvA), influence);
raycaster._vB.addScaledVector(raycaster._tempB.subVectors(targets[face.b], fvB), influence);
raycaster._vC.addScaledVector(raycaster._tempC.subVectors(targets[face.c], fvC), influence);
}
raycaster._vA.add(fvA);
raycaster._vB.add(fvB);
raycaster._vC.add(fvC);
fvA = raycaster._vA;
fvB = raycaster._vB;
fvC = raycaster._vC;
}
intersection = checkIntersection(this, raycaster, raycaster._ray, fvA, fvB, fvC, raycaster._intersectionPoint);
if (intersection) {
if (uvs) {
var uvs_f = uvs[f];
raycaster._uvA.copy(uvs_f[0]);
raycaster._uvB.copy(uvs_f[1]);
raycaster._uvC.copy(uvs_f[2]);
intersection.uv = uvIntersection(raycaster, raycaster._intersectionPoint, fvA, fvB, fvC, raycaster._uvA, raycaster._uvB, raycaster._uvC);
}
intersection.face = face;
intersection.faceIndex = f;
intersects.push(intersection);
if (approach === Raycaster.Approach.First) return;
}
}
}
};