bevy icon indicating copy to clipboard operation
bevy copied to clipboard

A way to automatically scale the camera so that the currently visible object(s) fill the viewport

Open carschandler opened this issue 6 months ago • 2 comments

What problem does this solve or what need does it fill?

Setting up a camera to give a "full picture" of an object while being agnostic to the object's size and shape can be somewhat tedious.

What solution would you like?

This feature request was inspired by the VTK project, which has a ResetCamera() function and ResetCameraScreenSpace(). This makes it very easy to load in a mesh, set an initial camera view, and then let VTK scale everything for you so that your object occupies most of the screen space, which is great for rendering previews of a model (i.e. exporting images of a model, implementing some kind of "showcase" functionality, etc.).

What alternative(s) have you considered?

Implementing this myself by calculating the bounding box of the object(s) and setting scale appropriately.

Additional context

Aforementioned link to VTK project.

carschandler avatar Dec 13 '23 19:12 carschandler

I don't have experience with VTK but I do with Unity's asset preview system.

It is worth considering that there may be a future use case where multiple objects need to be rendered within a camera's view.

Scaling an object may work for a single object, but can become cumbersome with lots of child/offset objects if there are relative nested scales. (Can result in non-uniform scaling visual bugs). On the other hand, scaling the camera can lead to clipping.

I think the way Unity does this is it renders an empty scene with just the object(s) being previewed, the camera is then moved to the outside of the cumulative bounding box and offset by a distance. When a preview is hovered over then the user can rotate the model and use the scrollwheel to adjust the distance offset. Only one preview scene is active at a time, other previews are cached as static images until selected.

It also seems to do something to orient the object so visible faces face the camera more often than not, in cases where mesh normals may not be visible.

gltf only allows for units in meters so this may help creating asset previews directly of gltf files. I'd imagine there is some sort of Sketchfab style viewport in existence somewhere.

Having a built-in function to match bounds of the camera to an object's bounds is useful in other contexts and a good starting point.

TolinSimpson avatar Dec 15 '23 07:12 TolinSimpson

@TolinSimpson VTK's implementation is entirely camera-based and does not scale objects. Looking at the code for ResetCamera(), an overall bounding box is calculated by taking the extrema of all bounding boxes of all objects ("properties" or "props" as VTK calls them) using the ComputeVisiblePropBounds() function. The camera's position is calculated using viewing angles and its focal point is set on the center of the new overall bounding box. Then the camera's up vector is reset if the new view plane normal is parallel to it.

I may take a stab at my own implementation of this for bevy if I get some spare time.

carschandler avatar Jan 16 '24 21:01 carschandler

If no-one is working on it, I may give it a try. I am learning rust, so a good opporutnity for me. Please let me know.

mghildiy avatar Feb 25 '24 03:02 mghildiy