CCD (ccdbox)

detailed example

by jmcjc5u

HTML

<div id="info">
  IK of Two-Link Arm
  <br>
  <br> ( generic CCD Solver )
</div>

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js">
</script>
<!--script src="https://rawgit.com/jyunming-chen/game3js/master/js/ccdbox.js"></script-->
<!--script src="https://cdn.jsdelivr.net/gh/jyunming-chen/game3js@13a05103eb51d913dd7815939bf7ad45690e8dc9/js/ccdbox.js"></script-->
<script src="https://jyunming-chen.github.io/game3js/js/ccdsys.js"></script>

CSS

body {
	  background-color: #fff;
	  color: #111;
	  margin: 0px;
	  overflow: hidden;
	font-family: Monospace;
	  font-size: 20px;
	}
	
	#info {
	  position: absolute;
	  top: 0px;
	  width: 100%;
	  padding: 5px;
	  text-align: center;
	  color: #ffff00
	}
	
	a {
	  color: #00ffff
	}
	
	strong {
	  color: red
	}
	
	#container {
	  z-index: 0;
	  left: 0px;
	  top: 0px;
	  overflow: hidden;
	  position: absolute;
	  width: 100%;
	  height: 100%;
	}

JavaScript

var scene, renderer, camera;
var zz = 0, sign = 1;

var puck;
var raycaster;
var mouse = new THREE.Vector2();
var pickables = [];

/////////////////////////
var twoLinkArm;
//var target;
var  twoLinker = {  

    // this is a JavaScript Object
    // no need to make it a CLASS (one of a kind)
    
    theta1: 0,
    theta2: 0,
    target: new THREE.Vector3(),

		init: function() {
      let twoLinkArm = new THREE.Group ();

			this.link1 = makeLink (60);
      this.link2 = makeLink (90);

			twoLinkArm.add (this.link1);
      this.link1.add (this.link2);
      
      // add link2 to END of link1 ...
      this.link2.position.set (60,0,0);

      // base
      let cyl_geom = new THREE.CylinderGeometry(10, 10, 6, 32);
      let cyl_mat = new THREE.MeshBasicMaterial({
        color: 0xff2211
      });
      let base = new THREE.Mesh(cyl_geom, cyl_mat);
      twoLinkArm.add(base);
			return twoLinkArm;    
    },

		// ccdSys: to be added later

		update: function (thetas) { 
      // HERE: thetas is modified after CCD iterations
      
    	this.theta1 = thetas[0];
      this.theta2 = thetas[1];
			this.link1.rotation.y = this.theta1;
  		this.link2.rotation.y = this.theta2;    
    }
    
  }


init();
animate();

////////////////////////////////////////////////////////
// forward kinematics
function fk (theta, joints) {  
  // all memory assumed in place (已經有了)

  // all joints are in LOCAL coordinates (of twoLinkArm)
  joints[0].set (0,0,0);
  
  var localzero = new THREE.Vector3(0, 0, 0);
  var m = new THREE.Matrix4();
  m.makeRotationY(theta[0]);
  m.multiply(new THREE.Matrix4().makeTranslation(60, 0, 0));
  localzero.applyMatrix4(m);
  joints[1].copy(localzero);

  localzero.set(0, 0, 0);
  m.multiply(new THREE.Matrix4().makeRotationY(theta[1]));
  m.multiply(new THREE.Matrix4().makeTranslation(90, 0, 0));
  localzero.applyMatrix4(m);
  joints[2].copy(localzero);  // this is the END (local)...