我設法使用四元數在three.js中平滑地動畫相機。我花了一段時間才弄明白,但一旦完成,觀察四元數是如何工作的很好。
的方法是:
- 存儲初始四元數
- 定義目標四元數的吐溫
- 期間從0
- 吐溫東西1
- 插值四元數的每一幀上應用內插四元數回到相機每幀
而且一個簡單的例子的代碼的關鍵部分:
var camera // camera
var cameraPos0 // initial camera position
var cameraUp0 // initial camera up
var cameraZoom // camera zoom
var iniQ // initial quaternion
var endQ // target quaternion
var curQ // temp quaternion during slerp
var vec3 // generic vector object
var tweenValue // tweenable value
// init camera
function setup()
{
camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 2000)
camera.position = new THREE.Vector3(0, 0, 80)
cameraPos0 = camera.position.clone()
cameraUp0 = camera.up.clone()
cameraZoom = camera.position.z
}
// set a new target for the camera
function moveCamera(euler, zoom)
{
// reset everything
endQ = new THREE.Quaternion()
iniQ = new THREE.Quaternion().copy(camera.quaternion)
curQ = new THREE.Quaternion()
vec3 = new THREE.Vector3()
tweenValue = 0
endQ.setFromEuler(euler)
TweenLite.to(this, 5, { tweenValue:1, cameraZoom:zoom, onUpdate:onSlerpUpdate })
}
// on every update of the tween
function onSlerpUpdate()
{
// interpolate quaternions with the current tween value
THREE.Quaternion.slerp(iniQ, endQ, curQ, tweenObj.value)
// apply new quaternion to camera position
vec3.x = cameraPos0.x
vec3.y = cameraPos0.y
vec3.z = cameraZoom
vec3.applyQuaternion(curQ)
camera.position.copy(vec3)
// apply new quaternion to camera up
vec3 = cameraUp0.clone()
vec3.applyQuaternion(curQ)
camera.up.copy(vec3)
}
的最後一步是尋找目標Euler旋轉傳遞給moveCamera
。在我的情況下,我使用TrackballControls來尋找一些有趣的相機位置/旋轉,然後用euler = camera.rotation.clone()
檢索它們並將其作爲目標傳遞。例如:
moveCamera(new THREE.Euler(2.20, -0.15, 0.55), 120)
這種方法的應用可以在這裏看到:http://brunoimbrizi.com/experiments/#/08
對於相同問題的更詳細的答案,看看這裏:http://stackoverflow.com/questions/14567712/how-to-animate-camera-lookat-using-three-js – kjyv