Created
January 30, 2012 04:31
-
-
Save bellbind/1702547 to your computer and use it in GitHub Desktop.
[html5][threejs][javascript]Three.js wirh quaternion squad
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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