|
@@ -0,0 +1,368 @@
|
|
|
+/******/ (function(modules) { // webpackBootstrap
|
|
|
+/******/ // The module cache
|
|
|
+/******/ var installedModules = {};
|
|
|
+
|
|
|
+/******/ // The require function
|
|
|
+/******/ function __webpack_require__(moduleId) {
|
|
|
+
|
|
|
+/******/ // Check if module is in cache
|
|
|
+/******/ if(installedModules[moduleId])
|
|
|
+/******/ return installedModules[moduleId].exports;
|
|
|
+
|
|
|
+/******/ // Create a new module (and put it into the cache)
|
|
|
+/******/ var module = installedModules[moduleId] = {
|
|
|
+/******/ exports: {},
|
|
|
+/******/ id: moduleId,
|
|
|
+/******/ loaded: false
|
|
|
+/******/ };
|
|
|
+
|
|
|
+/******/ // Execute the module function
|
|
|
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
|
+
|
|
|
+/******/ // Flag the module as loaded
|
|
|
+/******/ module.loaded = true;
|
|
|
+
|
|
|
+/******/ // Return the exports of the module
|
|
|
+/******/ return module.exports;
|
|
|
+/******/ }
|
|
|
+
|
|
|
+
|
|
|
+/******/ // expose the modules object (__webpack_modules__)
|
|
|
+/******/ __webpack_require__.m = modules;
|
|
|
+
|
|
|
+/******/ // expose the module cache
|
|
|
+/******/ __webpack_require__.c = installedModules;
|
|
|
+
|
|
|
+/******/ // __webpack_public_path__
|
|
|
+/******/ __webpack_require__.p = "";
|
|
|
+
|
|
|
+/******/ // Load entry module and return exports
|
|
|
+/******/ return __webpack_require__(0);
|
|
|
+/******/ })
|
|
|
+/************************************************************************/
|
|
|
+/******/ ([
|
|
|
+/* 0 */
|
|
|
+/***/ (function(module, exports) {
|
|
|
+
|
|
|
+ /* global AFRAME */
|
|
|
+
|
|
|
+ if (typeof AFRAME === 'undefined') {
|
|
|
+ throw new Error('Component attempted to register before AFRAME was available.');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Curve component for A-Frame to deal with spline curves
|
|
|
+ */
|
|
|
+ var zAxis = new THREE.Vector3(0, 0, 1);
|
|
|
+ var degToRad = THREE.Math.degToRad;
|
|
|
+
|
|
|
+ AFRAME.registerComponent('curve-point', {
|
|
|
+
|
|
|
+ //dependencies: ['position'],
|
|
|
+
|
|
|
+ schema: {},
|
|
|
+
|
|
|
+ init: function () {
|
|
|
+ this.el.addEventListener("componentchanged", this.changeHandler.bind(this));
|
|
|
+ this.el.emit("curve-point-change");
|
|
|
+ },
|
|
|
+
|
|
|
+ changeHandler: function (event) {
|
|
|
+ if (event.detail.name == "position") {
|
|
|
+ this.el.emit("curve-point-change");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ AFRAME.registerComponent('curve', {
|
|
|
+
|
|
|
+ //dependencies: ['curve-point'],
|
|
|
+
|
|
|
+ schema: {
|
|
|
+ type: {
|
|
|
+ type: 'string',
|
|
|
+ default: 'CurvePath',
|
|
|
+ oneOf: ['CatmullRom', 'CubicBezier', 'QuadraticBezier', 'Line', 'CurvePath']
|
|
|
+ },
|
|
|
+ closed: {
|
|
|
+ type: 'boolean',
|
|
|
+ default: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ init: function () {
|
|
|
+ this.pathPoints = null;
|
|
|
+ this.curve = null;
|
|
|
+
|
|
|
+ this.el.addEventListener("curve-point-change", this.update.bind(this));
|
|
|
+ },
|
|
|
+
|
|
|
+ update: function (oldData) {
|
|
|
+
|
|
|
+ this.points = Array.from(this.el.querySelectorAll("a-curve-point, [curve-point]"));
|
|
|
+
|
|
|
+ if (this.points.length <= 1) {
|
|
|
+ console.warn("At least 2 curve-points needed to draw a curve");
|
|
|
+ this.curve = null;
|
|
|
+ } else {
|
|
|
+ // Get Array of Positions from Curve-Points
|
|
|
+ var pointsArray = this.points.map(function (point) {
|
|
|
+
|
|
|
+ if (point.x !== undefined && point.y !== undefined && point.z !== undefined) {
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ return point.object3D.getWorldPosition();
|
|
|
+ });
|
|
|
+
|
|
|
+ // Update the Curve if either the Curve-Points or other Properties changed
|
|
|
+ if (!AFRAME.utils.deepEqual(pointsArray, this.pathPoints) || (oldData !== 'CustomEvent' && !AFRAME.utils.deepEqual(this.data, oldData))) {
|
|
|
+ this.curve = null;
|
|
|
+
|
|
|
+ this.pathPoints = pointsArray;
|
|
|
+
|
|
|
+ // Create Curve
|
|
|
+ switch (this.data.type) {
|
|
|
+ case 'CubicBezier':
|
|
|
+ if (this.pathPoints.length != 4) {
|
|
|
+ throw new Error('The Three constructor of type CubicBezierCurve3 requires 4 points');
|
|
|
+ }
|
|
|
+ this.curve = new THREE.CubicBezierCurve3(this.pathPoints[0], this.pathPoints[1], this.pathPoints[2], this.pathPoints[3]);
|
|
|
+ break;
|
|
|
+ case 'QuadraticBezier':
|
|
|
+ if (this.pathPoints.length != 3) {
|
|
|
+ throw new Error('The Three constructor of type QuadraticBezierCurve3 requires 3 points');
|
|
|
+ }
|
|
|
+ this.curve = new THREE.QuadraticBezierCurve3(this.pathPoints[0], this.pathPoints[1], this.pathPoints[2]);
|
|
|
+ break;
|
|
|
+ case 'Line':
|
|
|
+ if (this.pathPoints.length != 2) {
|
|
|
+ throw new Error('The Three constructor of type LineCurve3 requires 2 points');
|
|
|
+ }
|
|
|
+ this.curve = new THREE.LineCurve3(this.pathPoints[0], this.pathPoints[1]);
|
|
|
+ break;
|
|
|
+ case 'CatmullRom':
|
|
|
+ this.curve = new THREE.CatmullRomCurve3(this.pathPoints);
|
|
|
+ break;
|
|
|
+ case 'Spline':
|
|
|
+ this.curve = new THREE.SplineCurve3(this.pathPoints);
|
|
|
+ break;
|
|
|
+
|
|
|
+ // Patrick
|
|
|
+ case 'CurvePath':
|
|
|
+ this.curve = new THREE.CurvePath();
|
|
|
+ for(var i = 0, p = this.pathPoints.length - 1; i < p; i++) {
|
|
|
+ var curveSegment = new THREE.LineCurve3(this.pathPoints[i], this.pathPoints[i + 1]);
|
|
|
+ this.curve.add(curveSegment);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new Error('No Three constructor of type (case sensitive): ' + this.data.type + 'Curve3');
|
|
|
+ }
|
|
|
+
|
|
|
+ this.curve.closed = this.data.closed;
|
|
|
+
|
|
|
+ this.el.emit('curve-updated');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ remove: function () {
|
|
|
+ this.el.removeEventListener("curve-point-change", this.update.bind(this));
|
|
|
+ },
|
|
|
+
|
|
|
+ closestPointInLocalSpace: function closestPoint(point, resolution, testPoint, currentRes) {
|
|
|
+ if (!this.curve) throw Error('Curve not instantiated yet.');
|
|
|
+ resolution = resolution || 0.1 / this.curve.getLength();
|
|
|
+ currentRes = currentRes || 0.5;
|
|
|
+ testPoint = testPoint || 0.5;
|
|
|
+ currentRes /= 2;
|
|
|
+ var aTest = testPoint + currentRes;
|
|
|
+ var bTest = testPoint - currentRes;
|
|
|
+ var a = this.curve.getPointAt(aTest);
|
|
|
+ var b = this.curve.getPointAt(bTest);
|
|
|
+ var aDistance = a.distanceTo(point);
|
|
|
+ var bDistance = b.distanceTo(point);
|
|
|
+ var aSmaller = aDistance < bDistance;
|
|
|
+ if (currentRes < resolution) {
|
|
|
+
|
|
|
+ var tangent = this.curve.getTangentAt(aSmaller ? aTest : bTest);
|
|
|
+ if (currentRes < resolution) return {
|
|
|
+ result: aSmaller ? aTest : bTest,
|
|
|
+ location: aSmaller ? a : b,
|
|
|
+ distance: aSmaller ? aDistance : bDistance,
|
|
|
+ normal: normalFromTangent(tangent),
|
|
|
+ tangent: tangent
|
|
|
+ };
|
|
|
+ }
|
|
|
+ if (aDistance < bDistance) {
|
|
|
+ return this.closestPointInLocalSpace(point, resolution, aTest, currentRes);
|
|
|
+ } else {
|
|
|
+ return this.closestPointInLocalSpace(point, resolution, bTest, currentRes);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ var tempQuaternion = new THREE.Quaternion();
|
|
|
+
|
|
|
+ function normalFromTangent(tangent) {
|
|
|
+ var lineEnd = new THREE.Vector3(0, 1, 0);
|
|
|
+ tempQuaternion.setFromUnitVectors(zAxis, tangent);
|
|
|
+ lineEnd.applyQuaternion(tempQuaternion);
|
|
|
+ return lineEnd;
|
|
|
+ }
|
|
|
+
|
|
|
+ AFRAME.registerShader('line', {
|
|
|
+ schema: {
|
|
|
+ color: {default: '#ff0000'},
|
|
|
+ },
|
|
|
+
|
|
|
+ init: function (data) {
|
|
|
+ this.material = new THREE.LineBasicMaterial(data);
|
|
|
+ },
|
|
|
+
|
|
|
+ update: function (data) {
|
|
|
+ this.material = new THREE.LineBasicMaterial(data);
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ AFRAME.registerComponent('draw-curve', {
|
|
|
+
|
|
|
+ //dependencies: ['curve', 'material'],
|
|
|
+
|
|
|
+ schema: {
|
|
|
+ curve: {type: 'selector'}
|
|
|
+ },
|
|
|
+
|
|
|
+ init: function () {
|
|
|
+ console.log(this.data);
|
|
|
+ this.data.curve.addEventListener('curve-updated', this.update.bind(this));
|
|
|
+ },
|
|
|
+
|
|
|
+ update: function () {
|
|
|
+ if (this.data.curve) {
|
|
|
+ this.curve = this.data.curve.components.curve;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.curve && this.curve.curve) {
|
|
|
+ var lineGeometry = new THREE.BufferGeometry().setFromPoints(this.curve.curve.getPoints(this.curve.curve.getPoints().length * 10));
|
|
|
+ var mesh = this.el.getOrCreateObject3D('mesh', THREE.Line);
|
|
|
+ lineMaterial = mesh.material ? mesh.material : new THREE.LineBasicMaterial({
|
|
|
+ color: "#ff0000"
|
|
|
+ });
|
|
|
+
|
|
|
+ this.el.setObject3D('mesh', new THREE.Line(lineGeometry, lineMaterial));
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ remove: function () {
|
|
|
+ this.data.curve.removeEventListener('curve-updated', this.update.bind(this));
|
|
|
+ this.el.getObject3D('mesh').geometry = new THREE.Geometry();
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ AFRAME.registerComponent('clone-along-curve', {
|
|
|
+
|
|
|
+ //dependencies: ['curve'],
|
|
|
+
|
|
|
+ schema: {
|
|
|
+ curve: {type: 'selector'},
|
|
|
+ spacing: {default: 1},
|
|
|
+ rotation: {
|
|
|
+ type: 'vec3',
|
|
|
+ default: '0 0 0'
|
|
|
+ },
|
|
|
+ scale: {
|
|
|
+ type: 'vec3',
|
|
|
+ default: '1 1 1'
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ init: function () {
|
|
|
+ this.el.addEventListener('model-loaded', this.update.bind(this));
|
|
|
+ this.data.curve.addEventListener('curve-updated', this.update.bind(this));
|
|
|
+ },
|
|
|
+
|
|
|
+ update: function () {
|
|
|
+ this.remove();
|
|
|
+
|
|
|
+ if (this.data.curve) {
|
|
|
+ this.curve = this.data.curve.components.curve;
|
|
|
+ }
|
|
|
+console.log(this.curve);
|
|
|
+ if (!this.el.getObject3D('clones') && this.curve && this.curve.curve) {
|
|
|
+ var mesh = this.el.getObject3D('mesh');
|
|
|
+
|
|
|
+ var length = this.curve.curve.getLength();
|
|
|
+ var start = 0;
|
|
|
+ var counter = start;
|
|
|
+
|
|
|
+ var cloneMesh = this.el.getOrCreateObject3D('clones', THREE.Group);
|
|
|
+
|
|
|
+ var parent = new THREE.Object3D();
|
|
|
+ mesh.scale.set(this.data.scale.x, this.data.scale.y, this.data.scale.z);
|
|
|
+ mesh.rotation.set(degToRad(this.data.rotation.x), degToRad(this.data.rotation.y), degToRad(this.data.rotation.z));
|
|
|
+ mesh.rotation.order = 'YXZ';
|
|
|
+
|
|
|
+ parent.add(mesh);
|
|
|
+
|
|
|
+ while (counter <= length) {
|
|
|
+ var child = parent.clone(true);
|
|
|
+
|
|
|
+ child.position.copy(this.curve.curve.getPointAt(counter / length));
|
|
|
+
|
|
|
+ tangent = this.curve.curve.getTangentAt(counter / length).normalize();
|
|
|
+
|
|
|
+ child.quaternion.setFromUnitVectors(zAxis, tangent);
|
|
|
+
|
|
|
+ cloneMesh.add(child);
|
|
|
+
|
|
|
+ counter += this.data.spacing;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ remove: function () {
|
|
|
+ this.curve = null;
|
|
|
+ if (this.el.getObject3D('clones')) {
|
|
|
+ this.el.removeObject3D('clones');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ AFRAME.registerPrimitive('a-draw-curve', {
|
|
|
+ defaultComponents: {
|
|
|
+ 'draw-curve': {},
|
|
|
+ },
|
|
|
+ mappings: {
|
|
|
+ curveref: 'draw-curve.curve',
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ AFRAME.registerPrimitive('a-curve-point', {
|
|
|
+ defaultComponents: {
|
|
|
+ 'curve-point': {},
|
|
|
+ },
|
|
|
+ mappings: {}
|
|
|
+ });
|
|
|
+
|
|
|
+ AFRAME.registerPrimitive('a-curve', {
|
|
|
+ defaultComponents: {
|
|
|
+ 'curve': {}
|
|
|
+ },
|
|
|
+
|
|
|
+ mappings: {
|
|
|
+ type: 'curve.type',
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+/***/ })
|
|
|
+/******/ ]);
|