ThingJS 使用角度控制物体旋转。
通常使用如下属性和接口控制物体旋转:
在世界坐标系下,使用 angles 属性来设置或访问旋转信息。
obj.angles = [0,45,0] //设置世界坐标系Y轴向旋转45角度在父物体坐标系下,使用 localAngles 属性来设置或访问旋转信息。
obj.localAngles = [0,45,0] //设置父物体坐标系Y轴向旋转45角度在自身坐标系下,使用如下接口方法:
//使用rotate,可输入角度和轴向。设置沿给定轴向转一定角度,传入的旋转轴是自身坐标系下的轴方向 obj.rotate( 45, [0,1,0]) //沿自身x轴向旋转,等同于 obj.rotate( 30, [1,0,0]) obj.rotateX(30) //沿自身y轴向旋转,等同于 obj.rotate( 90, [0,1,0]) obj.rotateY(90)我们还可以使用 lookAt 接口方法,使得物体的观察方向一直对准一个位置或物体
//让物体面向[0,1,0],该坐标是在世界坐标下obj.lookAt( [0,1,0]) //让物体一直面向摄影机obj.lookAt( app.camera ) //让物体一直面向一个物体obj.lookAt( obj ) //让物体一直面向一个物体,同时物体沿自身Y轴向再旋转90度obj.lookAt( obj, [0,90,0] ) //取消lookAt功能obj.lookAt( null )查看示例网页链接
正常情况下,子物体会随着父物体旋转而一起旋转,如果想控制子物体不随父物体旋转,可通过设置子物体的 inheritAngles 属性为 false 而实现。
/* Referrer links:
1. http://graphic-sim.com/23_body_axis_rotation.php
2. http://rwoodley.org/?p=1073
3. http://stackoverflow.com/questions/25199173/how-to-find-rotation-matrix-between-two-vectors-in-three-js */
function fixMatrix(mesh) {
bakeRotation(mesh);
rotate180(mesh);
bakeRotation(mesh);
}
function rotate180(mesh) {
var m = new THREE.Matrix4();
m.makeRotationY(Math.PI);
mesh.matrix.multiplyMatrices(mesh.matrix, m);
mesh.matrix.decompose(mesh.position, mesh.quaternion, mesh.scale);
}
function bakeRotation(mesh) {
mesh.updateMatrixWorld();
var geom = mesh.geometry;
var rotMatrix = mesh.matrix.clone();
rotMatrix.setPosition(new THREE.Vector3(0, 0, 0));
var pos = new THREE.Vector3();
pos.setFromMatrixPosition(mesh.matrix);
geom.applyMatrix(rotMatrix);
mesh.matrix.identity();
mesh.matrix.setPosition(pos);
mesh.matrix.decompose(mesh.position, mesh.quaternion, mesh.scale);
mesh.updateMatrixWorld();
}
var init = function() {
var canv = document.getElementsByTagName("canvas")[0];
var w = canv.clientWidth;
var h = canv.clientHeight;
renderer = new THREE.WebGLRenderer({
canvas: canv
});
renderer.setSize(w, h);
renderer.setClearColor(new THREE.Color(0xeeeeee), 1);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
15, // Field of view
w / h, // Aspect ratio
0.1, // Near
10000 // Far
);
camera.position.set(0, 1, 15);
scene.add(camera);
var light = new THREE.PointLight(0xFFFFDD);
light.position.set(-15, 10, 15);
scene.add(light);
var ambient = new THREE.AmbientLight(0x777777);
scene.add(ambient);
var loader = new THREE.ObjectLoader();
var mesh;
var onScene = function(scn) {
mesh = scn.getObjectByName("Bug");
mesh.material.shininess = 5;
fixMatrix(mesh);
scene.add(mesh);
requestAnimationFrame(animate);
};
loader.load("/uploads/160801/vwbug-scene.json", onScene);
var rotationSpeed = 1.0;
function onKeyDown(evt) {
switch (evt.keyCode) {
case 88: // 'x'
xRot = true;
break;
case 89: // 'y'
yRot = true;
break;
case 90: // 'z'
zRot = true;
break;
case 16: // SHIFT
shiftOn = true;
break;
}
}
function onKeyUp(evt) {
switch (evt.keyCode) {
case 88: // 'x'
xRot = false;
break;
case 89: // 'y'
yRot = false;
break;
case 90: // 'z'
zRot = false;
break;
case 16: // SHIFT
shiftOn = false;
break;
}
}
var shiftOn = false;
var xRot = false;
var yRot = false;
var zRot = false;
window.onkeydown = onKeyDown;
window.onkeyup = onKeyUp;
var xUnit = new THREE.Vector3(1, 0, 0);
var yUnit = new THREE.Vector3(0, 1, 0);
var zUnit = new THREE.Vector3(0, 0, 1);
var axis = new THREE.Vector3();
var quat = new THREE.Quaternion();
var clock = new THREE.Clock();
function animate() {
var dt = clock.getDelta();
var dTheta = dt * rotationSpeed;
if (xRot)
axis = xUnit;
if (yRot)
axis = yUnit;
if (zRot)
axis = zUnit;
var moving = xRot || yRot || zRot;
if (mesh && moving) {
quat.setFromAxisAngle(axis, dTheta);
if (shiftOn) // world axes
mesh.quaternion.multiplyQuaternions(quat, mesh.quaternion);
else // body axes
mesh.quaternion.multiply(quat);
}
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
};
window.onload = init;
window.onresize = init;
引入js 找自路径哈threejs库文件面代码加入
var controls = new THREE.OrbitControls(camera);//创建控件象 camera相机象
controls.addEventListener('change', render);//监听鼠标、键盘事件
随意旋转