Skip to content

Instantly share code, notes, and snippets.

@bellbind
Created January 30, 2012 04:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bellbind/1702547 to your computer and use it in GitHub Desktop.
Save bellbind/1702547 to your computer and use it in GitHub Desktop.
[html5][threejs][javascript]Three.js wirh quaternion squad
<!DOCTYPE html>
<html>
<head>
<script src="Three.js"></script>
<script>
window.addEventListener("load", function () {
var scene = new THREE.Scene();
//var camera = new THREE.PerspectiveCamera(100, 16/9, 1, 10000);
var camera = new THREE.OrthographicCamera(-800, 800, 450, -450, 1, 10000);
camera.position.z = 1000;
scene.add(camera);
var shape = new THREE.CubeGeometry(100, 100, 100);
var material = new THREE.MeshBasicMaterial(
{color: 0xff0000, wireframe: true});
var mesh = new THREE.Mesh(shape, material);
scene.add(mesh);
//var renderer = new THREE.CanvasRenderer();
var renderer = new THREE.WebGLRenderer(
{antialias: true, clearColor: 0x000000, clearAlpha: 1});
renderer.setSize(800, 450);
document.body.appendChild(renderer.domElement);
// rotation with quaternion
var qs = [
new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 1, 1).normalize(), Math.PI/2),
new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 1, 1).normalize(), 0),
new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 1, 1).normalize(), Math.PI/2),
new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 1, 1).normalize(), Math.PI/1),
new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 1, 1).normalize(), Math.PI/2),
new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 1, 1).normalize(), 0),
new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 1, 1).normalize(), Math.PI/2),
];
var qrs = quadrangles(qs);
var timeOffset = new Date();
var span = 10000 / 2;
var baseRot = new THREE.Vector3(0, 0, 1).normalize();
var qBuf = new THREE.Quaternion();
mesh.rotation = squads(qs, qrs, 0).multiplyVector3(baseRot.clone());
var animate = function () {
var msec = new Date() - timeOffset;
var rate = msec / span;
var times = 0| rate;
var t = rate - times;
//if (times % 2 === 1) t = 1 - t;
mesh.rotation = squads(qs, qrs, t).multiplyVector3(baseRot.clone());
//mesh.rotation.x += 0.01;
//mesh.rotation.y += 0.01;
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
animate();
}, false);
// additional functions for quaternion
var add = function (qa, qb) {
return new THREE.Quaternion(
qa.x + qb.x, qa.y + qb.y, qa.z + qb.z, qa.w + qb.w);
};
var factor = function (n, q) {
return new THREE.Quaternion(n * q.x, n * q.y, n * q.z, n * q.w);
};
var log = function (q) {
var a = Math.acos(q.w);
var sin = Math.sin(a);
if (sin === 0) return new THREE.Quaternion(0, 0, 0, 0);
var t = a / sin;
return new THREE.Quaternion(t * q.x, t * q.y, t * q.z, 0);
};
var exp = function (q) {
var a = q.length();
if (a === 0) return new THREE.Quaternion(0, 0, 0, 1);
var cos = Math.cos(a);
var sin = Math.sin(a);
var t = sin / a;
return new THREE.Quaternion(t * q.x, t * q.y, t * q.z, cos);
};
var quadrangle = function (qprev, qcurr, qnext) {
var iQcQn = new THREE.Quaternion().copy(qcurr).inverse().multiplySelf(qnext);
var iQcQp = new THREE.Quaternion().copy(qcurr).inverse().multiplySelf(qprev);
var l = factor(-1/4, add(log(iQcQn), log(iQcQp)));
return new THREE.Quaternion().copy(qcurr).multiplySelf(exp(l));
};
var quadrangles = function (qs) {
var qrs = [];
for (var i = 1, last = qs.length - 1; i < last; i++) {
qrs.push(quadrangle(qs[i - 1], qs[i], qs[i + 1]));
}
return qrs;
};
var squad = function (q1, qr1, qr2, q2, h) {
var s1 = THREE.Quaternion.slerp(q1, q2, new THREE.Quaternion(), h);
var s2 = THREE.Quaternion.slerp(qr1, qr2, new THREE.Quaternion(), h);
var sh = 2 * h * (1 - h);
return THREE.Quaternion.slerp(s1, s2, new THREE.Quaternion(), sh);
};
var squads = function (qs, qrs, t) {
if (t == 1) {
var n = qrs.length - 2;
var h = 1;
} else {
var m = t * (qrs.length - 1);
var n = 0|m;
var h = m - n;
}
return squad(qs[n + 1], qrs[n], qrs[n + 1], qs[n + 2], h);
};
</script>
</head>
<body>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment