boundaryEnclosesCamera causes zoom on bound collision
Describe the bug
I am trying to limit the position of the camera to be above the z-axis (the camera is z-up), and tried using a combination of the boundary and boundaryEnclosesCamera settings to limit the position. However, when the camera collides with the "floor" it zooms to the center of the view (presumably the focal point). I tried fiddling with the boundaryFriction setting, but this didn't seem to affect it. For reference, I was previously using a standard OrbitControls with the following onChange (react):
<OrbitControls
onChange={() => {
if ((camera as THREE.PerspectiveCamera).isPerspectiveCamera) {
camera.position.z = Math.max(camera.position.z, 0.01);
}}
}
/>
This worked for me, so ideally I would like to see the same type of result.
To Reproduce
- Using react, create a camera controls component that does the following:
useEffect(() => {
if (controlsRef.current) {
controlsRef.current.setBoundary(
new THREE.Box3(
new Vector3(-Infinity, -Infinity, 0),
new Vector3(Infinity, Infinity, Infinity),
),
);
}
}, [controlsRef]);
return (
<CameraControls
ref={controlsRef}
enabled
camera={camera}
dollyToCursor
boundaryEnclosesCamera
boundaryFriction={1}
/>
);
- Then, drag the cursor so that the camera collides with the floor.
- Observe that the camera glitches to the focal point.
Code
Live example
No response
Expected behavior
I would expect that if the camera collides with the boundary, it doesn't shift away visually from its current location. See video of implementation using OrbitControls. Note, it does seem like this implementation does exhibit some drift, but it is much less "breaking" than what I see in the camera controls.
https://github.com/user-attachments/assets/77f4e9f6-b4fe-444f-8949-31513981084a
Screenshots or Video
https://github.com/user-attachments/assets/ebd02be5-9538-4ca7-82e1-357415ba45d6
Device
Desktop
OS
MacOS
Browser
Safari
This is because the way the library does collision it contracts a sphere from the target based on distance to whatever it collides. In the case of the floor the more you rotate down the closer the distance gets and the sphere contracts.
This is a common flow especially in video games but sometimes it should just discard the move to not go beyond the boundary...
So, how will it be handled in the end?
So, how will it be handled in the end?
It likely wont be, this isn't a flaw but a common method for floor detection. If you dont want this behavior don't make the floor a collider. Add a step in your camera move method to check the camera height and limit it. I think some of the other methods might do this for you but it may be easier to do yourself