Hi All,
This week I've experimented with making it easier to provide camera settings via scene graph, rather than solely at the application/viewer level. The aim of this work to make it possible to load a scene graph, such as from the vsgXchange/Assimp loader that have camera settings provided in them as nodes, and then utilize these when setting a viewer level cameras.
To achieve this functionality I've changed
vsg::Camera so that it now subclass from vsg::Node rather than vsg::Object. This enables users to just add a vsg::Camera directly as child in the scene graph. I've also added serialize support so you can read/write them as part of the scene graph. I have also added a std::string name member variable to vsg::Camera to allow you to give a string name to cameras so they can be later located in searches.
To help locate the cameras in the scene graph I have added a vsg::FindCameras visitor, and to streamline the creation and visitation of the scene graph I've add new
vsg::visit<> templated function so to find all the cameras and then print out where in the scene graph they were found you just need to do:
auto scene_cameras = vsg::visit<vsg::FindCameras>(scenegraph).cameras;
for(auto& [nodePath, camera] : scene_cameras)
{
std::cout<<"\ncamera = "<<camera<<", "<<camera->name<<" :";
for(auto& node : nodePath) std::cout<<" "<<node;
std::cout<<std::endl;
}
The vsg::visit<> template function is something that just popped up as an idea for streamlining the Visitor usage, but isn't limited to camera related functionality,
it should be useable in number of places for making visitor usage more
expressive and streamlined.
I have also added support for mapping Assimp's aiCamera objects to equivalent vsg::Camera objects placing them under the appropriate transforms in the scene graph. To illustrate this all in action I've also created a new
vsgcameras example, which using the above code and loading file via vsgXchange/Assimp we see on the console:
$ vsgcameras ./FBX/global_settings.fbx
camera = ref_ptr<vsg::Camera>(vsg::Camera 0x55a2d1335d40), Camera.001 : ref_ptr<vsg::Object>(vsg::MatrixTransform 0x5
5a2d133d910) ref_ptr<vsg::Object>(vsg::StateGroup 0x55a2d1335c80) ref_ptr<vsg::Object>(vsg::MatrixTransform 0x55a2d12
bfc20) ref_ptr<vsg::Object>(vsg::MatrixTransform 0x55a2d13503e0) ref_ptr<vsg::Object>(vsg::Camera 0x55a2d1335d40)
camera = ref_ptr<vsg::Camera>(vsg::Camera 0x55a2d1335de0), Camera : ref_ptr<vsg::Object>(vsg::MatrixTransform 0x55a2d
133d910) ref_ptr<vsg::Object>(vsg::StateGroup 0x55a2d1335c80) ref_ptr<vsg::Object>(vsg::MatrixTransform 0x55a2d12bfc2
0) ref_ptr<vsg::Object>(vsg::MatrixTransform 0x55a2d12bfce0) ref_ptr<vsg::Object>(vsg::Camera 0x55a2d1335de0)
Using a single RenderGraph, with both Views separated by a ClearAttachemnts
The new vsgcamears also also creates an event handler that maps a viewer's View's Camera's ViewMatrix to the location of the of in scene graph cameras in response to 1 2 etc. key presses. Pressing 0 returns to the default viewing position.
To help with tracking moving cameras in the scene graph I've add a vsg::ViewTrackObject ViewMatrix subclass so you use the nodePath that locates an in scene graph camera in conjunction with vsg::computeTransform(nodePath)so the View will automatically be updated on each frame - so there is no need to manually updated. This can be used from having a View that tracks a camera on a robot located in scene and moving around.
All these changes can be found in the CameraNode branches of VulkanSceneGraph, vsgXchange and vsgExamples:
The vsgcameras examples doesn't yet doesn't yet demonstrate all the functionality I want it to, at the core VSG and vsgXchange level I think we're now mostly there. The additions to vsgcameras I am planning to use of the vsg::ViewTrackObject to bind View's to track objects and cameras in the scene graph.
I am open to suggestions of better names for vsg::ViewTrackObject and enhancements with the vsg::visit<> template function, vsg::Camera, so let me know what you think.
Cheers,
Robert.