particle constraints
with orbitControls, XZgrid, info
by jmcjc5u
HTML
<div id="info">Constraints with Verlet
</div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script>
CSS
#info {
position: absolute;
top: 0px;
width: 100%;
padding: 10px;
text-align: center;
color: #ffff00
}
body {
overflow: hidden;
}
JavaScript
class Particle {
constructor (mesh) {
this.p = new THREE.Vector3();
this.pOld = new THREE.Vector3();
this.f = new THREE.Vector3(0,-10,0);
this.mesh = mesh
scene.add (mesh)
this.anchor = null; // default: free to move
this.tmp = new THREE.Vector3() // for update calculation
}
setStartPos (pos) {
this.p.copy (pos)
this.pOld.copy (pos)
}
update(dt) {
const F = 0.005;
this.tmp.copy ( this.p.clone().multiplyScalar(2-F).sub( this.pOld.clone().multiplyScalar(1-F) ).add( this.f.clone().multiplyScalar(dt*dt) ))
this.pOld.copy (this.p)
this.p.copy (this.tmp)
this.doCollision();
this.mesh.position.copy (this.p)
}
doCollision() { // simple y = -25 wall
if (this.p.y < -25) {
this.tmp.copy ( this.pOld.clone().sub(this.p).reflect(new THREE.Vector3(0,1,0)) );
this.p.y = -25;
this.pOld.copy (this.p.clone().add (this.tmp))
}
}
}
class Rod {
constructor (par1, par2) {
this.parA = par1;
this.parB = par2;
this.restlen = par1.p.distanceTo (par2.p)
let geometry = new THREE.Geometry();
geometry.vertices.push (this.parA.p, this.parB.p);
let line = new THREE.Line (geometry, new THREE.LineBasicMaterial());
this.line = line;
scene.add (line)
}
update() { // a:p1, b:p2
let x1 = this.parA
let x2 = this.parB
let delta = x2.p.clone().sub(x1.p);
let deltalen = delta.length();
let diff = (deltalen - this.restlen)/deltalen;
x1.p.add ( delta.clone().multiplyScalar (0.5*diff) );
x2.p.sub ( delta.clone().multiplyScalar (0.5*diff) );
// graphics update
this.line.geometry.verticesNeedUpdate = true;
}
}
/////////////////////////////////////////////////////
var camera, scene, renderer;
var pars = [], rods = [];
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x888888);
...