Rigid Body

by jason870509

HTML

<div id="info">Rigid Body Dynamics
  <br></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/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 RB {
	constructor () {
    // states
    this.x = new THREE.Vector3();
    this.q = new THREE.Quaternion(0,0,0,1);  // identity matrix
    this.P = new THREE.Vector3();
    this.L = new THREE.Vector3();

		// force & torque
    this.F = new THREE.Vector3();
    this.tau = new THREE.Vector3();
		
    // mass & inertia tensor
    this.M = 2;    
    //this.I = new THREE.Matrix3();  // identity
		//this.Ibody = new THREE.Matrix3();  // set in init()
    
		// aux variables
  	this.v = new THREE.Vector3();
		this.omega = new THREE.Vector3();
		this.R = new THREE.Matrix3();  // identity matrix

		// external force
    this.p0 = new THREE.Vector3 (10, 1, -10);  // spring connection point
    
    // for threejs only
    this.matrix4 = new THREE.Matrix4();
    this.Ibodyinv = new THREE.Matrix3();
  }
  
  update (dt) {
    // compute F (force)
    this.F.set (0, -10, 0);  // gravity
    let corner = this.p0.clone().applyMatrix3 (this.R).add(this.x);

		let sf = corner.clone().multiplyScalar(-1).add(spring.anchor).multiplyScalar(spring.ks);
    this.F.add (sf);
    // compute tau (torque)
		this.tau.copy (corner.sub(this.x).cross(sf));
    
    // Euler's method
    this.x.add (this.v.clone().multiplyScalar(dt));
    this.P.add (this.F.clone().multiplyScalar(dt));
    this.L.add (this.tau.clone().multiplyScalar(dt));
		
    // update q
    let omegaQ = new THREE.Quaternion ();
    let k = 0.5*dt;
    omegaQ.set (k*this.omega.x, k*this.omega.y, k*this.omega.z, 0);
    omegaQ.multiply (this.q);
    this.q.set (this.q.x + omegaQ.x, this.q.y + omegaQ.y, this.q.z + omegaQ.z, this.q.w + omegaQ.w);
    this.q.normalize();
    
		//////////////////////////////////////////////
		// update aux variables
    
    // compute R(t) from q
    this.matrix4.makeRotationFromQuaternion (this.q);
    this.R.setFromMatrix4 (this.matrix4);
    
    this.v.copy (this.P.clone().multiplyScalar (1/this.M));
    // I = R Ibody Rt
    //this.I.multiplyMatrices (this.R, this.Ibody);
   ...