【发布时间】:2012-01-15 15:26:40
【问题描述】:
我的场景中有很多对象,因此旋转所有对象可能会很痛苦。那么在鼠标点击和拖动时将相机围绕原点移动的最简单方法是什么?这样,场景中的所有灯光和对象都在同一个位置,所以唯一改变的是相机。 Three.js 没有提供围绕一个点旋转相机的方法,或者是这样吗?
谢谢
【问题讨论】:
标签: javascript 3d three.js
我的场景中有很多对象,因此旋转所有对象可能会很痛苦。那么在鼠标点击和拖动时将相机围绕原点移动的最简单方法是什么?这样,场景中的所有灯光和对象都在同一个位置,所以唯一改变的是相机。 Three.js 没有提供围绕一个点旋转相机的方法,或者是这样吗?
谢谢
【问题讨论】:
标签: javascript 3d three.js
Here's a project with a rotating camera。通过源查看,它似乎只是将相机位置移动了一圈。
function onDocumentMouseMove( event ) {
event.preventDefault();
if ( isMouseDown ) {
theta = - ( ( event.clientX - onMouseDownPosition.x ) * 0.5 )
+ onMouseDownTheta;
phi = ( ( event.clientY - onMouseDownPosition.y ) * 0.5 )
+ onMouseDownPhi;
phi = Math.min( 180, Math.max( 0, phi ) );
camera.position.x = radious * Math.sin( theta * Math.PI / 360 )
* Math.cos( phi * Math.PI / 360 );
camera.position.y = radious * Math.sin( phi * Math.PI / 360 );
camera.position.z = radious * Math.cos( theta * Math.PI / 360 )
* Math.cos( phi * Math.PI / 360 );
camera.updateMatrix();
}
mouse3D = projector.unprojectVector(
new THREE.Vector3(
( event.clientX / renderer.domElement.width ) * 2 - 1,
- ( event.clientY / renderer.domElement.height ) * 2 + 1,
0.5
),
camera
);
ray.direction = mouse3D.subSelf( camera.position ).normalize();
interact();
render();
}
Here's another demo 在这个我认为它只是创建了一个新的THREE.TrackballControls 对象,以相机作为参数,这可能是更好的方法。
controls = new THREE.TrackballControls( camera );
controls.target.set( 0, 0, 0 )
【讨论】:
看看下面的例子
http://threejs.org/examples/#misc_controls_orbit
http://threejs.org/examples/#misc_controls_trackball
还有其他不同鼠标控件的示例,但是这两个都允许相机围绕一个点旋转并使用鼠标滚轮放大和缩小,主要区别是 OrbitControls 强制相机向上方向,而 TrackballControls 允许相机倒转。
您所要做的就是在您的 html 文档中包含控件
<script src="js/OrbitControls.js"></script>
并将这一行包含在您的源代码中
controls = new THREE.OrbitControls( camera, renderer.domElement );
【讨论】:
controls = new THREE.OrbitControls( camera, renderer.domElement );不能让它工作。你应该添加一个更改事件的处理程序并在处理程序中调用renderer.render(scene, camera),或者添加动画循环并调用controls.update()在animate().
看看 THREE.PointerLockControls
这可以作为使用鼠标/触控板(在打字稿中)移动/旋转/缩放相机的良好起点:
class CameraControl {
zoomMode: boolean = false
press: boolean = false
sensitivity: number = 0.02
constructor(renderer: Three.Renderer, public camera: Three.PerspectiveCamera, updateCallback:() => void){
renderer.domElement.addEventListener('mousemove', event => {
if(!this.press){ return }
if(event.button == 0){
camera.position.y -= event.movementY * this.sensitivity
camera.position.x -= event.movementX * this.sensitivity
} else if(event.button == 2){
camera.quaternion.y -= event.movementX * this.sensitivity/10
camera.quaternion.x -= event.movementY * this.sensitivity/10
}
updateCallback()
})
renderer.domElement.addEventListener('mousedown', () => { this.press = true })
renderer.domElement.addEventListener('mouseup', () => { this.press = false })
renderer.domElement.addEventListener('mouseleave', () => { this.press = false })
document.addEventListener('keydown', event => {
if(event.key == 'Shift'){
this.zoomMode = true
}
})
document.addEventListener('keyup', event => {
if(event.key == 'Shift'){
this.zoomMode = false
}
})
renderer.domElement.addEventListener('mousewheel', event => {
if(this.zoomMode){
camera.fov += event.wheelDelta * this.sensitivity
camera.updateProjectionMatrix()
} else {
camera.position.z += event.wheelDelta * this.sensitivity
}
updateCallback()
})
}
}
把它放在这样的地方:
this.cameraControl = new CameraControl(renderer, camera, () => {
// you might want to rerender on camera update if you are not rerendering all the time
window.requestAnimationFrame(() => renderer.render(scene, camera))
})
控件:
另外:
如果您想通过更改“距离”(沿 yz)而不是更改视野来进行缩放,您可以向上/向下调整相机的位置 y 和 z,同时保持位置 y 和 z 的比率不变,例如:
// in mousewheel event listener in zoom mode
const ratio = camera.position.y / camera.position.z
camera.position.y += (event.wheelDelta * this.sensitivity * ratio)
camera.position.z += (event.wheelDelta * this.sensitivity)
【讨论】:
OrbitControls 和 TrackballControls 似乎很适合这个目的。
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
在渲染中更新
controls.update();
【讨论】:
【讨论】: