计算围绕网格上某个特定点旋转后相机的位置
Calculate position of the camera after rotation around some deliberate point on mesh
我正在尝试实现当前场景:
- 在用户点击的点上的网格焦点透视相机上的鼠标按下事件
- 允许用户通过 orbitControls 旋转相机;
- 在鼠标松开事件上完成旋转后,以这种方式更改相机位置和目标,使得相机看起来仍在以与聚焦和旋转之前相同的角度注视网格。
所以看起来用户围绕网格上的某个点旋转了相机,并且在旋转之后能够从聚焦和旋转之前的相同位置观察它。
1)和2)没有问题
我对 3)
很困惑
这里我添加了一些图片来说明主要步骤
1) User clicks on some point on the mesh
2) Camera focus is set on the point where the user clicked
3) User rotates the camera around the selected pivot point
4) On mouse up camera should be placed in such fashion so in user's eyes selected point is brought back to the place where it was and the camera is looking from the same angle
问题是如何实现第 4 张图片中所示的行为。
重要的是,认为相机似乎是从相同的位置和相同的目标看的,金字塔似乎围绕用户点击的点旋转。
如有任何帮助,我将不胜感激。谢谢!
希望我没听错。
找到对象上的初始目标和目标点之间的差异,并在鼠标上移 - 使用此值移动相机位置。
var w = window.innerWidth,
h = window.innerHeight;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, w / h, 1, 1000);
camera.position.setScalar(5);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
scene.add(new THREE.GridHelper(10, 10));
var prismGeom = new THREE.ConeBufferGeometry(1, 2, 3);
prismGeom.translate(0, 1, 0);
var prismMat = new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
});
var prism = new THREE.Mesh(prismGeom, prismMat);
prism.position.set(-1, 0, -2);
scene.add(prism);
var centralMarker = new THREE.Mesh(new THREE.SphereBufferGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
color: "aqua"
}));
scene.add(centralMarker);
var pointMarker = new THREE.Mesh(centralMarker.geometry, new THREE.MeshBasicMaterial({
color: "magenta"
}));
pointMarker.visible = false;
scene.add(pointMarker);
var oldTarget = scene.position;
var targeted = false;
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];
window.addEventListener("mousedown", onMouseDown, false);
window.addEventListener("mouseup", onMouseUp, false);
function onMouseDown(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObject(prism);
if (intersects.length > 0) {
targeted = true;
controls.target.copy(intersects[0].point);
pointMarker.position.copy(intersects[0].point);
pointMarker.visible = true;
controls.update();
}
}
function onMouseUp(event) {
if (!targeted) return;
let shift = new THREE.Vector3().copy(oldTarget).sub(controls.target);
camera.position.add(shift);
controls.target.copy(oldTarget);
controls.update();
targeted = false;
pointMarker.visible = false;
}
renderer.setAnimationLoop(() => {
renderer.render(scene, camera)
})
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
我正在尝试实现当前场景:
- 在用户点击的点上的网格焦点透视相机上的鼠标按下事件
- 允许用户通过 orbitControls 旋转相机;
- 在鼠标松开事件上完成旋转后,以这种方式更改相机位置和目标,使得相机看起来仍在以与聚焦和旋转之前相同的角度注视网格。
所以看起来用户围绕网格上的某个点旋转了相机,并且在旋转之后能够从聚焦和旋转之前的相同位置观察它。
1)和2)没有问题 我对 3)
很困惑这里我添加了一些图片来说明主要步骤
1) User clicks on some point on the mesh
2) Camera focus is set on the point where the user clicked
3) User rotates the camera around the selected pivot point
4) On mouse up camera should be placed in such fashion so in user's eyes selected point is brought back to the place where it was and the camera is looking from the same angle
问题是如何实现第 4 张图片中所示的行为。
重要的是,认为相机似乎是从相同的位置和相同的目标看的,金字塔似乎围绕用户点击的点旋转。
如有任何帮助,我将不胜感激。谢谢!
希望我没听错。 找到对象上的初始目标和目标点之间的差异,并在鼠标上移 - 使用此值移动相机位置。
var w = window.innerWidth,
h = window.innerHeight;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, w / h, 1, 1000);
camera.position.setScalar(5);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
scene.add(new THREE.GridHelper(10, 10));
var prismGeom = new THREE.ConeBufferGeometry(1, 2, 3);
prismGeom.translate(0, 1, 0);
var prismMat = new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
});
var prism = new THREE.Mesh(prismGeom, prismMat);
prism.position.set(-1, 0, -2);
scene.add(prism);
var centralMarker = new THREE.Mesh(new THREE.SphereBufferGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
color: "aqua"
}));
scene.add(centralMarker);
var pointMarker = new THREE.Mesh(centralMarker.geometry, new THREE.MeshBasicMaterial({
color: "magenta"
}));
pointMarker.visible = false;
scene.add(pointMarker);
var oldTarget = scene.position;
var targeted = false;
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];
window.addEventListener("mousedown", onMouseDown, false);
window.addEventListener("mouseup", onMouseUp, false);
function onMouseDown(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObject(prism);
if (intersects.length > 0) {
targeted = true;
controls.target.copy(intersects[0].point);
pointMarker.position.copy(intersects[0].point);
pointMarker.visible = true;
controls.update();
}
}
function onMouseUp(event) {
if (!targeted) return;
let shift = new THREE.Vector3().copy(oldTarget).sub(controls.target);
camera.position.add(shift);
controls.target.copy(oldTarget);
controls.update();
targeted = false;
pointMarker.visible = false;
}
renderer.setAnimationLoop(() => {
renderer.render(scene, camera)
})
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>