Camera controls based on object bounding box?
Normal orbit controls from three.js is perfect for round object, but not good for long object (especially when zoom close), I'm looking for a solution to solve that.
It's hard to describe in words, please view this webgl example from Google (zoom in maximum to see): https://www.google.com/o3d/shopping/viewer/360?q=ymMBhK8fu3C&o3ds=use_3d
This is top view illustration of what I'm looking for:
I was thinking about use based on default OrbitControls, continuous cast ray from camera to bounding box and keep a constant distance, but the problem is the camera always looking at the center of object, unlike in the above example (cam only rotate when reaching to the corner of object).
Any ideas would be greatly appreciated.
As you pointed out, using the existing THREE.OrbitControls
and modifying the target
does not work as the camera wouldn't look perpendicularly at the bounding box.
I tried different things, with quite bad results but here's my work.
In every solution I tried, I always had to compute (in any order) :
In any case, the camera must rotate around something. So, all my solutions are more or less based on the THREE.OrbitControls
, which acts as, say, "the current state of the rotation" and handles all DOM events stuff for me.
Looking at the closest point on the AABB
The idea is the following :
There are 2 cases :
The border
The corner
Tested on this (very tricky) fiddle. Still need to fix top and bottom faces though (rotation singularity).
Raycasting on a bounding volume
This is the idea you described in the question :
I tried it with a subdivided box geometry with rounded borders and corners so that the camera rotates at angles.
Considering the smoothness of the surface, the result could have been very convenient. Unfortunately, the camera sharply changes direction when the normal of the intersection changes, causing unpleasant bumps in the motion.
See this (tricky again) fiddle.
To fix this, we can linearly interpolate the normal along the triangle, but this requires the normals to be computed in such a way that every normal of a vertex is the average of the normals of the faces this vertex belongs to.
Note that this solution is quite heavy (raycasting a lot of faces) and may requires some pre-processing to create the BV.
Changing the basis of the classical Orbit Controls
This is not exactly what you're looking for but it's also suitable for long objects and, honestly, that's the less tricky solution I made.
The idea is to modify the basis on which the classical THREE.OrbitControls
operates so that the position is modified but the direction remains unchanged, like the following :
I sort of did it with a customized version : THREE.BasisOrbitControls
. Take a look at this fiddle.
var basis = new THREE.Matrix4();
basis.makeScale(2.0, 3.0, 4.0); // my object is very long and a bit tall
var controls = new THREE.BasisOrbitControl(camera, basis, renderer.domElement);
Note that the resulting motion of the camera is described by an ellipsoid .
Hope this helped, I'm really interested in a clean solution too.
上一篇: 是否可以修改服务工作者缓存响应头文件?
下一篇: 基于对象边界框的相机控件?