babylon-steering
Version:
Steering behaviours library for Babylon.js
1 lines • 39.4 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/index.js"],"sourcesContent":["import * as BABYLON from 'babylonjs';\r\n\r\nconst defaultPriorities = {\r\n avoid: 10,\r\n queue: 9,\r\n separation: 7,\r\n flock: 6,\r\n flee: 6,\r\n seek: 5,\r\n idle: 0\r\n};\r\n\r\nconst defaultProbabilities = {\r\n avoid: 0.66,\r\n queue: 0.66,\r\n separation: 0.66,\r\n flock: 0.66,\r\n flee: 0.66,\r\n seek: 0.66,\r\n idle: 0.66\r\n};\r\n\r\nexport default class SteeringVehicle {\r\n\r\n constructor(mesh, engine, options = {}) {\r\n\r\n this.engine = engine;\r\n this.mesh = mesh;\r\n this.mesh.checkCollisions = true;\r\n this.steeringForce = new BABYLON.Vector3(0, 0, 0);\r\n this.maxForce = options.maxForce || 1;\r\n this.velocity = new BABYLON.Vector3(0, 0, 0);\r\n this.forces = [];\r\n\r\n this.maxSpeed = options.maxSpeed || 0.2;\r\n this.mass = options.mass || 1;\r\n\r\n this.velocitySamples = [];\r\n this.numSamplesForSmoothing = options.numSamplesForSmoothing || 20;\r\n\r\n // ARRIVAL\r\n this.arrivalThreshold = options.arrivalThreshold || 100;\r\n\r\n // AVOID\r\n this.avoidDistance = options.avoidDistance || 120;\r\n this.radius = options.radius || 100;\r\n\r\n // FOLLOWPATH\r\n this.waypoints = [];\r\n this.pathIndex = 0;\r\n\r\n // WANDER\r\n this.wanderDistance = options.wanderDistance || 10;\r\n this.wanderAngle = options.wanderAngle || 10;\r\n this.wanderRadius = options.wanderRadius || 5;\r\n this.wanderRange = options.wanderRange || 20;\r\n\r\n // QUEUE\r\n this.inSightDistance = options.inSightDistance || 200;\r\n this.tooCloseDistance = options.tooCloseDistance || 60;\r\n }\r\n\r\n get dt() {\r\n return this.engine.getDeltaTime();\r\n }\r\n\r\n set dt(what) {\r\n this.dt = what;\r\n }\r\n\r\n idle(target, configuration = {}) {\r\n this.velocity.scaleInPlace(0);\r\n this.steeringForce.setAll(0, 0, 0);\r\n let action = { force: this.steeringForce, name: this.idle.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n }\r\n\r\n lookTarget(target) {\r\n this.mesh.lookAt(target.mesh.position); // native function\r\n return this;\r\n }\r\n\r\n lookWhereGoing(smoothing) {\r\n var direction = this.mesh.position.clone().add(this.velocity); // si punta alla somma della velocità e della posizione\r\n direction.y = this.mesh.position.y;\r\n if (smoothing) {\r\n if (this.velocitySamples.length == this.numSamplesForSmoothing) {\r\n this.velocitySamples.shift();\r\n }\r\n let c = this.velocity.clone();\r\n c.y = this.mesh.position.y\r\n this.velocitySamples.push(c);\r\n direction.setAll(0, 0, 0);\r\n for (var v = 0; v < this.velocitySamples.length; v++) {\r\n direction.addInPlace(this.velocitySamples[v])\r\n }\r\n direction.scaleInPlace(1 / this.velocitySamples.length)\r\n direction = this.mesh.position.clone().add(direction)\r\n direction.y = this.mesh.position.y;\r\n }\r\n this.mesh.lookAt(direction);\r\n return this;\r\n }\r\n\r\n // se è sullo stesso lato ma non che è visibile...\r\n // TEST: vedere se new BABYLON.Vector3(0, 0, 1) funziona meglio\r\n inSight(target) {\r\n if (BABYLON.Vector3.Distance(this.mesh.position, target.mesh.position) > this.inSightDistance) {\r\n return false;\r\n }\r\n var heading = /* new BABYLON.Vector3(0, 0, 1); // */target.velocity.clone().normalize().scaleInPlace(1);\r\n var difference = target.mesh.position.clone().subtract(this.mesh.position.clone());\r\n var dot = BABYLON.Vector3.Dot(difference, heading);\r\n // console.log(`Dot:${dot}`)\r\n return dot < 0 ? false : true;\r\n }\r\n\r\n // ACTIVE\r\n hasInConeOfView(targets) {\r\n for (let i = 0; i < targets.length; i++) {\r\n const target = targets[i];\r\n\r\n let targetPos = target.mesh.position.clone();\r\n let actorPos = this.mesh.position.clone();\r\n let distance = BABYLON.Vector3.Distance(targetPos, actorPos);\r\n\r\n let v0 = this.velocity.clone().normalize();\r\n let v1 = target.mesh.position.clone().subtract(this.mesh.position.clone());\r\n v1.normalize();\r\n let dot = BABYLON.Vector3.Dot(v0, v1)\r\n let angle = Math.acos(dot);\r\n let angleInDegree = BABYLON.Tools.ToDegrees(angle);\r\n // console.log(`Distance: ${distance}`, `Degree: ${angleInDegree}, Dot:${dot}`);\r\n if (distance < 170 && (angleInDegree < 60)) {\r\n target.mesh.material.emissiveColor = new BABYLON.Color3(1, 0.5, 0);\r\n } else {\r\n target.mesh.material.emissiveColor = target.mesh.color; // TODO: \r\n }\r\n }\r\n return this;\r\n }\r\n\r\n // https://forum.babylonjs.com/t/rotation-angle-of-camera-to-object/2603/21\r\n // PASSIVA\r\n isInConeOfViewOf(target) {\r\n\r\n let targetPos = target.mesh.position.clone();\r\n let actorPos = this.mesh.position.clone();\r\n let distance = BABYLON.Vector3.Distance(targetPos, actorPos);\r\n\r\n /* var v0 = new BABYLON.Vector3(0, 0, 1);\r\n v0 = this.vecToLocal(v0, target);\r\n v0.normalize(); */\r\n\r\n let v0 = target.velocity.clone().normalize(); // new BABYLON.Vector3(0, 0, 1);\r\n // var ray = new BABYLON.Ray(target.mesh.position, v0, 100);\r\n // let rayHelper = new BABYLON.RayHelper(ray);\r\n // rayHelper.show(this.mesh.getScene());\r\n\r\n let v1 = this.mesh.position.clone().subtract(target.mesh.position.clone());\r\n // var ray2 = new BABYLON.Ray(target.mesh.position, v1, 100);\r\n // let rayHelper2 = new BABYLON.RayHelper(ray2);\r\n // rayHelper2.show(this.mesh.getScene());\r\n v1.normalize();\r\n\r\n let dot = BABYLON.Vector3.Dot(v0, v1)\r\n let angle = Math.acos(dot);\r\n let angleInDegree = BABYLON.Tools.ToDegrees(angle);\r\n // console.log(`Distance: ${distance}`, `Degree: ${angleInDegree}, Dot:${dot}`);\r\n if (distance < 170 && (angleInDegree < 60)) {\r\n this.mesh.material.emissiveColor = new BABYLON.Color3(1, 0.5, 0);\r\n } else {\r\n this.mesh.material.emissiveColor = new BABYLON.Color3(0, 0, 1);\r\n }\r\n return this;\r\n }\r\n\r\n // TODO: convert Three.js clampLength method to BABYLON\r\n truncate(vector, max) {\r\n let i = max / vector.length();\r\n return vector.scaleInPlace(i < 1.0 ? i : 1.0);\r\n }\r\n\r\n // si aggiorna in base a sistema di riferimento GLOBALE\r\n update() {\r\n this.steeringForce = this.truncate(this.steeringForce, this.maxForce);\r\n this.steeringForce.scaleInPlace(1 / this.mass);\r\n this.velocity.addInPlace(this.steeringForce);\r\n this.velocity = this.truncate(this.velocity, this.maxSpeed* this.dt);\r\n this.velocity.y = 0;\r\n this.steeringForce.setAll(0, 0, 0);\r\n this.mesh.moveWithCollisions(this.velocity);\r\n this.forces = [];\r\n }\r\n\r\n // forza generica...(ES: wind...)\r\n applyForce(force, configuration = {}) {\r\n let action = { force: force, name: this.applyForce.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n return this;\r\n }\r\n\r\n // seek with a specific strength\r\n // PASSIVE\r\n attract(target, threshold = 0, strenght = 1, configuration = {}) {\r\n let distance = BABYLON.Vector3.Distance(this.mesh.position, target.mesh.position);\r\n if (distance < threshold && distance > 20) {\r\n var desiredVelocity = (this.mesh.position.clone().subtract(target.mesh.position.clone())).normalize().scaleInPlace(this.maxSpeed * this.dt * strenght);\r\n let action = { force: desiredVelocity.subtractInPlace(target.velocity), name: this.attract.name };\r\n target.forces.push(Object.assign(configuration, action));\r\n } else {\r\n // senza di questo oscilla...\r\n target.flee(this);\r\n }\r\n return this;\r\n }\r\n\r\n seek(target, threshold = 0, configuration = {}) {\r\n let distance = BABYLON.Vector3.Distance(this.mesh.position, target.mesh.position);\r\n if (distance > threshold) {\r\n var desiredVelocity = (target.mesh.position.clone().subtract(this.mesh.position.clone())).normalize().scaleInPlace(this.maxSpeed * this.dt);\r\n let action = { force: desiredVelocity.subtractInPlace(this.velocity), name: this.seek.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n } else {\r\n this.idle(target, configuration);\r\n }\r\n return this;\r\n }\r\n\r\n seekWithArrive(target, threshold, configuration = {}) {\r\n var desiredVelocity = target.mesh.position.clone().subtract(this.mesh.position.clone());\r\n desiredVelocity.normalize()\r\n var distance = BABYLON.Vector3.Distance(target.mesh.position, this.mesh.position);\r\n // si procede normalmente\r\n if (distance > this.arrivalThreshold) {\r\n desiredVelocity.scaleInPlace(this.maxSpeed * this.dt);\r\n // si decellera\r\n } else if (distance > threshold && distance < this.arrivalThreshold) {\r\n desiredVelocity.scaleInPlace(this.maxSpeed * this.dt * (distance - threshold) / (this.arrivalThreshold - threshold))\r\n // ci si ferma\r\n } else {\r\n this.idle(target, configuration);\r\n }\r\n let action = { force: desiredVelocity.subtractInPlace(this.velocity), name: this.seekWithArrive.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n return this;\r\n }\r\n\r\n flee(target, threshold = 0, configuration = {}) {\r\n let distance = BABYLON.Vector3.Distance(this.mesh.position, target.mesh.position);\r\n if (distance < threshold) {\r\n var desiredVelocity = (this.mesh.position.clone().subtract(target.mesh.position.clone())).normalize().scaleInPlace(this.maxSpeed * this.dt);\r\n let action = { force: desiredVelocity.subtractInPlace(this.velocity), name: this.flee.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n } else {\r\n this.idle(target, configuration);\r\n }\r\n return this;\r\n }\r\n\r\n arrive(target, configuration = {}) {\r\n var desiredVelocity = target.mesh.position.clone().subtract(this.mesh.position.clone());\r\n desiredVelocity.normalize()\r\n var distance = BABYLON.Vector3.Distance(target.mesh.position, this.mesh.position)\r\n if (distance > this.arrivalThreshold) {\r\n desiredVelocity.scaleInPlace(this.maxSpeed * this.dt);\r\n } else {\r\n desiredVelocity.scaleInPlace(this.maxSpeed * this.dt * distance / this.arrivalThreshold)\r\n }\r\n let action = { force: desiredVelocity.subtractInPlace(this.velocity), name: this.flee.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n return this;\r\n }\r\n\r\n pursue(target, threshold = 0) {\r\n var lookAheadTime = BABYLON.Vector3.Distance(this.mesh.position, target.mesh.position) / (this.maxSpeed * this.dt);\r\n var predictedTarget = target.mesh.position.clone().add(target.velocity.clone().scaleInPlace(lookAheadTime));\r\n this.seek({\r\n mesh: {\r\n position: predictedTarget\r\n }\r\n }, threshold);\r\n }\r\n\r\n evade(target, threshold = 0) {\r\n var lookAheadTime = BABYLON.Vector3.Distance(this.mesh.position, target.mesh.position) / (this.maxSpeed * this.dt);\r\n var predictedTarget = target.mesh.position.clone().subtract(target.velocity.clone().scaleInPlace(lookAheadTime));\r\n this.flee({\r\n mesh: {\r\n position: predictedTarget\r\n }\r\n }, threshold);\r\n }\r\n\r\n // tramite un ray casting si vede se il target è visibile (non ci stanno ostacoli che lo nascondono)\r\n canSee(target) {\r\n var forward = target.mesh.position.clone();\r\n var direction = forward.subtract(this.mesh.position).normalize();\r\n var length = 350;\r\n let start = BABYLON.Vector3.Lerp(target.mesh.position.clone(), this.mesh.position.clone(), 0.66);\r\n var ray = new BABYLON.Ray(start, direction, length);\r\n // let rayHelper = new BABYLON.RayHelper(ray);\r\n // rayHelper.show(this.mesh.getScene());\r\n var hit = target.mesh.getScene().pickWithRay(ray);\r\n let output = hit.pickedMesh && hit.pickedMesh.uniqueId === target.mesh.uniqueId ? true : false;\r\n // console.log('Can see: ', output);\r\n return output;\r\n }\r\n\r\n hide(target, obstacles, threshold = 250) {\r\n if (this.canSee(target)) {\r\n this.lookTarget(target);\r\n // si sceglie l'ostacolo più vicino all'elemento da nascondere\r\n let closestObstacle = new BABYLON.Vector3(0, 0, 0);\r\n let closestDistance = 10000;\r\n for (let i = 0; i < obstacles.length; i++) {\r\n const obstacle = obstacles[i];\r\n let distance = BABYLON.Vector3.Distance(this.mesh.position, obstacle.mesh.position);\r\n if (distance < closestDistance) {\r\n closestObstacle = obstacle.mesh.position.clone();\r\n closestDistance = distance;\r\n }\r\n }\r\n // si calcola il punto dove si andrà a nasconderci\r\n let distanceWithTarget = BABYLON.Vector3.Distance(this.mesh.position, target.mesh.position);\r\n var pointToReach = BABYLON.Vector3.Lerp(target.mesh.position.clone(), closestObstacle.clone(), 2);\r\n pointToReach.y = this.mesh.position.y;\r\n // ci si nasconde solo se il target non è troppo lontano\r\n if (distanceWithTarget < threshold) {\r\n this.seek({\r\n mesh: {\r\n position: pointToReach\r\n }\r\n }, 10);\r\n } else {\r\n this.flee(target)\r\n }\r\n } else {\r\n this.lookWhereGoing(true);\r\n this.idle();\r\n }\r\n return this;\r\n }\r\n\r\n // FIXME: NOT WORKING PROPERLY ???\r\n wander(configuration = {}) {\r\n var center = this.velocity.clone().normalize().scaleInPlace(this.wanderDistance);\r\n var offset = new BABYLON.Vector3(1, 1, 1).scaleInPlace(this.wanderRadius);\r\n offset.x = Math.sin(this.wanderAngle) * offset.length();\r\n offset.z = - Math.cos(this.wanderAngle) * offset.length();\r\n offset.y = 0;\r\n this.wanderAngle = Math.random() * this.wanderRange - this.wanderRange * .5;\r\n center.addInPlace(offset);\r\n center.y = this.mesh.position.y;\r\n let action = { force: center, name: this.wander.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n return this;\r\n }\r\n\r\n separation(entities, separationRadius = 50, maxSeparation = 40, configuration = {}) {\r\n var force = new BABYLON.Vector3(0, 0, 0);\r\n var neighborCount = 0\r\n for (var i = 0; i < entities.length; i++) {\r\n if (entities[i] != this && BABYLON.Vector3.Distance(this.mesh.position, entities[i].mesh.position) <= separationRadius) {\r\n force.addInPlace(entities[i].mesh.position.clone().subtractInPlace(this.mesh.position));\r\n neighborCount++;\r\n }\r\n }\r\n if (neighborCount != 0) {\r\n force.scaleInPlace(1 / neighborCount)\r\n force.negateInPlace();\r\n }\r\n force.normalize().scaleInPlace(maxSeparation);\r\n let action = { force: force, name: this.separation.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n return this;\r\n }\r\n\r\n interpose(targetA, targetB) {\r\n var midPoint = targetA.mesh.position.clone().addInPlace(targetB.mesh.position.clone()).scaleInPlace(.5);\r\n var timeToMidPoint = BABYLON.Vector3.Distance(this.mesh.position, midPoint) / (this.maxSpeed * this.dt);\r\n var pointA = targetA.mesh.position.clone().addInPlace(targetA.velocity.clone().scaleInPlace(timeToMidPoint))\r\n var pointB = targetB.mesh.position.clone().addInPlace(targetB.velocity.clone().scaleInPlace(timeToMidPoint))\r\n midPoint = pointA.addInPlace(pointB).scaleInPlace(.5);\r\n this.seek({\r\n mesh: {\r\n position: midPoint\r\n }\r\n }, 10);\r\n }\r\n\r\n avoid(obstacles, configuration = {}) {\r\n var dynamic_length = this.velocity.length() / (this.maxSpeed * this.dt);\r\n var ahead = this.mesh.position.clone().addInPlace(this.velocity.clone().normalize().scaleInPlace(dynamic_length))\r\n var ahead2 = this.mesh.position.clone().addInPlace(this.velocity.clone().normalize().scaleInPlace(this.avoidDistance * .5));\r\n var mostThreatening = null;\r\n for (var i = 0; i < obstacles.length; i++) {\r\n if (obstacles[i] === this)\r\n continue;\r\n var collision = BABYLON.Vector3.Distance(obstacles[i].mesh.position, ahead) <= this.radius || BABYLON.Vector3.Distance(obstacles[i].mesh.position, ahead2) <= this.radius;\r\n if (collision && (mostThreatening == null || BABYLON.Vector3.Distance(this.mesh.position, obstacles[i].mesh.position) < BABYLON.Vector3.Distance(this.mesh.position, mostThreatening.mesh.position))) {\r\n mostThreatening = obstacles[i];\r\n }\r\n }\r\n var avoidance = new BABYLON.Vector3(0, 0, 0);\r\n if (mostThreatening != null) {\r\n avoidance = ahead.clone().subtractInPlace(mostThreatening.mesh.position.clone()).normalize().scaleInPlace(this.maxSpeed * this.dt * .75); // MAX AVOID FORCE (<= maxSpeed)\r\n } else {\r\n avoidance.scaleInPlace(0); // nullify the avoidance force\r\n }\r\n let action = { force: avoidance, name: this.avoid.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n return this;\r\n }\r\n\r\n followPath(path, loop, thresholdRadius = 10) {\r\n var wayPoint = path[this.pathIndex]\r\n if (wayPoint == null)\r\n return;\r\n if (BABYLON.Vector3.Distance(this.mesh.position, wayPoint) < thresholdRadius) {\r\n if (this.pathIndex >= path.length - 1) {\r\n if (loop)\r\n this.pathIndex = 0;\r\n } else {\r\n this.pathIndex++\r\n }\r\n }\r\n if (this.pathIndex >= path.length - 1 && !loop) {\r\n this.arrive({\r\n mesh: {\r\n position: wayPoint\r\n }\r\n });\r\n } else {\r\n this.seek({\r\n mesh: {\r\n position: wayPoint\r\n }\r\n });\r\n }\r\n }\r\n\r\n isOnLeaderSight(leader, ahead, leaderSightRadius) {\r\n return (BABYLON.Vector3.Distance(ahead, this.mesh.position) <= leaderSightRadius ||\r\n BABYLON.Vector3.Distance(leader.mesh.position, this.mesh.position) <= leaderSightRadius);\r\n }\r\n\r\n followLeader(leader, entities, distance = 20, separationRadius = 40, maxSeparation = 10, leaderSightRadius = 50, arrivalThreshold = 100) {\r\n var tv = leader.velocity.clone();\r\n tv.normalize().scaleInPlace(distance)\r\n var ahead = leader.mesh.position.clone().add(tv);\r\n tv.negateInPlace()\r\n var behind = leader.mesh.position.clone().add(tv);\r\n\r\n if (this.isOnLeaderSight(leader, ahead, leaderSightRadius)) {\r\n this.flee(leader);\r\n }\r\n this.arrivalThreshold = arrivalThreshold;\r\n this.arrive({\r\n mesh: {\r\n position: behind\r\n }\r\n });\r\n this.separation(entities, separationRadius, maxSeparation);\r\n return this;\r\n }\r\n\r\n getNeighborAhead(entities) {\r\n var maxQueueAhead = 100;\r\n var maxQueueRadius = 100;\r\n var res;\r\n var qa = this.velocity.clone().normalize().scaleInPlace(maxQueueAhead);\r\n var ahead = this.mesh.position.clone().add(qa);\r\n for (var i = 0; i < entities.length; i++) {\r\n var distance = BABYLON.Vector3.Distance(ahead, entities[i].mesh.position);\r\n if (entities[i] != this && distance <= maxQueueRadius) {\r\n res = entities[i]\r\n break;\r\n }\r\n }\r\n return res;\r\n }\r\n\r\n queue(entities, maxQueueRadius = 50, configuration = {}) {\r\n var neighbor = this.getNeighborAhead(entities);\r\n var brake = new BABYLON.Vector3(0, 0, 0);\r\n var v = this.velocity.clone()\r\n if (neighbor != null) {\r\n brake = this.steeringForce.clone().negateInPlace().scaleInPlace(0.8);\r\n v.negateInPlace().normalize();\r\n brake.add(v)\r\n if (BABYLON.Vector3.Distance(this.mesh.position, neighbor.mesh.position) <= maxQueueRadius) {\r\n this.velocity.scaleInPlace(0.3)\r\n }\r\n }\r\n let action = { force: brake, name: this.queue.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n return this;\r\n }\r\n\r\n // NOT WORKING !!!\r\n flock(entities, configuration = {}) {\r\n var averageVelocity = this.velocity.clone();\r\n var averagePosition = new BABYLON.Vector3(0, 0, 0);\r\n var inSightCount = 0;\r\n for (var i = 0; i < entities.length; i++) {\r\n if (entities[i] != this && this.inSight(entities[i])) {\r\n averageVelocity.add(entities[i].velocity)\r\n averagePosition.add(entities[i].mesh.position)\r\n if (BABYLON.Vector3.Distance(this.mesh.position, entities[i].mesh.position) < this.tooCloseDistance) {\r\n this.flee(entities[i] /* .mesh.position */);\r\n }\r\n inSightCount++;\r\n }\r\n }\r\n if (inSightCount > 0) {\r\n averageVelocity.scaleInPlace(1 / inSightCount);\r\n averagePosition.scaleInPlace(1 / inSightCount);\r\n this.seek({\r\n mesh: {\r\n position: averagePosition\r\n }\r\n });\r\n let action = { force: averageVelocity.subtractInPlace(this.velocity), name: this.flock.name };\r\n this.forces.push(Object.assign(configuration, action));\r\n }\r\n return this;\r\n }\r\n\r\n sortByPriority(arr) {\r\n return arr.sort(function (a, b) {\r\n return (b.priority || defaultPriorities[b.name]) - (a.priority || defaultPriorities[a.name]);\r\n });\r\n }\r\n\r\n animate(mode) {\r\n if (mode === \"blend\") {\r\n this.forces.forEach(a => {\r\n this.steeringForce = this.steeringForce.add(a.force).scaleInPlace(a.weigth || 0.5);\r\n });\r\n } else if (mode === \"priority\") {\r\n // order for priority\r\n this.forces = this.sortByPriority(this.forces);\r\n let output = this.forces[0].force;\r\n this.steeringForce = this.steeringForce.add(output);\r\n } else if (mode === \"probability\") {\r\n let output = new BABYLON.Vector3(0, 0, 0);\r\n this.forces = this.sortByPriority(this.forces);\r\n for (let i = 0; i < this.forces.length; i++) {\r\n let ele = this.forces[i];\r\n if ((ele.probability || defaultProbabilities[ele.name]) > Math.random()) {\r\n output = ele.force;\r\n break;\r\n }\r\n }\r\n this.steeringForce = this.steeringForce.add(output);\r\n } else if (mode === \"truncated\") {\r\n this.forces = this.sortByPriority(this.forces);\r\n for (let i = 0; i < this.forces.length; i++) {\r\n let ele = this.forces[i];\r\n this.steeringForce = this.steeringForce.add(ele.force).scaleInPlace(ele.weigth || 0.5);\r\n if (this.steeringForce.length() > 0.005) {\r\n break;\r\n }\r\n }\r\n } else {\r\n this.forces.forEach(a => {\r\n this.steeringForce = this.steeringForce.add(a.force)\r\n });\r\n }\r\n this.update();\r\n }\r\n\r\n}\r\n"],"names":["const","defaultPriorities","avoid","queue","separation","flock","flee","seek","idle","defaultProbabilities","SteeringVehicle","constructor","mesh","engine","options","checkCollisions","steeringForce","BABYLON","maxForce","velocity","forces","maxSpeed","mass","velocitySamples","numSamplesForSmoothing","arrivalThreshold","avoidDistance","radius","waypoints","pathIndex","wanderDistance","wanderAngle","wanderRadius","wanderRange","inSightDistance","tooCloseDistance","dt","this","getDeltaTime","what","target","configuration","scaleInPlace","setAll","push","Object","assign","force","name","lookTarget","lookAt","position","lookWhereGoing","smoothing","direction","clone","add","y","length","shift","c","v","addInPlace","inSight","Distance","heading","normalize","difference","subtract","Dot","hasInConeOfView","targets","let","i","targetPos","actorPos","distance","v0","v1","dot","angle","Math","acos","angleInDegree","ToDegrees","material","emissiveColor","color","isInConeOfViewOf","truncate","vector","max","update","moveWithCollisions","applyForce","attract","threshold","strenght","action","subtractInPlace","seekWithArrive","desiredVelocity","arrive","pursue","lookAheadTime","predictedTarget","evade","canSee","start","Lerp","ray","hit","getScene","pickWithRay","pickedMesh","uniqueId","hide","obstacles","closestObstacle","closestDistance","obstacle","distanceWithTarget","pointToReach","wander","center","offset","x","sin","z","cos","random","entities","separationRadius","maxSeparation","neighborCount","negateInPlace","interpose","targetA","targetB","midPoint","timeToMidPoint","pointA","pointB","dynamic_length","ahead","ahead2","mostThreatening","avoidance","followPath","path","loop","thresholdRadius","wayPoint","isOnLeaderSight","leader","leaderSightRadius","followLeader","tv","behind","getNeighborAhead","res","qa","maxQueueRadius","neighbor","brake","averageVelocity","averagePosition","inSightCount","sortByPriority","arr","sort","a","b","priority","animate","mode","forEach","weigth","output","ele","probability"],"mappings":"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"}