只需更新controls.target属性,例如:
controls.target.set(1, 5, 7);
controls.target.copy(mesh.position)
OrbitControls旨在用于围绕场景旋转,摄像机视口直接朝向控制旋转目标。它们不适用于处理与相机分离的对象旋转,但有TransformControls,但这些不支持阻尼。
使用轨道控件旋转,将锁定您的相机视口以查看中心(虚线),并围绕中心旋转(红线):
如果移动/平移目标,则相机目标和旋转中心一起移动,如下所示:
您需要独立的旋转中心和相机目标,因此相机围绕对象旋转,同时查看某个点,如下所示:
似乎有两种方法创建自定义相机/旋转功能:
1)修改OrbitControls 将相机.lookAt更改为与controls.target偏移。
OrbitControls所需的视图更改: https://github.com/sciecode/three.js/commit/dccf1578343bb9b7c79bb2eb2004d5ee34a76e6a#diff-ffef32863dd826c87a45cfb28c4ddd83
自定义Orbit Controls演示: https://jsfiddle.net/kmturley/6qxh3zc9/28/
2)修改TransformControls 更改变换控件以允许阻尼、自由旋转和隐藏gizmo叠加。
自定义Transform Controls演示 https://jsfiddle.net/kmturley/2p1v6bcw/18/
3)创建您自己的物体旋转控件
import * as THREE from "https://threejs.org/build/three.module.js";
var mesh, renderer, scene, camera, controls;
var radius = 5;
var group;
var targetRotationX = 0;
var targetRotationOnMouseDownX = 0;
var targetRotationY = 0;
var targetRotationOnMouseDownY = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var mouseY = 0;
var mouseYOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var finalRotationY
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, radius * 2, radius * 2);
camera.lookAt(0, radius, 0)
// controls
/* controls = new OrbitControls( camera, renderer.domElement ); */
document.addEventListener('mousedown', onDocumentMouseDown, false);
document.addEventListener('touchstart', onDocumentTouchStart, false);
document.addEventListener('touchmove', onDocumentTouchMove, false);
// ambient
scene.add(new THREE.AmbientLight(0x222222));
// light
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(20, 20, 0);
scene.add(light);
// geometry
var geometry = new THREE.SphereGeometry(radius, 12, 8);
// material
var material = new THREE.MeshPhongMaterial({
color: 0x00ffff,
flatShading: true,
transparent: true,
opacity: 0.7,
});
// mesh
group = new THREE.Object3D();
mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
scene.add(group);
}
function onDocumentMouseDown(event) {
event.preventDefault();
document.addEventListener('mousemove', onDocumentMouseMove, false);
document.addEventListener('mouseup', onDocumentMouseUp, false);
document.addEventListener('mouseout', onDocumentMouseOut, false);
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDownX = targetRotationX;
mouseYOnMouseDown = event.clientY - windowHalfY;
targetRotationOnMouseDownY = targetRotationY;
}
function onDocumentMouseMove(event) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
targetRotationY = targetRotationOnMouseDownY + (mouseY - mouseYOnMouseDown) * 0.02;
targetRotationX = targetRotationOnMouseDownX + (mouseX - mouseXOnMouseDown) * 0.02;
}
function onDocumentMouseUp(event) {
document.removeEventListener('mousemove', onDocumentMouseMove, false);
document.removeEventListener('mouseup', onDocumentMouseUp, false);
document.removeEventListener('mouseout', onDocumentMouseOut, false);
}
function onDocumentMouseOut(event) {
document.removeEventListener('mousemove', onDocumentMouseMove, false);
document.removeEventListener('mouseup', onDocumentMouseUp, false);
document.removeEventListener('mouseout', onDocumentMouseOut, false);
}
function onDocumentTouchStart(event) {
if (event.touches.length == 1) {
event.preventDefault();
mouseXOnMouseDown = event.touches[0].pageX - windowHalfX;
targetRotationOnMouseDownX = targetRotationX;
mouseYOnMouseDown = event.touches[0].pageY - windowHalfY;
targetRotationOnMouseDownY = targetRotationY;
}
}
function onDocumentTouchMove(event) {
if (event.touches.length == 1) {
event.preventDefault();
mouseX = event.touches[0].pageX - windowHalfX;
targetRotationX = targetRotationOnMouseDownX + (mouseX - mouseXOnMouseDown) * 0.05;
mouseY = event.touches[0].pageY - windowHalfY;
targetRotationY = targetRotationOnMouseDownY + (mouseY - mouseYOnMouseDown) * 0.05;
}
}
function animate() {
requestAnimationFrame(animate);
rotate();
renderer.render(scene, camera);
}
function rotate() {
group.rotation.y += (targetRotationX - group.rotation.y) * 0.1;
finalRotationY = (targetRotationY - group.rotation.x);
if (group.rotation.x <= 1 && group.rotation.x >= -1) {
group.rotation.x += finalRotationY * 0.1;
}
if (group.rotation.x > 1) {
group.rotation.x = 1
}
if (group.rotation.x < -1) {
group.rotation.x = -1
}
}