aframe-extras.pathfinding.min.js 13 KB

1
  1. !function t(e,n,r){function o(s,a){if(!n[s]){if(!e[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var c=n[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return o(n||t)},c,c.exports,t,e,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(t,e,n){"use strict";t("./src/pathfinding")},{"./src/pathfinding":3}],2:[function(t,e,n){var r=function(){};r.computeCentroids=function(t){var e,n,r;for(e=0,n=t.faces.length;e<n;e++)(r=t.faces[e]).centroid=new THREE.Vector3(0,0,0),r.centroid.add(t.vertices[r.a]),r.centroid.add(t.vertices[r.b]),r.centroid.add(t.vertices[r.c]),r.centroid.divideScalar(3)},r.roundNumber=function(t,e){return Number(t.toFixed(e))},r.sample=function(t){return t[Math.floor(Math.random()*t.length)]},r.mergeVertexIds=function(t,e){var n=[];if(t.forEach(function(t){e.indexOf(t)>=0&&n.push(t)}),n.length<2)return[];n.includes(t[0])&&n.includes(t[t.length-1])&&t.push(t.shift()),n.includes(e[0])&&n.includes(e[e.length-1])&&e.push(e.shift()),n=[],t.forEach(function(t){e.includes(t)&&n.push(t)});for(var r=n[1],o=n[0],i=t.slice();i[0]!==r;)i.push(i.shift());for(var s=0,a=e.slice();a[0]!==o;)if(a.push(a.shift()),s++>10)throw new Error("Unexpected state");return a.shift(),a.pop(),i=i.concat(a)},r.setPolygonCentroid=function(t,e){var n=new THREE.Vector3,r=e.vertices;t.vertexIds.forEach(function(t){n.add(r[t])}),n.divideScalar(t.vertexIds.length),t.centroid.copy(n)},r.cleanPolygon=function(t,e){for(var n=[],r=e.vertices,o=0;o<t.vertexIds.length;o++){var i,s,a,u=r[t.vertexIds[o]];0===o?(i=t.vertexIds[1],s=t.vertexIds[t.vertexIds.length-1]):o===t.vertexIds.length-1?(i=t.vertexIds[0],s=t.vertexIds[t.vertexIds.length-2]):(i=t.vertexIds[o+1],s=t.vertexIds[o-1]),a=r[s];var h=r[i].clone().sub(u),c=a.clone().sub(u),d=h.angleTo(c);if(d>Math.PI-.01&&d<Math.PI+.01){var f=[];t.neighbours.forEach(function(e){e.vertexIds.includes(t.vertexIds[o])||f.push(e)}),t.neighbours=f}else n.push(t.vertexIds[o])}t.vertexIds=n,this.setPolygonCentroid(t,e)},r.isConvex=function(t,e){var n=e.vertices;if(t.vertexIds.length<3)return!1;for(var r=!0,o=[],i=0;i<t.vertexIds.length;i++){var s,a,u=n[t.vertexIds[i]];0===i?(s=n[t.vertexIds[1]],a=n[t.vertexIds[t.vertexIds.length-1]]):i===t.vertexIds.length-1?(s=n[t.vertexIds[0]],a=n[t.vertexIds[t.vertexIds.length-2]]):(s=n[t.vertexIds[i+1]],a=n[t.vertexIds[i-1]]);var h=s.clone().sub(u),c=a.clone().sub(u),d=h.angleTo(c);if(d===Math.PI||0===d)return!1;var f=h.cross(c).y;o.push(f)}return o.forEach(function(t){0===t&&(r=!1)}),o.forEach(o[0]>0?function(t){t<0&&(r=!1)}:function(t){t>0&&(r=!1)}),r},r.distanceToSquared=function(t,e){var n=t.x-e.x,r=t.y-e.y,o=t.z-e.z;return n*n+r*r+o*o},r.isPointInPoly=function(t,e){for(var n=!1,r=-1,o=t.length,i=o-1;++r<o;i=r)(t[r].z<=e.z&&e.z<t[i].z||t[i].z<=e.z&&e.z<t[r].z)&&e.x<(t[i].x-t[r].x)*(e.z-t[r].z)/(t[i].z-t[r].z)+t[r].x&&(n=!n);return n},r.isVectorInPolygon=function(t,e,n){var r=1e5,o=-1e5,i=[];return e.vertexIds.forEach(function(t){r=Math.min(n[t].y,r),o=Math.max(n[t].y,o),i.push(n[t])}),!!(t.y<o+.5&&t.y>r-.5&&this.isPointInPoly(i,t))},r.triarea2=function(t,e,n){return(n.x-t.x)*(e.z-t.z)-(e.x-t.x)*(n.z-t.z)},r.vequal=function(t,e){return this.distanceToSquared(t,e)<1e-5};var o=function(t){this.content=[],this.scoreFunction=t};o.prototype.push=function(t){this.content.push(t),this.sinkDown(this.content.length-1)},o.prototype.pop=function(){var t=this.content[0],e=this.content.pop();return this.content.length>0&&(this.content[0]=e,this.bubbleUp(0)),t},o.prototype.remove=function(t){var e=this.content.indexOf(t),n=this.content.pop();e!==this.content.length-1&&(this.content[e]=n,this.scoreFunction(n)<this.scoreFunction(t)?this.sinkDown(e):this.bubbleUp(e))},o.prototype.size=function(){return this.content.length},o.prototype.rescoreElement=function(t){this.sinkDown(this.content.indexOf(t))},o.prototype.sinkDown=function(t){for(var e=this.content[t];t>0;){var n=(t+1>>1)-1,r=this.content[n];if(!(this.scoreFunction(e)<this.scoreFunction(r)))break;this.content[n]=e,this.content[t]=r,t=n}},o.prototype.bubbleUp=function(t){for(var e=this.content.length,n=this.content[t],r=this.scoreFunction(n);;){var o=t+1<<1,i=o-1,s=null,a=void 0;if(i<e&&(a=this.scoreFunction(this.content[i]))<r&&(s=i),o<e&&this.scoreFunction(this.content[o])<(null===s?r:a)&&(s=o),null===s)break;this.content[t]=this.content[s],this.content[s]=n,t=s}};var i=function(){};i.init=function(t){for(var e=0;e<t.length;e++){var n=t[e];n.f=0,n.g=0,n.h=0,n.cost=1,n.visited=!1,n.closed=!1,n.parent=null}},i.cleanUp=function(t){for(var e=0;e<t.length;e++){var n=t[e];delete n.f,delete n.g,delete n.h,delete n.cost,delete n.visited,delete n.closed,delete n.parent}},i.heap=function(){return new o(function(t){return t.f})},i.search=function(t,e,n){this.init(t);var r=this.heap();for(r.push(e);r.size()>0;){var o=r.pop();if(o===n){for(var i=o,s=[];i.parent;)s.push(i),i=i.parent;return this.cleanUp(s),s.reverse()}o.closed=!0;for(var a=this.neighbours(t,o),u=0,h=a.length;u<h;u++){var c=a[u];if(!c.closed){var d=o.g+c.cost,f=c.visited;if(!f||d<c.g){if(c.visited=!0,c.parent=o,!c.centroid||!n.centroid)throw new Error("Unexpected state");c.h=c.h||this.heuristic(c.centroid,n.centroid),c.g=d,c.f=c.g+c.h,f?r.rescoreElement(c):r.push(c)}}}}return[]},i.heuristic=function(t,e){return r.distanceToSquared(t,e)},i.neighbours=function(t,e){for(var n=[],r=0;r<e.neighbours.length;r++)n.push(t[e.neighbours[r]]);return n};var s=1,a=function(){};a.buildZone=function(t){var e=this,n=this._buildNavigationMesh(t),o={};n.vertices.forEach(function(t){t.x=r.roundNumber(t.x,2),t.y=r.roundNumber(t.y,2),t.z=r.roundNumber(t.z,2)}),o.vertices=n.vertices;var i=this._buildPolygonGroups(n);o.groups=[];var s=function(t,e){for(var n=0;n<t.length;n++)if(e===t[n])return n};return i.forEach(function(t){var n=[];t.forEach(function(o){var i=o.neighbours.map(function(e){return s(t,e)}),a=o.neighbours.map(function(t){return e._getSharedVerticesInOrder(o,t)});o.centroid.x=r.roundNumber(o.centroid.x,2),o.centroid.y=r.roundNumber(o.centroid.y,2),o.centroid.z=r.roundNumber(o.centroid.z,2),n.push({id:s(t,o),neighbours:i,vertexIds:o.vertexIds,centroid:o.centroid,portals:a})}),o.groups.push(n)}),o},a._buildNavigationMesh=function(t){return r.computeCentroids(t),t.mergeVertices(),this._buildPolygonsFromGeometry(t)},a._buildPolygonGroups=function(t){var e=[],n=0,r=function(t){t.neighbours.forEach(function(e){void 0===e.group&&(e.group=t.group,r(e))})};return t.polygons.forEach(function(t){void 0===t.group&&(t.group=n++,r(t)),e[t.group]||(e[t.group]=[]),e[t.group].push(t)}),e},a._buildPolygonNeighbours=function(t,e,n){var r=new Set,o=n.get(t.vertexIds[0]),i=n.get(t.vertexIds[1]),s=n.get(t.vertexIds[2]);o.forEach(function(t){(i.has(t)||s.has(t))&&r.add(e.polygons[t])}),i.forEach(function(t){s.has(t)&&r.add(e.polygons[t])}),t.neighbours=Array.from(r)},a._buildPolygonsFromGeometry=function(t){for(var e=this,n=[],r=t.vertices,o=t.faceVertexUvs,i=new Map,a=0;a<r.length;a++)i.set(a,new Set);t.faces.forEach(function(t){n.push({id:s++,vertexIds:[t.a,t.b,t.c],centroid:t.centroid,normal:t.normal,neighbours:[]}),i.get(t.a).add(n.length-1),i.get(t.b).add(n.length-1),i.get(t.c).add(n.length-1)});var u={polygons:n,vertices:r,faceVertexUvs:o};return n.forEach(function(t){e._buildPolygonNeighbours(t,u,i)}),u},a._getSharedVerticesInOrder=function(t,e){var n=t.vertexIds,r=e.vertexIds,o=new Set;if(n.forEach(function(t){r.includes(t)&&o.add(t)}),o.size<2)return[];o.has(n[0])&&o.has(n[n.length-1])&&n.push(n.shift()),o.has(r[0])&&o.has(r[r.length-1])&&r.push(r.shift());var i=[];return n.forEach(function(t){r.includes(t)&&i.push(t)}),i};var u=function(){this.portals=[]};u.prototype.push=function(t,e){void 0===e&&(e=t),this.portals.push({left:t,right:e})},u.prototype.stringPull=function(){var t,e,n,o=this.portals,i=[],s=0,a=0,u=0;e=o[0].left,n=o[0].right,i.push(t=o[0].left);for(var h=1;h<o.length;h++){var c=o[h].left,d=o[h].right;if(r.triarea2(t,n,d)<=0){if(!(r.vequal(t,n)||r.triarea2(t,e,d)>0)){i.push(e),e=t=e,n=t,a=s=a,u=s,h=s;continue}n=d,u=h}if(r.triarea2(t,e,c)>=0){if(!(r.vequal(t,e)||r.triarea2(t,n,c)<0)){i.push(n),e=t=n,n=t,a=s=u,u=s,h=s;continue}e=c,a=h}}return 0!==i.length&&r.vequal(i[i.length-1],o[o.length-1].left)||i.push(o[o.length-1].left),this.path=i,i};var h,c,d,f,v,l,p=function(){this.zones={}};p.createZone=function(t){return a.buildZone(t)},p.prototype.setZoneData=function(t,e){this.zones[t]=e},p.prototype.getGroup=function(t,e){if(!this.zones[t])return null;var n=null,o=Math.pow(50,2);return this.zones[t].groups.forEach(function(t,i){t.forEach(function(t){var s=r.distanceToSquared(t.centroid,e);s<o&&(n=i,o=s)})}),n},p.prototype.getRandomNode=function(t,e,n,o){if(!this.zones[t])return new THREE.Vector3;n=n||null,o=o||0;var i=[];return this.zones[t].groups[e].forEach(function(t){n&&o?r.distanceToSquared(n,t.centroid)<o*o&&i.push(t.centroid):i.push(t.centroid)}),r.sample(i)||new THREE.Vector3},p.prototype.getClosestNode=function(t,e,n,o){void 0===o&&(o=!1);var i=this.zones[e].vertices,s=null,a=1/0;return this.zones[e].groups[n].forEach(function(e){var n=r.distanceToSquared(e.centroid,t);n<a&&(!o||r.isVectorInPolygon(t,e,i))&&(s=e,a=n)}),s},p.prototype.findPath=function(t,e,n,r){var o=this.zones[n].groups[r],s=this.zones[n].vertices,a=this.getClosestNode(t,n,r),h=this.getClosestNode(e,n,r,!0);if(!a||!h)return null;var c=i.search(o,a,h),d=function(t,e){for(var n=0;n<t.neighbours.length;n++)if(t.neighbours[n]===e.id)return t.portals[n]},f=new u;f.push(t);for(var v=0;v<c.length;v++){var l=c[v+1];if(l){var p=d(c[v],l);f.push(s[p[0]],s[p[1]])}}f.push(e),f.stringPull();var g=f.path.map(function(t){return new THREE.Vector3(t.x,t.y,t.z)});return g.shift(),g},p.prototype.clampStep=(d=new THREE.Vector3,f=new THREE.Plane,v=new THREE.Triangle,l=new THREE.Vector3,function(t,e,n,r,o,i){var s=this.zones[r].vertices,a=this.zones[r].groups[o],u=[n],p={};p[n.id]=0,h=void 0,l.set(0,0,0),c=1/0,f.setFromCoplanarPoints(s[n.vertexIds[0]],s[n.vertexIds[1]],s[n.vertexIds[2]]),f.projectPoint(e,d),e.copy(d);for(var g=u.pop();g;g=u.pop()){v.set(s[g.vertexIds[0]],s[g.vertexIds[1]],s[g.vertexIds[2]]),v.closestPointToPoint(e,d),d.distanceToSquared(e)<c&&(h=g,l.copy(d),c=d.distanceToSquared(e));var y=p[g];if(!(y>2))for(var x=0;x<g.neighbours.length;x++){var m=a[g.neighbours[x]];m.id in p||(u.push(m),p[m.id]=y+1)}}return i.copy(l),h}),n.Pathfinding=p},{}],3:[function(t,e,n){"use strict";t("./nav-mesh"),t("./nav-agent"),t("./system")},{"./nav-agent":4,"./nav-mesh":5,"./system":6}],4:[function(t,e,n){"use strict";e.exports=AFRAME.registerComponent("nav-agent",{schema:{destination:{type:"vec3"},active:{default:!1},speed:{default:2}},init:function(){this.system=this.el.sceneEl.systems.nav,this.system.addAgent(this),this.group=null,this.path=[],this.raycaster=new THREE.Raycaster},remove:function(){this.system.removeAgent(this)},update:function(){this.path.length=0},updateNavLocation:function(){this.group=null,this.path=[]},tick:function(){var t=new THREE.Vector3,e=new THREE.Vector3,n=new THREE.Vector3;return function(r,o){var i=this.el,s=this.data,a=this.raycaster,u=s.speed*o/1e3;if(s.active){if(!this.path.length){var h=this.el.object3D.position;this.group=this.group||this.system.getGroup(h),this.path=this.system.getPath(h,t.copy(s.destination),this.group)||[],i.emit("nav-start")}if(!this.path.length)return console.warn("[nav] Unable to find path to %o.",s.destination),this.el.setAttribute("nav-agent",{active:!1}),void i.emit("nav-end");var c=i.object3D.position,d=this.path[0];e.subVectors(d,c);var f=void 0;if(e.length()<u){if(this.path.shift(),!this.path.length)return this.el.setAttribute("nav-agent",{active:!1}),void i.emit("nav-end");n.copy(c),f=this.path[0]}else n.copy(e.setLength(u)).add(c),f=d;f.y=c.y,i.object3D.lookAt(f),a.ray.origin.copy(n),a.ray.origin.y+=1.5,a.ray.direction.y=-1;var v=a.intersectObject(this.system.getNavMesh());v.length?(e.subVectors(v[0].point,c),c.add(e.setLength(u))):c.copy(n)}}}()})},{}],5:[function(t,e,n){"use strict";e.exports=AFRAME.registerComponent("nav-mesh",{init:function(){this.system=this.el.sceneEl.systems.nav,this.hasLoadedNavMesh=!1,this.el.addEventListener("model-loaded",this.loadNavMesh.bind(this))},play:function(){this.hasLoadedNavMesh||this.loadNavMesh()},loadNavMesh:function(){var t=this.el.getObject3D("mesh"),e=this.el.sceneEl.object3D;if(t){var n=void 0;if(t.traverse(function(t){t.isMesh&&(n=t)}),n){var r=n.geometry.isBufferGeometry?(new THREE.Geometry).fromBufferGeometry(n.geometry):n.geometry.clone();e.updateMatrixWorld(),r.applyMatrix(n.matrixWorld),this.system.setNavMeshGeometry(r),this.hasLoadedNavMesh=!0}}}})},{}],6:[function(t,e,n){"use strict";var r=t("three-pathfinding").Pathfinding,o=new r,i="level";e.exports=AFRAME.registerSystem("nav",{init:function(){this.navMesh=null,this.agents=new Set},setNavMeshGeometry:function(t){this.navMesh=new THREE.Mesh(t),o.setZoneData(i,r.createZone(t)),Array.from(this.agents).forEach(function(t){return t.updateNavLocation()})},getNavMesh:function(){return this.navMesh},addAgent:function(t){this.agents.add(t)},removeAgent:function(t){this.agents.delete(t)},getPath:function(t,e,n){return this.navMesh?o.findPath(t,e,i,n):null},getGroup:function(t){return this.navMesh?o.getGroup(i,t):null},getNode:function(t,e){return this.navMesh?o.getClosestNode(t,i,e,!0):null},clampStep:function(t,e,n,r,s){return this.navMesh?r?o.clampStep(t,e,r,i,n,s):(s.copy(e),this.getNode(e,n)):(s.copy(e),null)}})},{"three-pathfinding":2}]},{},[1]);