agent
seek, arrival
by j91157j91157
HTML
<div id="info">Agent (Seek, Arrival, Collision)</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js">
</script>
CSS
#info {
position: absolute;
top: 0px;
width: 100%;
padding: 10px;
text-align: center;
color: #ffff00
}
body {
overflow: hidden
}
JavaScript
class Obstacle {
constructor (center,size) {
this.center = center.clone();
this.mesh = new THREE.Mesh (new THREE.CylinderGeometry(size,size,1,20),
new THREE.MeshBasicMaterial());
this.mesh.position.copy (center);
this.size = size;
scene.add (this.mesh)
}
}
class Agent {
constructor(pos, mesh) {
this.pos = pos.clone();
this.vel = new THREE.Vector3();
this.force = new THREE.Vector3();
this.target = new THREE.Vector3();
this.size = 3; // half width
this.mesh = mesh;
this.MAXSPEED = 300;
this.ARRIVAL_R = 200;
//this.nbhd = [];
// for orientable agent
this.angle = 0;
}
update(dt) {
this.accumulateForce();
// collision
// for all obstacles in the scene
let obs = scene.obstacles;
// pick the most threatening one
let theOne = null;
let dist = 1e10;
let vhat = this.vel.clone().normalize();
const REACH = 200
const K = 5
let perp;
for (let i = 0; i < obs.length; i++) {
let point = obs[i].center.clone().sub (this.pos) // c-p
let proj = point.dot(vhat);
if (proj > 0 && proj < REACH) {
perp = new THREE.Vector3();
perp.subVectors (point, vhat.clone().setLength(proj));
let overlap = obs[i].size + this.size - perp.length()
if (overlap > 0 && proj < dist) {
theOne = obs[i]
dist = proj
perp.setLength (K*overlap);
perp.negate()
}
}
}
if (theOne)
this.force.add (perp);
this.vel.add(this.force.clone().multiplyScalar(dt));
// velocity modulation
let diff = this.target.clone().sub(this.pos)
let dst = diff.length();
if (dst < this.ARRIVAL_R) {
this.vel.setLength(dst)
}
this.pos.add(this.vel.clone().multiplyScalar(dt))
this.mesh.position.copy(this.pos)
// for orientable agent
// non PD version
if (this.vel.length() > 0.1) {
this.angle = Math.atan2...