awv3
Version:
⚡ AWV3 embedded CAD
495 lines (430 loc) • 22.3 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _three = require('three');
var THREE = _interopRequireWildcard(_three);
var _raycaster = require('../three/raycaster');
var _raycaster2 = _interopRequireDefault(_raycaster);
var _object = require('../three/object3');
var _object2 = _interopRequireDefault(_object);
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 Interaction = function () {
function Interaction() {
var view = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Error.log('View undefined');
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _classCallCheck3.default)(this, Interaction);
this.view = view;
this.canvas = view.canvas;
this.raycaster = new _raycaster2.default(this);
this.enabled = typeof options.enabled !== 'undefined' ? options.enabled : true;
this.targets = [];
this.intersects = [];
this.hits = {};
this.hitsArray = [];
this.actions = {};
this.actionsArray = [];
this.hovered = {};
this.filter = undefined;
this.coordinates = new THREE.Vector3(0, 0, 0);
this.click = new THREE.Vector3(0, 0, 0);
this.delta = 0;
this.__hovered = [];
this.__frontside = {};
}
(0, _createClass3.default)(Interaction, [{
key: 'update',
value: function update() {
if (!this.enabled) return;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(this.targets), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var target = _step.value;
if (target.interaction && target.interaction.enabled && (this.view.invalidateFrames > 0 || this.view.renderAlways || this.view.controls.inMotion) /*|| this.view.hudInMotion TODO: there are several hids now */
) {
target.emit(_object2.default.Events.Lifecycle.Rendered);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}, {
key: 'onMouseMove',
value: function onMouseMove(event) {
var _this = this;
if (!this.enabled) return;
this.coordinates.set(event.offsetX / this.view.width * 2 - 1, -(event.offsetY / this.view.height) * 2 + 1, 1);
this.delta = Math.max(this.delta, Math.abs(this.click.x - this.coordinates.x) + Math.abs(this.click.y - this.coordinates.y));
// View is moved or dry run (nothing under the curser when the view was clicked/touched)
if (this.view.controls.interaction || !event.fake && this.view.input.mouse.down && this.actionsArray.length == 0) return;
this.raycaster.setFromCamera(this.coordinates, this.view.camera.display);
this.intersects = [];
this.__hovered = [];
this.__frontside = {};
if (this.targets.length > 0) {
this.raycaster.castObjects(this.targets, this.intersects, this.filter);
if (this.intersects.length > 0) {
// Objects that have been pierced
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = (0, _getIterator3.default)(this.intersects), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var data = _step2.value;
// Set unique key
data.id = data.receiver.id;
if (data.receiver.interaction.recursive) data.id += 'R' + data.object.id;
if (data.face && data.object.userData && data.object.userData.refs) data.id += 'F' + data.face.materialIndex;
// Add region specific data
if (data.type === 'Region') {
data.id += 'V' + data.ref.id;
data.meta = data.ref.meta;
data.vertexId = data.ref.id;
}
// Flag is set on first occurance of a receiver
data.first = data === this.intersects[0];
// Current RAF timestamp
data.time = this.canvas.renderer.time;
// Mouse coordinates in world CS
data.ray = this.raycaster.ray;
// Fetch meta, if any
if (data.face && data.object.userData && data.object.userData.refs) {
data.meta = data.object.userData.refs[data.face.materialIndex];
} else if (data.object.userData && data.object.userData.meta) {
data.meta = data.object.userData.meta;
}
if (data.object.material) {
var isMultiMaterial = Array.isArray(data.object.material);
if (data.face) {
if (isMultiMaterial) {
data.materialIndex = data.face.materialIndex;
data.multiMaterial = data.object.material;
data.material = data.object.material[data.face.materialIndex];
} else {
data.material = data.object.material;
}
} else if (typeof data.index !== 'undefined') {
if (isMultiMaterial && data.object.geometry.groups) {
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = (0, _getIterator3.default)(data.object.geometry.groups), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var group = _step3.value;
if (group.start <= data.index && group.start + group.count > data.index) {
data.materialIndex = group.materialIndex;
data.multiMaterial = data.object.material;
data.material = data.object.material[group.materialIndex];
data.meta = group.meta;
data.id += 'L' + group.materialIndex;
break;
}
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
} else {
data.material = data.object.material;
}
}
}
// Raycaster can return two intersections, front & back, we cast away the backside
if (this.__frontside[data.id]) continue;
// Mark it for hover if it hasn't been hit already
if ((!data.receiver.interaction.first || data.first) && !this.hovered[data.id]) this.__hovered.push(data);
this.hits[data.id] = data;
this.__frontside[data.id] = true;
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
} else {
this.actionsArray.length == 0 && this.view.setCursor();
}
// Take out everything that's not under the cursor right now and that's not in the actions
this.hitsArray = (0, _keys2.default)(this.hits).map(function (item) {
return _this.hits[item];
})
// Sort after scene-graph
.sort(function (a, b) {
return a.receiver.depthIndex - b.receiver.depthIndex;
})
// Filter
.filter(function (data) {
var dispose = data.receiver.interaction.first && !data.first || data.time != _this.canvas.renderer.time;
if (dispose) {
if (_this.hovered[data.id] && !_this.actions[data.id]) {
delete _this.hovered[data.id];
data.receiver.emit(_object2.default.Events.Interaction.Unhovered, data);
_this.view.invalidate();
}
delete _this.hits[data.id];
}
return !dispose;
});
// Hover items
this.__hovered.forEach(function (data) {
_this.hovered[data.id] = true;
data.receiver.emit(_object2.default.Events.Interaction.Hovered, data);
_this.view.invalidate();
});
}
// Object being dragged
if (this.delta > 0.01 && (0, _keys2.default)(this.actions).length > 0) {
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = (0, _getIterator3.default)(this.actionsArray), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var _data = _step4.value;
if (!_data.receiver.interaction.first || _data.first) {
var vector = this.coordinates.clone().unproject(this.view.camera.display).sub(this.view.camera.display.position).normalize();
_data.drag = this.view.camera.display.position.clone().add(vector.multiplyScalar(_data.distance)).add(_data.offset);
_data.ray = this.raycaster.ray;
_data.receiver.emit(_object2.default.Events.Interaction.Dragged, _data);
this.view.invalidate();
}
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
}
}
}, {
key: 'onMouseOut',
value: function onMouseOut(event) {
if (!this.enabled) return;
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
for (var _iterator5 = (0, _getIterator3.default)(this.hitsArray), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var data = _step5.value;
if (this.hovered[data.id] && !this.actions[data.id]) {
delete this.hovered[data.id];
data.receiver.emit(_object2.default.Events.Interaction.Unhovered, data);
this.view.invalidate();
}
delete this.hits[data.id];
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
}
}, {
key: 'onMouseDown',
value: function onMouseDown(event) {
if (!this.enabled) return;
this.delta = 0;
this.click.set(event.offsetX / this.view.width * 2 - 1, -(event.offsetY / this.view.height) * 2 + 1, 1);
// Cause a fake-mousemove to refresh hits
this.onMouseMove((0, _extends3.default)({}, event, { fake: true }));
this.actions = {};
this.actionsArray = [];
var _iteratorNormalCompletion6 = true;
var _didIteratorError6 = false;
var _iteratorError6 = undefined;
try {
for (var _iterator6 = (0, _getIterator3.default)(this.hitsArray), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
var data = _step6.value;
if (!data.receiver.interaction.first || data.first) {
var pos = data.receiver.parent ? data.receiver.parent.localToWorld(data.receiver.position.clone()) : data.receiver.position.clone();
data.offset = pos.sub(data.point.clone());
this.actions[data.id] = data;
this.actionsArray.push(data);
data.receiver.emit(_object2.default.Events.Interaction.Picked, data);
}
}
} catch (err) {
_didIteratorError6 = true;
_iteratorError6 = err;
} finally {
try {
if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}
} finally {
if (_didIteratorError6) {
throw _iteratorError6;
}
}
}
this.view.invalidate();
}
}, {
key: 'onMouseUp',
value: function onMouseUp(event) {
if (!this.enabled) return;
// Signal Mouseup
var _iteratorNormalCompletion7 = true;
var _didIteratorError7 = false;
var _iteratorError7 = undefined;
try {
for (var _iterator7 = (0, _getIterator3.default)(this.actionsArray), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
var data = _step7.value;
if (this.hovered[data.id] && !this.hits[data.id]) {
delete this.hovered[data.id];
data.receiver.emit(_object2.default.Events.Interaction.Unhovered, data);
}
data.receiver.emit(_object2.default.Events.Interaction.Dropped, data);
if (this.delta < 0.05) {
data.receiver.emit(_object2.default.Events.Interaction.Clicked, data);
}
}
} catch (err) {
_didIteratorError7 = true;
_iteratorError7 = err;
} finally {
try {
if (!_iteratorNormalCompletion7 && _iterator7.return) {
_iterator7.return();
}
} finally {
if (_didIteratorError7) {
throw _iteratorError7;
}
}
}
if (this.actionsArray.length == 0 && this.delta < 0.05) {
var _iteratorNormalCompletion8 = true;
var _didIteratorError8 = false;
var _iteratorError8 = undefined;
try {
for (var _iterator8 = (0, _getIterator3.default)(this.targets), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
var target = _step8.value;
target.emit(_object2.default.Events.Interaction.Missed);
}
} catch (err) {
_didIteratorError8 = true;
_iteratorError8 = err;
} finally {
try {
if (!_iteratorNormalCompletion8 && _iterator8.return) {
_iterator8.return();
}
} finally {
if (_didIteratorError8) {
throw _iteratorError8;
}
}
}
}
this.view.invalidate();
this.actions = {};
this.actionsArray = [];
}
}, {
key: 'removeTarget',
value: function removeTarget(obj) {
var _this2 = this;
var index = this.targets.indexOf(obj);
if (index > -1) this.targets.splice(index, 1);
this.hitsArray.forEach(function (item) {
return item.receiver === obj && _this2.hitsArray.splice(_this2.hitsArray.indexOf(item), 1);
});
this.actionsArray.forEach(function (item) {
return item.receiver === obj && _this2.actionsArray.splice(_this2.actionsArray.indexOf(item), 1);
});
(0, _keys2.default)(this.hits).forEach(function (item) {
return _this2.hits[item].receiver === obj && delete _this2.hits[item];
});
(0, _keys2.default)(this.actions).forEach(function (item) {
return _this2.actions[item].receiver === obj && delete _this2.actions[item];
});
(0, _keys2.default)(this.hovered).forEach(function (item) {
return _this2.hovered[item].receiver === obj && delete _this2.hovered[item];
});
}
}, {
key: 'getActions',
value: function getActions() {
return this.actionsArray;
}
}, {
key: 'isHit',
value: function isHit(obj) {
return this.hitsArray.find(function (data) {
if (obj instanceof THREE.Material) return data.material === obj;else return data.object.id === obj.id;
}) !== undefined;
}
}, {
key: 'isAction',
value: function isAction(obj) {
return this.actionsArray.find(function (item) {
return item.object.id == obj.id;
});
}
}]);
return Interaction;
}();
exports.default = Interaction;