在ThreeJs中,物体的旋转运动是绕世界中心旋转的,实际却有很多场景要求物体绕其他点旋转。
思路一 将物体移动至中心与世界中心重合的位置,绕世界中心旋转等于自己中心旋转。步骤:
加载模型
获取模型的边界框
获取模型的中心与-1做矩阵乘法(multiply scalar)
通过translate方法或者position.set(),移动模型至世界中心
旋转物体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 loader.load('./js/model/model.obj' , onLoad); var mesh, material = new THREE.MeshLambertMaterial({color : 0xffffff });function onLoad (object ) { mesh = object; var objBox = new THREE.Box3().setFromObject(mesh); var boxCenter = objBox.getCenter(); boxCenter.multiplyScalar(-1 ); mesh.children.forEach(function (child ) { if (child instanceof THREE.Mesh) { child.material = material; } }); mesh.traverse(function (child ) { if (child instanceof THREE.Mesh) { child.geometry.translate(boxCenter.x, boxCenter.y, boxCenter.z); } }); scene.add(mesh); animation(); } function animation ( ) { requestAnimationFrame(animation); mesh.rotation.y += 0.02 ; renderer.render(scene, camera); stats.update(); }
思路二 不移动物体,让物体在原地绕自己的中心旋转。
ThreeJs中有Group
的概念,Group内的物体是绕着Group的中心旋转的。我将Group看作一个新世界
来理解,转动Group就是在转动整个新世界。
新建Group时,其位置(position)即新世界的中心是与世界中心重合的,转动Group看上去就是Group内的所有物体都在绕着世界中心旋转。
想让物体在自己原来的位置(目标旋转点)旋转,步骤如下:
移动Group的位置到这个目标旋转点
目标旋转点的获取与思路一获取模型的中心方式一样
这个时候Group内的所有物体都会做相应的移动
再反方向移动物体
旋转新世界
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 loader.load('./js/model/model.obj' , onLoad); var mesh, material = new THREE.MeshLambertMaterial({color : 0xffffff }), pivot = new THREE.Group(); function onLoad (object ) { mesh = object; var objBbox = new THREE.Box3().setFromObject(mesh); var bboxCenter = objBbox.clone().getCenter(); mesh.children.forEach(function (child ) { if (child instanceof THREE.Mesh) { child.material = material; } }); mesh.position.set(-bboxCenter.x, -bboxCenter.y, -bboxCenter.z); scene.add(pivot); pivot.add(mesh); pivot.position.set(bboxCenter.x, bboxCenter.y, bboxCenter.z); animation(); } function animation ( ) { requestAnimationFrame(animation); pivot.rotation.y += 0.02 ; renderer.render(scene, camera); stats.update(); }