UNPKG

awv3

Version:
329 lines (289 loc) 14.4 kB
'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; } } } };