我使用WebGlRenderer和Three.js展示OBJ元素,现在我想允许用户以任何方向旋转相机围绕着对象,我找到了这个答案:
但是两个示例都返回错误,第一个说投影器没有定义,我不知道它指的是什么。我只有一个简单的相机、对象和一些灯光。 第二段代码说未定义的函数。
有人知道如何获得我需要的结果吗?
我使用WebGlRenderer和Three.js展示OBJ元素,现在我想允许用户以任何方向旋转相机围绕着对象,我找到了这个答案:
但是两个示例都返回错误,第一个说投影器没有定义,我不知道它指的是什么。我只有一个简单的相机、对象和一些灯光。 第二段代码说未定义的函数。
有人知道如何获得我需要的结果吗?
这就是你想要的:http://threejs.org/examples/misc_controls_orbit.html
在下载控件后,包括轨道控制器:
<script src="js/controls/OrbitControls.js"></script>
设置变量:
var controls;
将控件附加到相机并添加监听器:
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );
在您的动画函数中更新控件:
controls.update();
[更新] controls.autoRotate = true;
(在v73版本中测试。OrbitControls.js的最新版本已添加此控件。)
OrbitControls
打交道,只需将相机添加到一个 Group
中。 const boom = new THREE.Group();
boom.add(camera);
scene.add(boom);
camera.position.set( 0, 0, 100 ); // this sets the boom's length
camera.lookAt( 0, 0, 0 ); // camera looks at the boom's zero
那么,您可以旋转这个支臂而不是相机本身。
boom.rotation.x += 0.01;
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// this would create the orbit controls
// it would allow camera control using mouse
const orbitControls = new OrbitControls(camera, renderer.domElement);
如果您需要自动旋转功能,
function init() {
...
// following would enable autorotate
const orbitControls.autoRotate = true;
..
}
function animate() {
// need to update the orbitcontrols for autorotate camera to take effect
orbitControls.update();
...
renderer.render( scene, camera );
requestAnimationFrame( animate );
}
参考链接:https://threejs.org/docs/#examples/zh/controls/OrbitControls
以下是一种快速的技巧,以防您由于某些原因不想使用OrbitControls。
camera.position.copy( target );
camera.position.x+=Math.sin(camera.rotationy)*3;
camera.position.z+=Math.cos(camera.rotationy)*3;
camera.position.y+=cameraHeight; // optional
tempVector.copy(target).y+=cameraHeight; // the += is optional
camera.lookAt( tempVector );
camera.rotationy是鼠标旋转值的一个副本,因为我们通过调用lookAt方法来改变它。
实际上,如果您将“相机”替换为所选择的对象,该对象将会旋转。但是,如果周围有其他物体(例如地板上的网格),它们仍将保持静止。这可能是您想要的,或者看起来很奇怪。(想象一下一把在空中旋转的椅子...?)
我选择在初始化轨道控制器后,从我的代码中覆盖OrbitControls.JS中心对象。
controls = new THREE.OrbitControls(camera, renderer.domElement);
…
controls.center = new THREE.Vector3(
chair.position.x,
chair.position.y,
chair.position.z
);
(免责声明:我有这样的印象,OrbitControls.js 有不同的版本,但我假设它们都使用这个中心对象)
添加一个监听器,以便在OrbitControl
更改时触发渲染方法:
const controls = new OrbitControls(camera, this.renderer.domElement);
controls.enableDamping = true; //damping
controls.dampingFactor = 0.25; //damping inertia
controls.enableZoom = true; //Zooming
controls.autoRotate = true; // enable rotation
controls.maxPolarAngle = Math.PI / 2; // Limit angle of visibility
controls.addEventListener("change", () => {
if (this.renderer) this.renderer.render(this.scene, camera);
});
并在动态更新控件中:
start = () => {
if (!this.frameId) {
this.frameId = requestAnimationFrame(this.animate);
}
};
stop = () => {
cancelAnimationFrame(this.frameId);
};
renderScene = () => {
if (this.renderer) this.renderer.render(this.scene, camera);
};
animate = () => {
// update controls
controls.update();
}
对于寻找在限制条件下自动旋转方向更改的人提供额外信息:
if (
controls.getAzimuthalAngle() >= Math.PI / 2 ||
controls.getAzimuthalAngle() <= -Math.PI / 2
) {
controls.autoRotateSpeed *= -1;
}
controls.update();
controls.addEventListener( 'change', render );
。库会自己完成这个操作。而且controls.update()
必须在function render(){...}
中,而不是在function animate(){...}
中。 - Ruben Kazumovrender()
中使用controls.update()
是不必要的,它仍然可以正常工作。 - Ruben Kazumov