JSFiddle - React, Tailwind, and code Playground
by tfoller
HTML
<link type="text/css" rel="stylesheet" href="https://alikim.com/_v1_jsm/css/controls.css">
<canvas id="bg" width="600" height="600"></canvas>
<div>
<button id="align">align hand with its cs</button>
<button id="match">match gun</button>
</div>
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/[email protected]/build/three.module.js"
}
}
</script>
JavaScript
import * as THREE from 'three';
import * as CONTROLS from 'https://alikim.com/_v1_jsm/controls.js'
const [w, h] = [window.innerWidth - 100, window.innerHeight - 100];
const canvas = document.getElementById('bg')
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, w / h, 0.1, 100)
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: false,
canvas: canvas
})
renderer.setSize(w, h)
camera.position.set(5, 5, 5);
const axes = new THREE.AxesHelper(5);
scene.add(axes);
// create coord system from points
const cs = (p1, p2, p3, p4) => {
const x = new THREE.Vector3().subVectors(p2, p1);
const _y = new THREE.Vector3().subVectors(p4, p3);
const z = new THREE.Vector3().crossVectors(x, _y);
const y = new THREE.Vector3().crossVectors(z, x);
return [x.normalize(), y.normalize(), z.normalize()];
};
// calculate quaternion of a cs
const csQuatern = cs => {
// rotation matrix
const m4 = new THREE.Matrix4().makeBasis(
new THREE.Vector3(cs[0].x, cs[1].x, cs[2].x),
new THREE.Vector3(cs[0].y, cs[1].y, cs[2].y),
new THREE.Vector3(cs[0].z, cs[1].z, cs[2].z),
);
return new THREE.Quaternion().setFromRotationMatrix(m4).normalize().invert();
};
// hand pivot points
const hand = {
'-x': new THREE.Vector3(1, 1.3, 1.5),
'+x': new THREE.Vector3(3, 3.5, 3.7),
'-y': new THREE.Vector3(2.1, 2.1, 2.6),
'+y': new THREE.Vector3(3.2, 3.4, 1.2),
'center': new THREE.Vector3(1.5, 2.8, 3.1),
};
const hand_cs = cs(hand['-x'], hand['+x'], hand['-y'], hand['+y']);
const addLine = (p1, p2, clr) => {
const mat = new THREE.LineBasicMaterial({ color: new THREE.Color(...clr) });
const geo = new THREE.BufferGeometry().setFromPoints([p1, p2]);
const line = new THREE.Line( geo, mat);
scene.add( line );
};
const vec3sum = (v1, v2) => new THREE.Vector3().addVectors(v1, v2);
// draw hand cs
const hand_origin = hand.center;
addLine(hand_origin, vec3sum(hand_origin, hand_cs[0]), [0.5,0,0]);
addLine(hand_origin,...