简体   繁体   中英

Calculate position of the camera after rotation around some deliberate point on mesh

I am trying to implement the current scenario:

  1. on mouse down event on the mesh focus perspective camera on the point where a user clicked
  2. allow a user to rotate the camera via orbitControls;
  3. after rotation is completed on mouse up event change camera position and target in such fashion that it would seem that camera is still looking at the mesh at the same angle that it was before focusing and rotation.

So it would appear that a user rotated the camera around some point on the mesh and after rotation is able to look at it at from the same place it used to be before the focusing and rotation.

There is no problem with 1) and 2) And I am quite confused about the 3)

Here I've added some pictures which illustrate main steps

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

The question is how to implement behavior illustrated in the 4th picture.

Important thing is that thought it seems that the camera is looking from the same position and to the same target the pyramid appears to be rotated around the point where the user clicked.

I would appreciate any help. Thanks!

I hope I got you correctly. Find the difference between the initial target and the target point on an object, and on mouse up - shift your camera position with this value.

 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM