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);
 ...