UNPKG

babylon-steering

Version:
3 lines (2 loc) 11.9 kB
import{Vector3 as e,Tools as i,Color3 as t,Ray as s}from"babylonjs";var o={avoid:10,queue:9,separation:7,flock:6,flee:6,seek:5,idle:0},n={avoid:.66,queue:.66,separation:.66,flock:.66,flee:.66,seek:.66,idle:.66},h=function(i,t,s){void 0===s&&(s={}),this.engine=t,this.mesh=i,this.mesh.checkCollisions=!0,this.steeringForce=new e(0,0,0),this.maxForce=s.maxForce||1,this.velocity=new e(0,0,0),this.forces=[],this.maxSpeed=s.maxSpeed||.2,this.mass=s.mass||1,this.velocitySamples=[],this.numSamplesForSmoothing=s.numSamplesForSmoothing||20,this.arrivalThreshold=s.arrivalThreshold||100,this.avoidDistance=s.avoidDistance||120,this.radius=s.radius||100,this.waypoints=[],this.pathIndex=0,this.wanderDistance=s.wanderDistance||10,this.wanderAngle=s.wanderAngle||10,this.wanderRadius=s.wanderRadius||5,this.wanderRange=s.wanderRange||20,this.inSightDistance=s.inSightDistance||200,this.tooCloseDistance=s.tooCloseDistance||60},a={dt:{configurable:!0}};a.dt.get=function(){return this.engine.getDeltaTime()},a.dt.set=function(e){this.dt=e},h.prototype.idle=function(e,i){void 0===i&&(i={}),this.velocity.scaleInPlace(0),this.steeringForce.setAll(0,0,0),this.forces.push(Object.assign(i,{force:this.steeringForce,name:this.idle.name}))},h.prototype.lookTarget=function(e){return this.mesh.lookAt(e.mesh.position),this},h.prototype.lookWhereGoing=function(e){var i=this.mesh.position.clone().add(this.velocity);if(i.y=this.mesh.position.y,e){this.velocitySamples.length==this.numSamplesForSmoothing&&this.velocitySamples.shift();var t=this.velocity.clone();t.y=this.mesh.position.y,this.velocitySamples.push(t),i.setAll(0,0,0);for(var s=0;s<this.velocitySamples.length;s++)i.addInPlace(this.velocitySamples[s]);i.scaleInPlace(1/this.velocitySamples.length),(i=this.mesh.position.clone().add(i)).y=this.mesh.position.y}return this.mesh.lookAt(i),this},h.prototype.inSight=function(i){if(e.Distance(this.mesh.position,i.mesh.position)>this.inSightDistance)return!1;var t=i.velocity.clone().normalize().scaleInPlace(1),s=i.mesh.position.clone().subtract(this.mesh.position.clone());return!(e.Dot(s,t)<0)},h.prototype.hasInConeOfView=function(s){for(var o=0;o<s.length;o++){var n=s[o],h=n.mesh.position.clone(),a=this.mesh.position.clone(),r=e.Distance(h,a),c=this.velocity.clone().normalize(),l=n.mesh.position.clone().subtract(this.mesh.position.clone());l.normalize();var p=e.Dot(c,l),m=Math.acos(p),d=i.ToDegrees(m);n.mesh.material.emissiveColor=r<170&&d<60?new t(1,.5,0):n.mesh.color}return this},h.prototype.isInConeOfViewOf=function(s){var o=s.mesh.position.clone(),n=this.mesh.position.clone(),h=e.Distance(o,n),a=s.velocity.clone().normalize(),r=this.mesh.position.clone().subtract(s.mesh.position.clone());r.normalize();var c=e.Dot(a,r),l=Math.acos(c),p=i.ToDegrees(l);return this.mesh.material.emissiveColor=h<170&&p<60?new t(1,.5,0):new t(0,0,1),this},h.prototype.truncate=function(e,i){var t=i/e.length();return e.scaleInPlace(t<1?t:1)},h.prototype.update=function(){this.steeringForce=this.truncate(this.steeringForce,this.maxForce),this.steeringForce.scaleInPlace(1/this.mass),this.velocity.addInPlace(this.steeringForce),this.velocity=this.truncate(this.velocity,this.maxSpeed*this.dt),this.velocity.y=0,this.steeringForce.setAll(0,0,0),this.mesh.moveWithCollisions(this.velocity),this.forces=[]},h.prototype.applyForce=function(e,i){return void 0===i&&(i={}),this.forces.push(Object.assign(i,{force:e,name:this.applyForce.name})),this},h.prototype.attract=function(i,t,s,o){void 0===t&&(t=0),void 0===s&&(s=1),void 0===o&&(o={});var n=e.Distance(this.mesh.position,i.mesh.position);if(n<t&&n>20){var h={force:this.mesh.position.clone().subtract(i.mesh.position.clone()).normalize().scaleInPlace(this.maxSpeed*this.dt*s).subtractInPlace(i.velocity),name:this.attract.name};i.forces.push(Object.assign(o,h))}else i.flee(this);return this},h.prototype.seek=function(i,t,s){if(void 0===t&&(t=0),void 0===s&&(s={}),e.Distance(this.mesh.position,i.mesh.position)>t){var o={force:i.mesh.position.clone().subtract(this.mesh.position.clone()).normalize().scaleInPlace(this.maxSpeed*this.dt).subtractInPlace(this.velocity),name:this.seek.name};this.forces.push(Object.assign(s,o))}else this.idle(i,s);return this},h.prototype.seekWithArrive=function(i,t,s){void 0===s&&(s={});var o=i.mesh.position.clone().subtract(this.mesh.position.clone());o.normalize();var n=e.Distance(i.mesh.position,this.mesh.position);n>this.arrivalThreshold?o.scaleInPlace(this.maxSpeed*this.dt):n>t&&n<this.arrivalThreshold?o.scaleInPlace(this.maxSpeed*this.dt*(n-t)/(this.arrivalThreshold-t)):this.idle(i,s);var h={force:o.subtractInPlace(this.velocity),name:this.seekWithArrive.name};return this.forces.push(Object.assign(s,h)),this},h.prototype.flee=function(i,t,s){if(void 0===t&&(t=0),void 0===s&&(s={}),e.Distance(this.mesh.position,i.mesh.position)<t){var o={force:this.mesh.position.clone().subtract(i.mesh.position.clone()).normalize().scaleInPlace(this.maxSpeed*this.dt).subtractInPlace(this.velocity),name:this.flee.name};this.forces.push(Object.assign(s,o))}else this.idle(i,s);return this},h.prototype.arrive=function(i,t){void 0===t&&(t={});var s=i.mesh.position.clone().subtract(this.mesh.position.clone());s.normalize();var o=e.Distance(i.mesh.position,this.mesh.position);s.scaleInPlace(o>this.arrivalThreshold?this.maxSpeed*this.dt:this.maxSpeed*this.dt*o/this.arrivalThreshold);var n={force:s.subtractInPlace(this.velocity),name:this.flee.name};return this.forces.push(Object.assign(t,n)),this},h.prototype.pursue=function(i,t){void 0===t&&(t=0);var s=e.Distance(this.mesh.position,i.mesh.position)/(this.maxSpeed*this.dt),o=i.mesh.position.clone().add(i.velocity.clone().scaleInPlace(s));this.seek({mesh:{position:o}},t)},h.prototype.evade=function(i,t){void 0===t&&(t=0);var s=e.Distance(this.mesh.position,i.mesh.position)/(this.maxSpeed*this.dt),o=i.mesh.position.clone().subtract(i.velocity.clone().scaleInPlace(s));this.flee({mesh:{position:o}},t)},h.prototype.canSee=function(i){var t=i.mesh.position.clone().subtract(this.mesh.position).normalize(),o=e.Lerp(i.mesh.position.clone(),this.mesh.position.clone(),.66),n=new s(o,t,350),h=i.mesh.getScene().pickWithRay(n);return!(!h.pickedMesh||h.pickedMesh.uniqueId!==i.mesh.uniqueId)},h.prototype.hide=function(i,t,s){if(void 0===s&&(s=250),this.canSee(i)){this.lookTarget(i);for(var o=new e(0,0,0),n=1e4,h=0;h<t.length;h++){var a=t[h],r=e.Distance(this.mesh.position,a.mesh.position);r<n&&(o=a.mesh.position.clone(),n=r)}var c=e.Distance(this.mesh.position,i.mesh.position),l=e.Lerp(i.mesh.position.clone(),o.clone(),2);l.y=this.mesh.position.y,c<s?this.seek({mesh:{position:l}},10):this.flee(i)}else this.lookWhereGoing(!0),this.idle();return this},h.prototype.wander=function(i){void 0===i&&(i={});var t=this.velocity.clone().normalize().scaleInPlace(this.wanderDistance),s=new e(1,1,1).scaleInPlace(this.wanderRadius);return s.x=Math.sin(this.wanderAngle)*s.length(),s.z=-Math.cos(this.wanderAngle)*s.length(),s.y=0,this.wanderAngle=Math.random()*this.wanderRange-.5*this.wanderRange,t.addInPlace(s),t.y=this.mesh.position.y,this.forces.push(Object.assign(i,{force:t,name:this.wander.name})),this},h.prototype.separation=function(i,t,s,o){void 0===t&&(t=50),void 0===s&&(s=40),void 0===o&&(o={});for(var n=new e(0,0,0),h=0,a=0;a<i.length;a++)i[a]!=this&&e.Distance(this.mesh.position,i[a].mesh.position)<=t&&(n.addInPlace(i[a].mesh.position.clone().subtractInPlace(this.mesh.position)),h++);return 0!=h&&(n.scaleInPlace(1/h),n.negateInPlace()),n.normalize().scaleInPlace(s),this.forces.push(Object.assign(o,{force:n,name:this.separation.name})),this},h.prototype.interpose=function(i,t){var s=i.mesh.position.clone().addInPlace(t.mesh.position.clone()).scaleInPlace(.5),o=e.Distance(this.mesh.position,s)/(this.maxSpeed*this.dt),n=i.mesh.position.clone().addInPlace(i.velocity.clone().scaleInPlace(o)),h=t.mesh.position.clone().addInPlace(t.velocity.clone().scaleInPlace(o));s=n.addInPlace(h).scaleInPlace(.5),this.seek({mesh:{position:s}},10)},h.prototype.avoid=function(i,t){void 0===t&&(t={});for(var s=this.velocity.length()/(this.maxSpeed*this.dt),o=this.mesh.position.clone().addInPlace(this.velocity.clone().normalize().scaleInPlace(s)),n=this.mesh.position.clone().addInPlace(this.velocity.clone().normalize().scaleInPlace(.5*this.avoidDistance)),h=null,a=0;a<i.length;a++)i[a]!==this&&(e.Distance(i[a].mesh.position,o)<=this.radius||e.Distance(i[a].mesh.position,n)<=this.radius)&&(null==h||e.Distance(this.mesh.position,i[a].mesh.position)<e.Distance(this.mesh.position,h.mesh.position))&&(h=i[a]);var r=new e(0,0,0);return null!=h?r=o.clone().subtractInPlace(h.mesh.position.clone()).normalize().scaleInPlace(this.maxSpeed*this.dt*.75):r.scaleInPlace(0),this.forces.push(Object.assign(t,{force:r,name:this.avoid.name})),this},h.prototype.followPath=function(i,t,s){void 0===s&&(s=10);var o=i[this.pathIndex];null!=o&&(e.Distance(this.mesh.position,o)<s&&(this.pathIndex>=i.length-1?t&&(this.pathIndex=0):this.pathIndex++),this.pathIndex>=i.length-1&&!t?this.arrive({mesh:{position:o}}):this.seek({mesh:{position:o}}))},h.prototype.isOnLeaderSight=function(i,t,s){return e.Distance(t,this.mesh.position)<=s||e.Distance(i.mesh.position,this.mesh.position)<=s},h.prototype.followLeader=function(e,i,t,s,o,n,h){void 0===t&&(t=20),void 0===s&&(s=40),void 0===o&&(o=10),void 0===n&&(n=50),void 0===h&&(h=100);var a=e.velocity.clone();a.normalize().scaleInPlace(t);var r=e.mesh.position.clone().add(a);a.negateInPlace();var c=e.mesh.position.clone().add(a);return this.isOnLeaderSight(e,r,n)&&this.flee(e),this.arrivalThreshold=h,this.arrive({mesh:{position:c}}),this.separation(i,s,o),this},h.prototype.getNeighborAhead=function(i){for(var t,s=this.velocity.clone().normalize().scaleInPlace(100),o=this.mesh.position.clone().add(s),n=0;n<i.length;n++){var h=e.Distance(o,i[n].mesh.position);if(i[n]!=this&&h<=100){t=i[n];break}}return t},h.prototype.queue=function(i,t,s){void 0===t&&(t=50),void 0===s&&(s={});var o=this.getNeighborAhead(i),n=new e(0,0,0),h=this.velocity.clone();return null!=o&&(n=this.steeringForce.clone().negateInPlace().scaleInPlace(.8),h.negateInPlace().normalize(),n.add(h),e.Distance(this.mesh.position,o.mesh.position)<=t&&this.velocity.scaleInPlace(.3)),this.forces.push(Object.assign(s,{force:n,name:this.queue.name})),this},h.prototype.flock=function(i,t){void 0===t&&(t={});for(var s=this.velocity.clone(),o=new e(0,0,0),n=0,h=0;h<i.length;h++)i[h]!=this&&this.inSight(i[h])&&(s.add(i[h].velocity),o.add(i[h].mesh.position),e.Distance(this.mesh.position,i[h].mesh.position)<this.tooCloseDistance&&this.flee(i[h]),n++);if(n>0){s.scaleInPlace(1/n),o.scaleInPlace(1/n),this.seek({mesh:{position:o}});var a={force:s.subtractInPlace(this.velocity),name:this.flock.name};this.forces.push(Object.assign(t,a))}return this},h.prototype.sortByPriority=function(e){return e.sort(function(e,i){return(i.priority||o[i.name])-(e.priority||o[e.name])})},h.prototype.animate=function(i){var t=this;if("blend"===i)this.forces.forEach(function(e){t.steeringForce=t.steeringForce.add(e.force).scaleInPlace(e.weigth||.5)});else if("priority"===i)this.forces=this.sortByPriority(this.forces),this.steeringForce=this.steeringForce.add(this.forces[0].force);else if("probability"===i){var s=new e(0,0,0);this.forces=this.sortByPriority(this.forces);for(var o=0;o<this.forces.length;o++){var h=this.forces[o];if((h.probability||n[h.name])>Math.random()){s=h.force;break}}this.steeringForce=this.steeringForce.add(s)}else if("truncated"===i){this.forces=this.sortByPriority(this.forces);for(var a=0;a<this.forces.length;a++){var r=this.forces[a];if(this.steeringForce=this.steeringForce.add(r.force).scaleInPlace(r.weigth||.5),this.steeringForce.length()>.005)break}}else this.forces.forEach(function(e){t.steeringForce=t.steeringForce.add(e.force)});this.update()},Object.defineProperties(h.prototype,a);export default h; //# sourceMappingURL=index.mjs.map