-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Beef up sessions and scenarios #288
Comments
Here's a bit of a mockup of a new interface I'm planning: Before
#define TESTAPP_DATA_PHYS_SHAPES 1, \
idPhysShapes
struct PlPhysShapes
{
PipelineDef<EStgIntr> spawnRequest {"spawnRequest - Spawned shapes"};
PipelineDef<EStgIntr> spawnedEnts {"spawnedEnts"};
PipelineDef<EStgRevd> ownedEnts {"ownedEnts"};
};
Session setup_phys_shapes(
TopTaskBuilder& rBuilder,
ArrayView<entt::any> const topData,
Session const& scene,
Session const& commonScene,
Session const& physics,
MaterialId const materialId)
{
OSP_DECLARE_GET_DATA_IDS(commonScene, TESTAPP_DATA_COMMON_SCENE);
OSP_DECLARE_GET_DATA_IDS(physics, TESTAPP_DATA_PHYSICS);
auto const tgScn = scene .get_pipelines<PlScene>();
auto const tgCS = commonScene .get_pipelines<PlCommonScene>();
auto const tgPhy = physics .get_pipelines<PlPhysics>();
Session out;
OSP_DECLARE_CREATE_DATA_IDS(out, topData, TESTAPP_DATA_PHYS_SHAPES);
auto const tgShSp = out.create_pipelines<PlPhysShapes>(rBuilder);
rBuilder.pipeline(tgShSp.spawnRequest) .parent(tgScn.update);
rBuilder.pipeline(tgShSp.spawnedEnts) .parent(tgScn.update);
rBuilder.pipeline(tgShSp.ownedEnts) .parent(tgScn.update);
top_emplace< ACtxPhysShapes > (topData, idPhysShapes, ACtxPhysShapes{ .m_materialId = materialId });
rBuilder.task()
.name ("Schedule Shape spawn")
.schedules ({tgShSp.spawnRequest(Schedule_)})
.sync_with ({tgScn.update(Run)})
.push_to (out.m_tasks)
.args ({ idPhysShapes })
.func([] (ACtxPhysShapes& rPhysShapes) noexcept -> TaskActions
{
return rPhysShapes.m_spawnRequest.empty() ? TaskAction::Cancel : TaskActions{};
});
// ...
#define SCENE_SESSIONS scene, commonScene, physics, physShapes, droppers, bounds, newton, nwtGravSet, nwtGrav, physShapesNwt
#define RENDERER_SESSIONS sceneRenderer, magnumScene, cameraCtrl, cameraFree, shVisual, shFlat, shPhong, camThrow, shapeDraw, cursor
using namespace testapp::scenes;
auto const defaultPkg = rTestApp.m_defaultPkg;
auto const application = rTestApp.m_application;
auto & rTopData = rTestApp.m_topData;
TopTaskBuilder builder{rTestApp.m_tasks, rTestApp.m_scene.m_edges, rTestApp.m_taskData};
auto & [SCENE_SESSIONS] = resize_then_unpack<10>(rTestApp.m_scene.m_sessions);
// Compose together lots of Sessions
scene = setup_scene (builder, rTopData, application);
commonScene = setup_common_scene (builder, rTopData, scene, application, defaultPkg);
physics = setup_physics (builder, rTopData, scene, commonScene);
physShapes = setup_phys_shapes (builder, rTopData, scene, commonScene, physics, sc_matPhong);
// ...
After
struct FIPhysShapes
{
struct DataIds
{
TopDataId physShapes;
};
struct Pipelines
{
PipelineDef<EStgIntr> spawnRequest {"spawnRequest - Spawned shapes"};
PipelineDef<EStgIntr> spawnedEnts {"spawnedEnts"};
PipelineDef<EStgRevd> ownedEnts {"ownedEnts"};
};
};
void ft_phys_shapes( FeatureBuilder fb )
{
fb.name("Physics Shapes");
auto [diScn, plScn] = fb.use_interface<FIScene>();
auto [diCS, plCS] = fb.use_interface<FICommonScene>();
auto [diPhy, plPhy] = fb.use_interface<FIGenericPhysics>();
auto [dPhSh, lPhSh] = fb.implement_interface<FIPhysShapes>();
fb.pipeline(lPhSh.spawnRequest) .parent(plScn.update);
fb.pipeline(lPhSh.spawnedEnts) .parent(plScn.update);
fb.pipeline(lPhSh.ownedEnts) .parent(plScn.update);
fb.data(dPhSh.physShapes).emplace< ACtxPhysShapes >( ACtxPhysShapes{ .m_materialId = materialId } );
fb.task()
.name ("Schedule Shape spawn")
.schedules ({lPhSh.spawnRequest(Schedule_)})
.sync_with ({plScn.update(Run)})
.args ({ dPhSh.physShapes })
.func([] (ACtxPhysShapes& rPhysShapes) noexcept -> TaskActions
{
return rPhysShapes.m_spawnRequest.empty() ? TaskAction::Cancel : TaskActions{};
});
// ...
auto ctxBuilder = rTestApp.builder().create_context();
rTopData.m_currentScene = ctxBuilder.context_id();
ctxBuilder.add_feature(&ft_scene);
ctxBuilder.add_feature(&ft_scene_common);
ctxBuilder.add_feature(&ft_physics);
ctxBuilder.add_feature(&ft_phys_shapes);
// ...
|
putting this here to not be so dependent on discord. A couple iterations later: https://godbolt.org/z/Gb3GvPqar
Calls to auto const gc_ftrPhysShapes = feature_def([] (FeatureBuilder& rBuilder, Implement<FIPhysShapes> phySh, DependOn<FIScene> scn, DependOn<FIGenericPhysics> phys)
{
// Initialize values of TopData (top_emplace),
// setup pipelines (rBuilder.pipeline(...).parent(...)),
// and setup tasks here
}); quoting my previous comment:
|
A few related things are required that are closely related:
A) Allow changing scenarios while the window is open
Requires a bit of refactoring to scenarios.
Sessions for keeping the window open (setup_window_app and setup_magnum) are already managed separately, found in main.cpp.
osp-magnum/src/testapp/main.cpp
Lines 270 to 271 in c42ed31
This means that scene-related sessions (setup_scene, setup_common_scene, setup_scene_renderer, setup_magnum_scene, setup_camera_ctrl, etc...) can be closed and new ones can be loaded in while the window stays open.
When a session is requested to change...
.cleanup(Run_)
) so data can be destructed gracefully.B) Have some API to open new sessions
Imagine starting with just a main menu session that only uses UI. The user can then select and load up a flight scenario, launching new sessions (this is why sessions are called sessions).
Challenges:
Imagine a case where the user is sitting in a mission control room, and has screens with live camera views open of multiple missions distant from each other, all being simulated in separate scenes. This favors the compositor solution, where the currently visible scene can call render into the required flight scenes.
In a more finalized product, a list of flights scenes, their sessions, and additional data about them (eg: associations with the universe) can be stored somewhere at the top-level of the application. Renderers can then be optionally assigned to them for the application's compositor function to call into.
C) Automatic runtime Session dependencies
Right now, dependencies between sessions are intended to be easy to write and copy-paste around manually, relying on lists of variable names using macros. None of this can really be reconfigured to create custom scenarios at runtime.
Note how similar the physics test scenario and the vehicles test scenario is. You can just put
if
statements around the vehicle-related setup functions to turn the vehicles test scenario into the physics test scenario conditionally. It's possible to make one mega-sized scenario instead individual physics/vehicle/universe ones, but this can probably be done in a smarter way for the "more finalized product."Ideally, the interface for this would be to just list off sessions, and dependencies will be automatically resolved. To do this, we need some way to identify/lookup sessions and determine what dependencies they require (make a trait system :3). A bunch of tables of data works for sure, but part of the problem is how to write a nice interface around it.
This might require a full rewrite of all the session stuff. Sessions are just groups of tasks, data, and pipelines, and maybe dealing with them individually 'per-scene' and removing sessions entirely may be easier for an automated solution. we'll see.
The text was updated successfully, but these errors were encountered: