I've explored various approaches to address the issue you raised about using the existing THREE.OrbitControls
and adjusting the target
without achieving the desired results. Regardless, I've made some progress on this matter.
Throughout my experimentation, I consistently found that I needed to calculate (in any sequence) :
- the position of the camera ;
- the direction of the camera.
Essentially, the camera must rotate around a point. As such, my solutions are mostly based on leveraging THREE.OrbitControls
to manage the rotation state and handle DOM event interactions.
Approach: Focusing on the Closest Point on the AABB
The concept I worked on involves:
- Rotating the camera ;
- Determining the closest point on the AABB from the camera as the target direction ;
- Applying a set distance d to displace the camera from this point as its new position.
There are two scenarios to consider:
The border
https://i.sstatic.net/qdFRl.png
The corner
https://i.sstatic.net/FtZ7T.png
Tested on this (challenging) fiddle. However, adjustments are needed for the top and bottom faces due to rotation singularities.
Method: Raycasting on a Bounding Volume
This aligns with the concept you outlined:
- Defining a bounding volume for the camera to follow ;
- Performing raycasting from the camera position on this BV ;
- Using the intersection point as the camera's new position ;
- Setting the camera's new direction as the normal of the intersected face.
I experimented with a box geometry with rounded edges and corners to enable varied camera rotations.
https://i.sstatic.net/PFflV.png
While the surface smoothness promised convenience, the abrupt changes in camera direction upon normal alterations resulted in jarring motions.
View this (challenging again) fiddle.
To mitigate this, linearly interpolating the normal along the triangle could help, necessitating the calculation of vertex normals from face normals.
https://i.sstatic.net/PFflV.png
Note that this solution is resource-intensive (raycasting numerous faces) and might require preprocessing to establish the BV.
Strategy: Adapting the Basis of Classic Orbit Controls
While not precisely aligned with your requirements, this approach suits elongated objects and is relatively straightforward compared to other solutions I explored.
The notion involves adjusting the basis for conventional THREE.OrbitControls
operations so that the position changes while retaining the direction, as depicted below:
https://i.sstatic.net/kXK7o.png
I partially implemented this concept with a custom version: THREE.BasisOrbitControls
. Refer to this fiddle.
var basis = new THREE.Matrix4();
basis.makeScale(2.0, 3.0, 4.0); // My object is elongated and somewhat tall
var controls = new THREE.BasisOrbitControl(camera, basis, renderer.domElement);
It's worth noting that the resulting camera movement follows an ellipsoid path.
I hope this information proves helpful, and I too am keen on discovering a more streamlined solution.