From 4e213f46b158165f0a17d7b4314f6dfb28c14b48 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 30 Mar 2024 23:37:58 -0400 Subject: [PATCH 1/3] [WIP] Build lander game --- .gitignore | 1 + src/osp/util/logging.h | 2 +- src/testapp/main.cpp | 3 +- src/testapp/scenarios.cpp | 95 ++++++++++ src/testapp/sessions/universe.cpp | 305 ++++++++++++++++++++++++++++++ src/testapp/sessions/universe.h | 9 + 6 files changed, 413 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e5babb84..58160bed 100644 --- a/.gitignore +++ b/.gitignore @@ -12,5 +12,6 @@ OSP-MAGNUM.cbp CMakeSettings.json out/ .vs/ +.vscode/ build/ .vscode/ diff --git a/src/osp/util/logging.h b/src/osp/util/logging.h index 5109501d..44634269 100644 --- a/src/osp/util/logging.h +++ b/src/osp/util/logging.h @@ -24,7 +24,7 @@ */ #pragma once -#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO +#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG #include namespace osp diff --git a/src/testapp/main.cpp b/src/testapp/main.cpp index fd01a140..79eed794 100644 --- a/src/testapp/main.cpp +++ b/src/testapp/main.cpp @@ -111,7 +111,7 @@ int main(int argc, char** argv) // Command line argument parsing Corrade::Utility::Arguments args; args.addSkippedPrefix("magnum", "Magnum options") - .addOption("scene", "none") .setHelp("scene", "Set the scene to launch") + .addOption("scene", "lander") .setHelp("scene", "Set the scene to launch") .addOption("config") .setHelp("config", "path to configuration file to use") .addBooleanOption("norepl") .setHelp("norepl", "don't enter read, evaluate, print, loop.") .addBooleanOption("log-exec") .setHelp("log-exec", "Log Task/Pipeline Execution (Extremely chatty!)") @@ -298,6 +298,7 @@ void start_magnum_async(int argc, char** argv) g_testApp.close_session(g_testApp.m_windowApp); OSP_LOG_INFO("Closed Magnum Application"); + std::exit(0); }); g_magnumThread.swap(t); } diff --git a/src/testapp/scenarios.cpp b/src/testapp/scenarios.cpp index 7797f433..29c85802 100644 --- a/src/testapp/scenarios.cpp +++ b/src/testapp/scenarios.cpp @@ -446,6 +446,101 @@ static ScenarioMap_t make_scenarios() return setup_renderer; }); + add_scenario("lander", "Lander simulation game", [] (TestApp& rTestApp) -> RendererSetupFunc_t { + #define SCENE_SESSIONS scene, commonScene, uniCore, uniScnFrame, uniPlanet, physics, \ + prefabs, parts, signalsFloat, vehicleSpawn, vehicleSpawnVB, vehicles, \ + newton, vehicleSpawnNwt, nwtRocketSet, rocketsNwt, \ + machRocket, machRcsDriver + #define SCENE_SESSIONS_COUNT 18 + #define RENDERER_SESSIONS sceneRenderer, magnumScene, planetDraw, \ + cameraCtrl, cameraFree, shVisual, shFlat, shPhong, \ + prefabDraw, vehicleDraw, vehicleCtrl, cameraVehicle + #define RENDERER_SESSIONS_COUNT 12 + + 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(rTestApp.m_scene.m_sessions); + + scene = setup_scene(builder, rTopData, application); + commonScene = setup_common_scene (builder, rTopData, scene, application, defaultPkg); + + auto const tgApp = application.get_pipelines< PlApplication >(); + uniCore = setup_uni_core (builder, rTopData, tgApp.mainLoop); + uniScnFrame = setup_uni_sceneframe (builder, rTopData, uniCore); + uniPlanet = setup_uni_landerplanet (builder, rTopData, uniCore, uniScnFrame); + + physics = setup_physics (builder, rTopData, scene, commonScene); + prefabs = setup_prefabs (builder, rTopData, application, scene, commonScene, physics); + parts = setup_parts (builder, rTopData, application, scene); + signalsFloat = setup_signals_float (builder, rTopData, scene, parts); + vehicleSpawn = setup_vehicle_spawn (builder, rTopData, scene); + vehicleSpawnVB = setup_vehicle_spawn_vb (builder, rTopData, application, scene, commonScene, prefabs, parts, vehicleSpawn, signalsFloat); + vehicles = setup_prebuilt_vehicles (builder, rTopData, application, scene); + + machRocket = setup_mach_rocket (builder, rTopData, scene, parts, signalsFloat); + machRcsDriver = setup_mach_rcsdriver (builder, rTopData, scene, parts, signalsFloat); + + newton = setup_newton (builder, rTopData, scene, commonScene, physics); + vehicleSpawnNwt = setup_vehicle_spawn_newton(builder, rTopData, application, commonScene, physics, prefabs, parts, vehicleSpawn, newton); + nwtRocketSet = setup_newton_factors (builder, rTopData); + rocketsNwt = setup_rocket_thrust_newton(builder, rTopData, scene, commonScene, physics, prefabs, parts, signalsFloat, newton, nwtRocketSet); + + + OSP_DECLARE_GET_DATA_IDS(vehicleSpawn, TESTAPP_DATA_VEHICLE_SPAWN); + OSP_DECLARE_GET_DATA_IDS(vehicleSpawnVB, TESTAPP_DATA_VEHICLE_SPAWN_VB); + OSP_DECLARE_GET_DATA_IDS(vehicles, TESTAPP_DATA_TEST_VEHICLES); + + auto &rVehicleSpawn = top_get (rTopData, idVehicleSpawn); + auto &rVehicleSpawnVB = top_get (rTopData, idVehicleSpawnVB); + auto &rPrebuiltVehicles = top_get (rTopData, idPrebuiltVehicles); + + rVehicleSpawn.spawnRequest.push_back( + { + .position = {30.0f, 0.0f, 0.0f}, + .velocity = {0.0f, 0.0f, 0.0f}, + .rotation = {} + }); + rVehicleSpawnVB.dataVB.push_back(rPrebuiltVehicles[gc_pbvSimpleCommandServiceModule].get()); + + RendererSetupFunc_t const setup_renderer = [] (TestApp& rTestApp) -> void + { + auto const application = rTestApp.m_application; + auto const windowApp = rTestApp.m_windowApp; + auto const magnum = rTestApp.m_magnum; + auto & rTopData = rTestApp.m_topData; + + TopTaskBuilder builder{rTestApp.m_tasks, rTestApp.m_renderer.m_edges, rTestApp.m_taskData}; + + auto & [SCENE_SESSIONS] = unpack(rTestApp.m_scene.m_sessions); + auto & [RENDERER_SESSIONS] = resize_then_unpack(rTestApp.m_renderer.m_sessions); + + sceneRenderer = setup_scene_renderer (builder, rTopData, application, windowApp, commonScene); + create_materials(rTopData, sceneRenderer, sc_materialCount); + + magnumScene = setup_magnum_scene (builder, rTopData, application, rTestApp.m_windowApp, sceneRenderer, rTestApp.m_magnum, scene, commonScene); + cameraCtrl = setup_camera_ctrl (builder, rTopData, windowApp, sceneRenderer, magnumScene); + // cameraFree = setup_camera_free (builder, rTopData, windowApp, scene, cameraCtrl); + shVisual = setup_shader_visualizer (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matVisualizer); + // shFlat = setup_shader_flat (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matFlat); + shPhong = setup_shader_phong (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matPhong); + planetDraw = setup_testplanets_draw (builder, rTopData, windowApp, sceneRenderer, cameraCtrl, commonScene, uniCore, uniScnFrame, uniPlanet, sc_matVisualizer, sc_matFlat); + + prefabDraw = setup_prefab_draw (builder, rTopData, application, windowApp, sceneRenderer, commonScene, prefabs, sc_matPhong); + vehicleDraw = setup_vehicle_spawn_draw (builder, rTopData, sceneRenderer, vehicleSpawn); + vehicleCtrl = setup_vehicle_control (builder, rTopData, windowApp, scene, parts, signalsFloat); + cameraVehicle = setup_camera_vehicle (builder, rTopData, windowApp, scene, sceneRenderer, commonScene, physics, parts, cameraCtrl, vehicleCtrl); + + setup_magnum_draw(rTestApp, scene, sceneRenderer, magnumScene); + }; + return setup_renderer; + }); + return scenarioMap; } diff --git a/src/testapp/sessions/universe.cpp b/src/testapp/sessions/universe.cpp index 2537defd..5d31c3b7 100644 --- a/src/testapp/sessions/universe.cpp +++ b/src/testapp/sessions/universe.cpp @@ -86,7 +86,103 @@ Session setup_uni_sceneframe( } // setup_uni_sceneframe +Session setup_uni_landerplanet( + TopTaskBuilder& rBuilder, + ArrayView topData, + Session const& uniCore, + Session const& uniScnFrame) +{ + using CoSpaceIdVec_t = std::vector; + using Corrade::Containers::Array; + + OSP_DECLARE_GET_DATA_IDS(uniCore, TESTAPP_DATA_UNI_CORE); + OSP_DECLARE_GET_DATA_IDS(uniScnFrame, TESTAPP_DATA_UNI_SCENEFRAME); + + auto const tgUCore = uniCore .get_pipelines(); + auto const tgUSFrm = uniScnFrame.get_pipelines(); + + auto &rUniverse = top_get< Universe >(topData, idUniverse); + + constexpr int precision = 10; + constexpr int planetCount = 1; + + // Create coordinate spaces + CoSpaceId const mainSpace = rUniverse.m_coordIds.create(); + std::vector satSurfaceSpaces(planetCount); + rUniverse.m_coordIds.create(satSurfaceSpaces.begin(), satSurfaceSpaces.end()); + rUniverse.m_coordCommon.resize(rUniverse.m_coordIds.capacity()); + + CoSpaceCommon &rMainSpaceCommon = rUniverse.m_coordCommon[mainSpace]; + rMainSpaceCommon.m_satCount = planetCount; + rMainSpaceCommon.m_satCapacity = planetCount; + + // Associate each planet satellite with their surface coordinate space + for (SatId satId = 0; satId < planetCount; ++satId) + { + CoSpaceId const surfaceSpaceId = satSurfaceSpaces[satId]; + CoSpaceCommon &rCommon = rUniverse.m_coordCommon[surfaceSpaceId]; + rCommon.m_parent = mainSpace; + rCommon.m_parentSat = satId; + } + + // Coordinate space data is a single allocation partitioned to hold positions, velocities, and + // rotations. + // TODO: Alignment is needed for SIMD (not yet implemented). see Corrade alignedAlloc + + std::size_t bytesUsed = 0; + + // Positions and velocities are arranged as XXXX... YYYY... ZZZZ... + partition(bytesUsed, planetCount, rMainSpaceCommon.m_satPositions[0]); + partition(bytesUsed, planetCount, rMainSpaceCommon.m_satPositions[1]); + partition(bytesUsed, planetCount, rMainSpaceCommon.m_satPositions[2]); + partition(bytesUsed, planetCount, rMainSpaceCommon.m_satVelocities[0]); + partition(bytesUsed, planetCount, rMainSpaceCommon.m_satVelocities[1]); + partition(bytesUsed, planetCount, rMainSpaceCommon.m_satVelocities[2]); + + // Rotations use XYZWXYZWXYZWXYZW... + partition(bytesUsed, planetCount, rMainSpaceCommon.m_satRotations[0], + rMainSpaceCommon.m_satRotations[1], + rMainSpaceCommon.m_satRotations[2], + rMainSpaceCommon.m_satRotations[3]); + // Allocate data for all planets + rMainSpaceCommon.m_data = Array{Corrade::NoInit, bytesUsed}; + + // Create easily accessible array views for each component + auto const [x, y, z] = sat_views(rMainSpaceCommon.m_satPositions, rMainSpaceCommon.m_data, planetCount); + auto const [vx, vy, vz] = sat_views(rMainSpaceCommon.m_satVelocities, rMainSpaceCommon.m_data, planetCount); + auto const [qx, qy, qz, qw] = sat_views(rMainSpaceCommon.m_satRotations, rMainSpaceCommon.m_data, planetCount); + + for (std::size_t i = 0; i < planetCount; ++i) + { + // Assign each planet random positions and velocities + x[i] = 0; + y[i] = 0; + z[i] = 0; + vx[i] = 0; + vy[i] = 0; + vz[i] = 0; + + // No rotation + qx[i] = 0.0; + qy[i] = 0.0; + qz[i] = 0.0; + qw[i] = 1.0; + } + + auto &rScnFrame = top_get(topData, idScnFrame); + rScnFrame.m_parent = mainSpace; + rScnFrame.m_position = math::mul_2pow({400, 400, 400}, precision); + + Session out; + OSP_DECLARE_CREATE_DATA_IDS(out, topData, TESTAPP_DATA_UNI_PLANETS); + + top_emplace< CoSpaceId > (topData, idPlanetMainSpace, mainSpace); + top_emplace< float > (topData, tgUniDeltaTimeIn, 1.0f / 60.0f); + top_emplace< CoSpaceIdVec_t > (topData, idSatSurfaceSpaces, std::move(satSurfaceSpaces)); + + return out; +} Session setup_uni_testplanets( TopTaskBuilder& rBuilder, @@ -318,6 +414,215 @@ struct PlanetDraw MaterialId matAxis; }; +Session setup_landerplanet_draw( + TopTaskBuilder& rBuilder, + ArrayView const topData, + Session const& windowApp, + Session const& sceneRenderer, + Session const& cameraCtrl, + Session const& commonScene, + Session const& uniCore, + Session const& uniScnFrame, + Session const& uniLanderPlanet, + MaterialId const matPlanets, + MaterialId const matAxis +) { + OSP_DECLARE_GET_DATA_IDS(commonScene, TESTAPP_DATA_COMMON_SCENE); + OSP_DECLARE_GET_DATA_IDS(sceneRenderer, TESTAPP_DATA_SCENE_RENDERER); + OSP_DECLARE_GET_DATA_IDS(cameraCtrl, TESTAPP_DATA_CAMERA_CTRL); + OSP_DECLARE_GET_DATA_IDS(uniCore, TESTAPP_DATA_UNI_CORE); + OSP_DECLARE_GET_DATA_IDS(uniScnFrame, TESTAPP_DATA_UNI_SCENEFRAME); + OSP_DECLARE_GET_DATA_IDS(uniLanderPlanet, TESTAPP_DATA_UNI_PLANETS); + + auto const tgWin = windowApp .get_pipelines(); + auto const tgScnRdr = sceneRenderer .get_pipelines(); + auto const tgCmCt = cameraCtrl .get_pipelines(); + auto const tgUSFrm = uniScnFrame .get_pipelines(); + + Session out; + + auto const [idPlanetDraw] = out.acquire_data<1>(topData); + auto &rPlanetDraw = top_emplace(topData, idPlanetDraw); + rPlanetDraw.matPlanets = matPlanets; + rPlanetDraw.matAxis = matAxis; + + rBuilder.task() + .name ("Position SceneFrame center to Camera Controller target") + .run_on ({tgWin.inputs(Run)}) + .sync_with ({tgCmCt.camCtrl(Ready), tgUSFrm.sceneFrame(Modify)}) + .push_to (out.m_tasks) + .args ({ idCamCtrl, idScnFrame }) + .func([] (ACtxCameraController& rCamCtrl, SceneFrame& rScnFrame) noexcept + { + if ( ! rCamCtrl.m_target.has_value()) + { + return; + } + Vector3 &rCamPl = rCamCtrl.m_target.value(); + + // check origin translation + // ADL used for Magnum::Math::sign/floor/abs + float const maxDist = 512.0f; + Vector3 const translate = sign(rCamPl) * floor(abs(rCamPl) / maxDist) * maxDist; + + if ( ! translate.isZero()) + { + rCamCtrl.m_transform.translation() -= translate; + rCamPl -= translate; + + // a bit janky to modify universe stuff directly here, but it works lol + Vector3 const rotated = Quaternion(rScnFrame.m_rotation).transformVector(translate); + rScnFrame.m_position += Vector3g(math::mul_2pow(rotated, rScnFrame.m_precision)); + } + + rScnFrame.m_scenePosition = Vector3g(math::mul_2pow(rCamCtrl.m_target.value(), rScnFrame.m_precision)); + }); + + rBuilder.task() + .name ("Resync test planets, create DrawEnts") + .run_on ({tgWin.resync(Run)}) + .sync_with ({tgScnRdr.drawEntResized(ModifyOrSignal)}) + .push_to (out.m_tasks) + .args ({ idScnRender, idPlanetDraw, idUniverse, idPlanetMainSpace}) + .func([] (ACtxSceneRender& rScnRender, PlanetDraw& rPlanetDraw, Universe& rUniverse, CoSpaceId const planetMainSpace) noexcept + { + CoSpaceCommon &rMainSpace = rUniverse.m_coordCommon[planetMainSpace]; + + rPlanetDraw.drawEnts.resize(rMainSpace.m_satCount, lgrn::id_null()); + + rScnRender.m_drawIds.create(rPlanetDraw.drawEnts .begin(), rPlanetDraw.drawEnts .end()); + rScnRender.m_drawIds.create(rPlanetDraw.axis .begin(), rPlanetDraw.axis .end()); + rPlanetDraw.attractor = rScnRender.m_drawIds.create(); + }); + + rBuilder.task() + .name ("Resync test planets, add mesh and material") + .run_on ({tgWin.resync(Run)}) + .sync_with ({tgScnRdr.drawEntResized(Done), tgScnRdr.materialDirty(Modify_), tgScnRdr.entMeshDirty(Modify_)}) + .push_to (out.m_tasks) + .args ({ idDrawing, idScnRender, idNMesh, idPlanetDraw, idUniverse, idPlanetMainSpace}) + .func([] (ACtxDrawing& rDrawing, ACtxSceneRender& rScnRender, NamedMeshes& rNMesh, PlanetDraw& rPlanetDraw, Universe& rUniverse, CoSpaceId const planetMainSpace) noexcept + { + CoSpaceCommon &rMainSpace = rUniverse.m_coordCommon[planetMainSpace]; + + Material &rMatPlanet = rScnRender.m_materials[rPlanetDraw.matPlanets]; + Material &rMatAxis = rScnRender.m_materials[rPlanetDraw.matAxis]; + + MeshId const sphereMeshId = rNMesh.m_shapeToMesh.at(EShape::Sphere); + MeshId const cubeMeshId = rNMesh.m_shapeToMesh.at(EShape::Box); + + for (std::size_t i = 0; i < rMainSpace.m_satCount; ++i) + { + DrawEnt const drawEnt = rPlanetDraw.drawEnts[i]; + + rScnRender.m_mesh[drawEnt] = rDrawing.m_meshRefCounts.ref_add(sphereMeshId); + rScnRender.m_meshDirty.push_back(drawEnt); + rScnRender.m_visible.set(std::size_t(drawEnt)); + rScnRender.m_opaque.set(std::size_t(drawEnt)); + rMatPlanet.m_ents.set(std::size_t(drawEnt)); + rMatPlanet.m_dirty.push_back(drawEnt); + } + + rScnRender.m_mesh[rPlanetDraw.attractor] = rDrawing.m_meshRefCounts.ref_add(sphereMeshId); + rScnRender.m_meshDirty.push_back(rPlanetDraw.attractor); + rScnRender.m_visible.set(std::size_t(rPlanetDraw.attractor)); + rScnRender.m_opaque.set(std::size_t(rPlanetDraw.attractor)); + rMatPlanet.m_ents.set(std::size_t(rPlanetDraw.attractor)); + rMatPlanet.m_dirty.push_back(rPlanetDraw.attractor); + + for (DrawEnt const drawEnt : rPlanetDraw.axis) + { + rScnRender.m_mesh[drawEnt] = rDrawing.m_meshRefCounts.ref_add(cubeMeshId); + rScnRender.m_meshDirty.push_back(drawEnt); + rScnRender.m_visible.set(std::size_t(drawEnt)); + rScnRender.m_opaque.set(std::size_t(drawEnt)); + rMatAxis.m_ents.set(std::size_t(drawEnt)); + rMatAxis.m_dirty.push_back(drawEnt); + } + + rScnRender.m_color[rPlanetDraw.axis[0]] = {1.0f, 0.0f, 0.0f, 1.0f}; + rScnRender.m_color[rPlanetDraw.axis[1]] = {0.0f, 1.0f, 0.0f, 1.0f}; + rScnRender.m_color[rPlanetDraw.axis[2]] = {0.0f, 0.0f, 1.0f, 1.0f}; + }); + + rBuilder.task() + .name ("Reposition test planet DrawEnts") + .run_on ({tgScnRdr.render(Run)}) + .sync_with ({tgScnRdr.drawTransforms(Modify_), tgScnRdr.drawEntResized(Done), tgCmCt.camCtrl(Ready), tgUSFrm.sceneFrame(Modify)}) + .push_to (out.m_tasks) + .args ({ idDrawing, idScnRender, idPlanetDraw, idUniverse, idScnFrame, idPlanetMainSpace}) + .func([] (ACtxDrawing& rDrawing, ACtxSceneRender& rScnRender, PlanetDraw& rPlanetDraw, Universe& rUniverse, SceneFrame const& rScnFrame, CoSpaceId const planetMainSpace) noexcept + { + + CoSpaceCommon &rMainSpace = rUniverse.m_coordCommon[planetMainSpace]; + auto const [x, y, z] = sat_views(rMainSpace.m_satPositions, rMainSpace.m_data, rMainSpace.m_satCount); + auto const [qx, qy, qz, qw] = sat_views(rMainSpace.m_satRotations, rMainSpace.m_data, rMainSpace.m_satCount); + + // Calculate transform from universe to area/local-space for rendering. + // This can be generalized by finding a common ancestor within the tree + // of coordinate spaces. Since there's only two possibilities, an if + // statement works. + CoordTransformer mainToArea; + if (rScnFrame.m_parent == planetMainSpace) + { + mainToArea = coord_parent_to_child(rMainSpace, rScnFrame); + } + else + { + CoSpaceId const landedId = rScnFrame.m_parent; + CoSpaceCommon &rLanded = rUniverse.m_coordCommon[landedId]; + + CoSpaceTransform const landedTf = coord_get_transform(rLanded, rLanded, x, y, z, qx, qy, qz, qw); + CoordTransformer const mainToLanded = coord_parent_to_child(rMainSpace, landedTf); + CoordTransformer const landedToArea = coord_parent_to_child(landedTf, rScnFrame); + + mainToArea = coord_composite(landedToArea, mainToLanded); + } + Quaternion const mainToAreaRot{mainToArea.rotation()}; + + float const scale = math::mul_2pow(1.0f, -rMainSpace.m_precision); + + Vector3 const attractorPos = Vector3(mainToArea.transform_position({0, 0, 0})) * scale; + + // Attractor + rScnRender.m_drawTransform[rPlanetDraw.attractor] + = Matrix4::translation(attractorPos) + * Matrix4{mainToAreaRot.toMatrix()} + * Matrix4::scaling({500, 500, 500}); + + rScnRender.m_drawTransform[rPlanetDraw.axis[0]] + = Matrix4::translation(attractorPos) + * Matrix4{mainToAreaRot.toMatrix()} + * Matrix4::scaling({500000, 10, 10}); + rScnRender.m_drawTransform[rPlanetDraw.axis[1]] + = Matrix4::translation(attractorPos) + * Matrix4{mainToAreaRot.toMatrix()} + * Matrix4::scaling({10, 500000, 10}); + rScnRender.m_drawTransform[rPlanetDraw.axis[2]] + = Matrix4::translation(attractorPos) + * Matrix4{mainToAreaRot.toMatrix()} + * Matrix4::scaling({10, 10, 500000}); + + for (std::size_t i = 0; i < rMainSpace.m_satCount; ++i) + { + Vector3g const relative = mainToArea.transform_position({x[i], y[i], z[i]}); + Vector3 const relativeMeters = Vector3(relative) * scale; + + Quaterniond const rot{{qx[i], qy[i], qz[i]}, qw[i]}; + + DrawEnt const drawEnt = rPlanetDraw.drawEnts[i]; + + rScnRender.m_drawTransform[drawEnt] + = Matrix4::translation(relativeMeters) + * Matrix4::scaling({200, 200, 200}) + * Matrix4{(mainToAreaRot * Quaternion{rot}).toMatrix()}; + } + + }); + + return out; +} + Session setup_testplanets_draw( TopTaskBuilder& rBuilder, ArrayView const topData, diff --git a/src/testapp/sessions/universe.h b/src/testapp/sessions/universe.h index 94039d16..30a1064f 100644 --- a/src/testapp/sessions/universe.h +++ b/src/testapp/sessions/universe.h @@ -47,6 +47,15 @@ osp::Session setup_uni_sceneframe( osp::ArrayView topData, osp::Session const& uniCore); +/** + * @brief A single planet setup for landing on + */ +osp::Session setup_uni_landerplanet( + osp::TopTaskBuilder& rBuilder, + osp::ArrayView topData, + osp::Session const& uniCore, + osp::Session const& uniScnFrame); + /** * @brief Unrealistic planets test, allows SceneFrame to move around and get captured into planets */ From 9dbe7394737647a95dfa057d0ae9c50fba026a9c Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 23 Jun 2024 10:19:58 -0400 Subject: [PATCH 2/3] Add some experimental changes to get camera movement to work --- src/testapp/scenarios.cpp | 2 +- src/testapp/sessions/universe.cpp | 12 ++++++++---- src/testapp/sessions/universe.h | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/testapp/scenarios.cpp b/src/testapp/scenarios.cpp index 29c85802..b07cb079 100644 --- a/src/testapp/scenarios.cpp +++ b/src/testapp/scenarios.cpp @@ -529,7 +529,7 @@ static ScenarioMap_t make_scenarios() shVisual = setup_shader_visualizer (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matVisualizer); // shFlat = setup_shader_flat (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matFlat); shPhong = setup_shader_phong (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matPhong); - planetDraw = setup_testplanets_draw (builder, rTopData, windowApp, sceneRenderer, cameraCtrl, commonScene, uniCore, uniScnFrame, uniPlanet, sc_matVisualizer, sc_matFlat); + planetDraw = setup_landerplanet_draw (builder, rTopData, windowApp, sceneRenderer, cameraCtrl, commonScene, uniCore, uniScnFrame, uniPlanet, sc_matVisualizer, sc_matFlat); prefabDraw = setup_prefab_draw (builder, rTopData, application, windowApp, sceneRenderer, commonScene, prefabs, sc_matPhong); vehicleDraw = setup_vehicle_spawn_draw (builder, rTopData, sceneRenderer, vehicleSpawn); diff --git a/src/testapp/sessions/universe.cpp b/src/testapp/sessions/universe.cpp index 5d31c3b7..2734c6ab 100644 --- a/src/testapp/sessions/universe.cpp +++ b/src/testapp/sessions/universe.cpp @@ -456,6 +456,7 @@ Session setup_landerplanet_draw( { if ( ! rCamCtrl.m_target.has_value()) { + OSP_LOG_INFO("Camera Controller target not set"); return; } Vector3 &rCamPl = rCamCtrl.m_target.value(); @@ -467,14 +468,17 @@ Session setup_landerplanet_draw( if ( ! translate.isZero()) { - rCamCtrl.m_transform.translation() -= translate; - rCamPl -= translate; + // OSP_LOG_INFO("Translate Camera Controller target by {},{},{}", translate.x(), translate.y(), translate.z()); + // rCamCtrl.m_transform.translation() -= translate; + // rCamPl -= translate; // a bit janky to modify universe stuff directly here, but it works lol - Vector3 const rotated = Quaternion(rScnFrame.m_rotation).transformVector(translate); - rScnFrame.m_position += Vector3g(math::mul_2pow(rotated, rScnFrame.m_precision)); + // Vector3 const rotated = Quaternion(rScnFrame.m_rotation).transformVector(translate); + // OSP_LOG_INFO("Translate SceneFrame by {},{},{}", rotated.x(), rotated.y(), rotated.z()); + // rScnFrame.m_position += Vector3g(math::mul_2pow(rotated, rScnFrame.m_precision)); } + // OSP_LOG_INFO("SceneFrame position: {},{},{}", rScnFrame.m_position.x(), rScnFrame.m_position.y(), rScnFrame.m_position.z()); rScnFrame.m_scenePosition = Vector3g(math::mul_2pow(rCamCtrl.m_target.value(), rScnFrame.m_precision)); }); diff --git a/src/testapp/sessions/universe.h b/src/testapp/sessions/universe.h index 30a1064f..577cca0e 100644 --- a/src/testapp/sessions/universe.h +++ b/src/testapp/sessions/universe.h @@ -65,6 +65,21 @@ osp::Session setup_uni_testplanets( osp::Session const& uniCore, osp::Session const& uniScnFrame); +/** + * @brief Draw universe, specifically designed for setup_uni_landerplanet + */ +osp::Session setup_landerplanet_draw( + osp::TopTaskBuilder& rBuilder, + osp::ArrayView topData, + osp::Session const& windowApp, + osp::Session const& sceneRenderer, + osp::Session const& cameraCtrl, + osp::Session const& commonScene, + osp::Session const& uniCore, + osp::Session const& uniScnFrame, + osp::Session const& uniTestPlanets, + osp::draw::MaterialId const matPlanets, + osp::draw::MaterialId const matAxis); /** * @brief Draw universe, specifically designed for setup_uni_test_planets From 2dfcdc598ada0ceea3079bd3ce7ce86aa6d35b84 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 23 Jun 2024 14:49:01 -0400 Subject: [PATCH 3/3] Move lander scenario into dedicated file * Move the scenario (involved moving some things into dedicated files like magnum.*) * Rebase to main --- src/testapp/main.cpp | 1 + src/testapp/scenarios.cpp | 227 +----------------------------- src/testapp/scenarios.h | 7 - src/testapp/scenarios/lander.cpp | 129 +++++++++++++++++ src/testapp/scenarios/lander.h | 11 ++ src/testapp/sessions/common.cpp | 1 + src/testapp/sessions/magnum.cpp | 121 ++++++++++++++++ src/testapp/sessions/magnum.h | 14 ++ src/testapp/sessions/universe.cpp | 18 +-- 9 files changed, 290 insertions(+), 239 deletions(-) create mode 100644 src/testapp/scenarios/lander.cpp create mode 100644 src/testapp/scenarios/lander.h diff --git a/src/testapp/main.cpp b/src/testapp/main.cpp index 79eed794..02fe9377 100644 --- a/src/testapp/main.cpp +++ b/src/testapp/main.cpp @@ -307,6 +307,7 @@ void load_a_bunch_of_stuff() { using namespace osp::restypes; using namespace Magnum; + using namespace testapp::scenes; using Primitives::ConeFlag; using Primitives::CylinderFlag; diff --git a/src/testapp/scenarios.cpp b/src/testapp/scenarios.cpp index b07cb079..d91a05cc 100644 --- a/src/testapp/scenarios.cpp +++ b/src/testapp/scenarios.cpp @@ -53,6 +53,8 @@ #include +#include "scenarios/lander.h" + using namespace adera; using namespace osp; using namespace osp::active; @@ -60,8 +62,6 @@ using namespace osp::active; namespace testapp { -static void setup_magnum_draw(TestApp& rTestApp, Session const& scene, Session const& sceneRenderer, Session const& magnumScene); - // MaterialIds hints which shaders should be used to draw a DrawEnt // DrawEnts can be assigned to multiple materials static constexpr auto sc_matVisualizer = draw::MaterialId(0); @@ -446,100 +446,9 @@ static ScenarioMap_t make_scenarios() return setup_renderer; }); - add_scenario("lander", "Lander simulation game", [] (TestApp& rTestApp) -> RendererSetupFunc_t { - #define SCENE_SESSIONS scene, commonScene, uniCore, uniScnFrame, uniPlanet, physics, \ - prefabs, parts, signalsFloat, vehicleSpawn, vehicleSpawnVB, vehicles, \ - newton, vehicleSpawnNwt, nwtRocketSet, rocketsNwt, \ - machRocket, machRcsDriver - #define SCENE_SESSIONS_COUNT 18 - #define RENDERER_SESSIONS sceneRenderer, magnumScene, planetDraw, \ - cameraCtrl, cameraFree, shVisual, shFlat, shPhong, \ - prefabDraw, vehicleDraw, vehicleCtrl, cameraVehicle - #define RENDERER_SESSIONS_COUNT 12 - - 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(rTestApp.m_scene.m_sessions); - - scene = setup_scene(builder, rTopData, application); - commonScene = setup_common_scene (builder, rTopData, scene, application, defaultPkg); - - auto const tgApp = application.get_pipelines< PlApplication >(); - uniCore = setup_uni_core (builder, rTopData, tgApp.mainLoop); - uniScnFrame = setup_uni_sceneframe (builder, rTopData, uniCore); - uniPlanet = setup_uni_landerplanet (builder, rTopData, uniCore, uniScnFrame); - - physics = setup_physics (builder, rTopData, scene, commonScene); - prefabs = setup_prefabs (builder, rTopData, application, scene, commonScene, physics); - parts = setup_parts (builder, rTopData, application, scene); - signalsFloat = setup_signals_float (builder, rTopData, scene, parts); - vehicleSpawn = setup_vehicle_spawn (builder, rTopData, scene); - vehicleSpawnVB = setup_vehicle_spawn_vb (builder, rTopData, application, scene, commonScene, prefabs, parts, vehicleSpawn, signalsFloat); - vehicles = setup_prebuilt_vehicles (builder, rTopData, application, scene); - - machRocket = setup_mach_rocket (builder, rTopData, scene, parts, signalsFloat); - machRcsDriver = setup_mach_rcsdriver (builder, rTopData, scene, parts, signalsFloat); - - newton = setup_newton (builder, rTopData, scene, commonScene, physics); - vehicleSpawnNwt = setup_vehicle_spawn_newton(builder, rTopData, application, commonScene, physics, prefabs, parts, vehicleSpawn, newton); - nwtRocketSet = setup_newton_factors (builder, rTopData); - rocketsNwt = setup_rocket_thrust_newton(builder, rTopData, scene, commonScene, physics, prefabs, parts, signalsFloat, newton, nwtRocketSet); - - - OSP_DECLARE_GET_DATA_IDS(vehicleSpawn, TESTAPP_DATA_VEHICLE_SPAWN); - OSP_DECLARE_GET_DATA_IDS(vehicleSpawnVB, TESTAPP_DATA_VEHICLE_SPAWN_VB); - OSP_DECLARE_GET_DATA_IDS(vehicles, TESTAPP_DATA_TEST_VEHICLES); - - auto &rVehicleSpawn = top_get (rTopData, idVehicleSpawn); - auto &rVehicleSpawnVB = top_get (rTopData, idVehicleSpawnVB); - auto &rPrebuiltVehicles = top_get (rTopData, idPrebuiltVehicles); - - rVehicleSpawn.spawnRequest.push_back( - { - .position = {30.0f, 0.0f, 0.0f}, - .velocity = {0.0f, 0.0f, 0.0f}, - .rotation = {} - }); - rVehicleSpawnVB.dataVB.push_back(rPrebuiltVehicles[gc_pbvSimpleCommandServiceModule].get()); - - RendererSetupFunc_t const setup_renderer = [] (TestApp& rTestApp) -> void - { - auto const application = rTestApp.m_application; - auto const windowApp = rTestApp.m_windowApp; - auto const magnum = rTestApp.m_magnum; - auto & rTopData = rTestApp.m_topData; - - TopTaskBuilder builder{rTestApp.m_tasks, rTestApp.m_renderer.m_edges, rTestApp.m_taskData}; - - auto & [SCENE_SESSIONS] = unpack(rTestApp.m_scene.m_sessions); - auto & [RENDERER_SESSIONS] = resize_then_unpack(rTestApp.m_renderer.m_sessions); - - sceneRenderer = setup_scene_renderer (builder, rTopData, application, windowApp, commonScene); - create_materials(rTopData, sceneRenderer, sc_materialCount); - - magnumScene = setup_magnum_scene (builder, rTopData, application, rTestApp.m_windowApp, sceneRenderer, rTestApp.m_magnum, scene, commonScene); - cameraCtrl = setup_camera_ctrl (builder, rTopData, windowApp, sceneRenderer, magnumScene); - // cameraFree = setup_camera_free (builder, rTopData, windowApp, scene, cameraCtrl); - shVisual = setup_shader_visualizer (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matVisualizer); - // shFlat = setup_shader_flat (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matFlat); - shPhong = setup_shader_phong (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matPhong); - planetDraw = setup_landerplanet_draw (builder, rTopData, windowApp, sceneRenderer, cameraCtrl, commonScene, uniCore, uniScnFrame, uniPlanet, sc_matVisualizer, sc_matFlat); - - prefabDraw = setup_prefab_draw (builder, rTopData, application, windowApp, sceneRenderer, commonScene, prefabs, sc_matPhong); - vehicleDraw = setup_vehicle_spawn_draw (builder, rTopData, sceneRenderer, vehicleSpawn); - vehicleCtrl = setup_vehicle_control (builder, rTopData, windowApp, scene, parts, signalsFloat); - cameraVehicle = setup_camera_vehicle (builder, rTopData, windowApp, scene, sceneRenderer, commonScene, physics, parts, cameraCtrl, vehicleCtrl); + using lander::setup_lander_scenario; - setup_magnum_draw(rTestApp, scene, sceneRenderer, magnumScene); - }; - return setup_renderer; - }); + add_scenario("lander", "Lander simulation game", setup_lander_scenario); return scenarioMap; } @@ -550,134 +459,6 @@ ScenarioMap_t const& scenarios() return s_scenarioMap; } - -//----------------------------------------------------------------------------- - - -struct MainLoopSignals -{ - PipelineId mainLoop; - PipelineId inputs; - PipelineId renderSync; - PipelineId renderResync; - PipelineId sceneUpdate; - PipelineId sceneRender; -}; - -/** - * @brief Runs Task/Pipeline main loop within MagnumApplication - */ -class CommonMagnumApp : public IOspApplication -{ -public: - CommonMagnumApp(TestApp &rTestApp, MainLoopControl &rMainLoopCtrl, MainLoopSignals signals) noexcept - : m_rTestApp { rTestApp } - , m_rMainLoopCtrl { rMainLoopCtrl } - , m_signals { signals } - { } - - void run(MagnumApplication& rApp) override - { - // Start the main loop - - PipelineId const mainLoop = m_rTestApp.m_application.get_pipelines().mainLoop; - m_rTestApp.m_pExecutor->run(m_rTestApp, mainLoop); - - // Resyncronize renderer - - m_rMainLoopCtrl = MainLoopControl{ - .doUpdate = false, - .doSync = true, - .doResync = true, - .doRender = false, - }; - - signal_all(); - - m_rTestApp.m_pExecutor->wait(m_rTestApp); - } - - void draw(MagnumApplication& rApp, float delta) override - { - // Magnum Application's main loop calls this - - m_rMainLoopCtrl = MainLoopControl{ - .doUpdate = true, - .doSync = true, - .doResync = false, - .doRender = true, - }; - - signal_all(); - - m_rTestApp.m_pExecutor->wait(m_rTestApp); - } - - void exit(MagnumApplication& rApp) override - { - m_rMainLoopCtrl = MainLoopControl{ - .doUpdate = false, - .doSync = false, - .doResync = false, - .doRender = false, - }; - - signal_all(); - - m_rTestApp.m_pExecutor->wait(m_rTestApp); - - if (m_rTestApp.m_pExecutor->is_running(m_rTestApp)) - { - // Main loop must have stopped, but didn't! - m_rTestApp.m_pExecutor->wait(m_rTestApp); - std::abort(); - } - } - -private: - - void signal_all() - { - m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.mainLoop); - m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.inputs); - m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.renderSync); - m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.renderResync); - m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.sceneUpdate); - m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.sceneRender); - } - - TestApp &m_rTestApp; - MainLoopControl &m_rMainLoopCtrl; - - MainLoopSignals m_signals; -}; - -void setup_magnum_draw(TestApp& rTestApp, Session const& scene, Session const& sceneRenderer, Session const& magnumScene) -{ - OSP_DECLARE_GET_DATA_IDS(rTestApp.m_application, TESTAPP_DATA_APPLICATION); - OSP_DECLARE_GET_DATA_IDS(sceneRenderer, TESTAPP_DATA_SCENE_RENDERER); - OSP_DECLARE_GET_DATA_IDS(rTestApp.m_magnum, TESTAPP_DATA_MAGNUM); - OSP_DECLARE_GET_DATA_IDS(magnumScene, TESTAPP_DATA_MAGNUM_SCENE); - - auto &rMainLoopCtrl = top_get (rTestApp.m_topData, idMainLoopCtrl); - auto &rActiveApp = top_get(rTestApp.m_topData, idActiveApp); - auto &rCamera = top_get (rTestApp.m_topData, idCamera); - - rCamera.set_aspect_ratio(Vector2{Magnum::GL::defaultFramebuffer.viewport().size()}); - - MainLoopSignals const signals - { - .mainLoop = rTestApp.m_application .get_pipelines() .mainLoop, - .inputs = rTestApp.m_windowApp .get_pipelines() .inputs, - .renderSync = rTestApp.m_windowApp .get_pipelines() .sync, - .renderResync = rTestApp.m_windowApp .get_pipelines() .resync, - .sceneUpdate = scene .get_pipelines() .update, - .sceneRender = sceneRenderer .get_pipelines() .render, - }; - - rActiveApp.set_osp_app( std::make_unique(rTestApp, rMainLoopCtrl, signals) ); -} - } // namespace testapp diff --git a/src/testapp/scenarios.h b/src/testapp/scenarios.h index 8beed14a..d35dfc3c 100644 --- a/src/testapp/scenarios.h +++ b/src/testapp/scenarios.h @@ -47,13 +47,6 @@ namespace scenes using enum EStgLink; } -struct MainLoopControl -{ - bool doUpdate; - bool doSync; - bool doResync; - bool doRender; -}; struct ScenarioOption { diff --git a/src/testapp/scenarios/lander.cpp b/src/testapp/scenarios/lander.cpp new file mode 100644 index 00000000..4177f623 --- /dev/null +++ b/src/testapp/scenarios/lander.cpp @@ -0,0 +1,129 @@ +#include "lander.h" +#include "../testapp.h" +#include "../identifiers.h" +#include "../sessions/common.h" +#include "../sessions/magnum.h" +#include "../sessions/misc.h" +#include "../sessions/newton.h" +#include "../sessions/physics.h" +#include "../sessions/shapes.h" +#include "../sessions/terrain.h" +#include "../sessions/universe.h" +#include "../sessions/vehicles.h" +#include "../sessions/vehicles_machines.h" +#include "../sessions/vehicles_prebuilt.h" +#include "../scenarios.h" + +#include + +#include + +namespace lander +{ + // MaterialIds hints which shaders should be used to draw a DrawEnt + // DrawEnts can be assigned to multiple materials + static constexpr auto sc_matVisualizer = osp::draw::MaterialId(0); + static constexpr auto sc_matFlat = osp::draw::MaterialId(1); + static constexpr auto sc_matPhong = osp::draw::MaterialId(2); + static constexpr int sc_materialCount = 4; + + RendererSetupFunc_t lander::setup_lander_scenario(TestApp &rTestApp) + { +#define SCENE_SESSIONS scene, commonScene, uniCore, uniScnFrame, uniPlanet, physics, \ + prefabs, parts, signalsFloat, vehicleSpawn, vehicleSpawnVB, vehicles, \ + newton, vehicleSpawnNwt, nwtRocketSet, rocketsNwt, \ + machRocket, machRcsDriver +#define SCENE_SESSIONS_COUNT 18 +#define RENDERER_SESSIONS sceneRenderer, magnumScene, planetDraw, \ + cameraCtrl, cameraFree, shVisual, shFlat, shPhong, \ + prefabDraw, vehicleDraw, vehicleCtrl, cameraVehicle +#define RENDERER_SESSIONS_COUNT 12 + + using namespace testapp::scenes; + using adera::ACtxVehicleSpawnVB; + using osp::top_get; + using osp::TopTaskBuilder; + using osp::active::ACtxVehicleSpawn; + using testapp::PlApplication; + // using osp::active::ad; + + 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(rTestApp.m_scene.m_sessions); + + scene = setup_scene(builder, rTopData, application); + commonScene = setup_common_scene(builder, rTopData, scene, application, defaultPkg); + + auto const tgApp = application.get_pipelines(); + uniCore = setup_uni_core(builder, rTopData, tgApp.mainLoop); + uniScnFrame = setup_uni_sceneframe(builder, rTopData, uniCore); + uniPlanet = setup_uni_landerplanet(builder, rTopData, uniCore, uniScnFrame); + + physics = setup_physics(builder, rTopData, scene, commonScene); + prefabs = setup_prefabs(builder, rTopData, application, scene, commonScene, physics); + parts = setup_parts(builder, rTopData, application, scene); + signalsFloat = setup_signals_float(builder, rTopData, scene, parts); + vehicleSpawn = setup_vehicle_spawn(builder, rTopData, scene); + vehicleSpawnVB = setup_vehicle_spawn_vb(builder, rTopData, application, scene, commonScene, prefabs, parts, vehicleSpawn, signalsFloat); + vehicles = setup_prebuilt_vehicles(builder, rTopData, application, scene); + + machRocket = setup_mach_rocket(builder, rTopData, scene, parts, signalsFloat); + machRcsDriver = setup_mach_rcsdriver(builder, rTopData, scene, parts, signalsFloat); + + newton = setup_newton(builder, rTopData, scene, commonScene, physics); + vehicleSpawnNwt = setup_vehicle_spawn_newton(builder, rTopData, application, commonScene, physics, prefabs, parts, vehicleSpawn, newton); + nwtRocketSet = setup_newton_factors(builder, rTopData); + rocketsNwt = setup_rocket_thrust_newton(builder, rTopData, scene, commonScene, physics, prefabs, parts, signalsFloat, newton, nwtRocketSet); + + OSP_DECLARE_GET_DATA_IDS(vehicleSpawn, TESTAPP_DATA_VEHICLE_SPAWN); + OSP_DECLARE_GET_DATA_IDS(vehicleSpawnVB, TESTAPP_DATA_VEHICLE_SPAWN_VB); + OSP_DECLARE_GET_DATA_IDS(vehicles, TESTAPP_DATA_TEST_VEHICLES); + + auto &rVehicleSpawn = top_get(rTopData, idVehicleSpawn); + auto &rVehicleSpawnVB = top_get(rTopData, idVehicleSpawnVB); + auto &rPrebuiltVehicles = top_get(rTopData, idPrebuiltVehicles); + + rVehicleSpawn.spawnRequest.push_back( + {.position = {30.0f, 0.0f, 0.0f}, + .velocity = {0.0f, 0.0f, 0.0f}, + .rotation = {}}); + rVehicleSpawnVB.dataVB.push_back(rPrebuiltVehicles[gc_pbvSimpleCommandServiceModule].get()); + + RendererSetupFunc_t const setup_renderer = [](TestApp &rTestApp) -> void + { + auto const application = rTestApp.m_application; + auto const windowApp = rTestApp.m_windowApp; + auto const magnum = rTestApp.m_magnum; + auto &rTopData = rTestApp.m_topData; + + TopTaskBuilder builder{rTestApp.m_tasks, rTestApp.m_renderer.m_edges, rTestApp.m_taskData}; + + auto &[SCENE_SESSIONS] = unpack(rTestApp.m_scene.m_sessions); + auto &[RENDERER_SESSIONS] = resize_then_unpack(rTestApp.m_renderer.m_sessions); + + sceneRenderer = setup_scene_renderer(builder, rTopData, application, windowApp, commonScene); + create_materials(rTopData, sceneRenderer, sc_materialCount); + + magnumScene = setup_magnum_scene(builder, rTopData, application, rTestApp.m_windowApp, sceneRenderer, rTestApp.m_magnum, scene, commonScene); + cameraCtrl = setup_camera_ctrl(builder, rTopData, windowApp, sceneRenderer, magnumScene); + // cameraFree = setup_camera_free (builder, rTopData, windowApp, scene, cameraCtrl); + shVisual = setup_shader_visualizer(builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matVisualizer); + // shFlat = setup_shader_flat (builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matFlat); + shPhong = setup_shader_phong(builder, rTopData, windowApp, sceneRenderer, magnum, magnumScene, sc_matPhong); + planetDraw = setup_landerplanet_draw(builder, rTopData, windowApp, sceneRenderer, cameraCtrl, commonScene, uniCore, uniScnFrame, uniPlanet, sc_matVisualizer, sc_matFlat); + + prefabDraw = setup_prefab_draw(builder, rTopData, application, windowApp, sceneRenderer, commonScene, prefabs, sc_matPhong); + vehicleDraw = setup_vehicle_spawn_draw(builder, rTopData, sceneRenderer, vehicleSpawn); + vehicleCtrl = setup_vehicle_control(builder, rTopData, windowApp, scene, parts, signalsFloat); + cameraVehicle = setup_camera_vehicle(builder, rTopData, windowApp, scene, sceneRenderer, commonScene, physics, parts, cameraCtrl, vehicleCtrl); + + setup_magnum_draw(rTestApp, scene, sceneRenderer, magnumScene); + }; + return setup_renderer; + } + +} // namespace lander \ No newline at end of file diff --git a/src/testapp/scenarios/lander.h b/src/testapp/scenarios/lander.h new file mode 100644 index 00000000..b585ebca --- /dev/null +++ b/src/testapp/scenarios/lander.h @@ -0,0 +1,11 @@ +#include "../testapp.h" + +namespace lander +{ + using testapp::TestApp; + + using RendererSetupFunc_t = void (*)(TestApp &); + using MagnumDrawFunc_t = void (*)(TestApp &, osp::Session const &, osp::Session const &, osp::Session const &); + + RendererSetupFunc_t setup_lander_scenario(TestApp &rTestApp); +} // namespace lander \ No newline at end of file diff --git a/src/testapp/sessions/common.cpp b/src/testapp/sessions/common.cpp index cf752c7e..d9cc8040 100644 --- a/src/testapp/sessions/common.cpp +++ b/src/testapp/sessions/common.cpp @@ -24,6 +24,7 @@ */ #include "common.h" #include "../scenarios.h" +#include "magnum.h" #include #include diff --git a/src/testapp/sessions/magnum.cpp b/src/testapp/sessions/magnum.cpp index 01d1722f..426b9782 100644 --- a/src/testapp/sessions/magnum.cpp +++ b/src/testapp/sessions/magnum.cpp @@ -546,4 +546,125 @@ Session setup_shader_phong( } // setup_shader_phong +struct MainLoopSignals +{ + PipelineId mainLoop; + PipelineId inputs; + PipelineId renderSync; + PipelineId renderResync; + PipelineId sceneUpdate; + PipelineId sceneRender; +}; + +/** + * @brief Runs Task/Pipeline main loop within MagnumApplication + */ +class CommonMagnumApp : public IOspApplication +{ +public: + CommonMagnumApp(TestApp &rTestApp, MainLoopControl &rMainLoopCtrl, MainLoopSignals signals) noexcept + : m_rTestApp{rTestApp}, m_rMainLoopCtrl{rMainLoopCtrl}, m_signals{signals} + { + } + + void run(MagnumApplication &rApp) override + { + // Start the main loop + + PipelineId const mainLoop = m_rTestApp.m_application.get_pipelines().mainLoop; + m_rTestApp.m_pExecutor->run(m_rTestApp, mainLoop); + + // Resyncronize renderer + + m_rMainLoopCtrl = MainLoopControl{ + .doUpdate = false, + .doSync = true, + .doResync = true, + .doRender = false, + }; + + signal_all(); + + m_rTestApp.m_pExecutor->wait(m_rTestApp); + } + + void draw(MagnumApplication &rApp, float delta) override + { + // Magnum Application's main loop calls this + + m_rMainLoopCtrl = MainLoopControl{ + .doUpdate = true, + .doSync = true, + .doResync = false, + .doRender = true, + }; + + signal_all(); + + m_rTestApp.m_pExecutor->wait(m_rTestApp); + } + + void exit(MagnumApplication &rApp) override + { + m_rMainLoopCtrl = MainLoopControl{ + .doUpdate = false, + .doSync = false, + .doResync = false, + .doRender = false, + }; + + signal_all(); + + m_rTestApp.m_pExecutor->wait(m_rTestApp); + + if (m_rTestApp.m_pExecutor->is_running(m_rTestApp)) + { + // Main loop must have stopped, but didn't! + m_rTestApp.m_pExecutor->wait(m_rTestApp); + std::abort(); + } + } + +private: + void signal_all() + { + m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.mainLoop); + m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.inputs); + m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.renderSync); + m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.renderResync); + m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.sceneUpdate); + m_rTestApp.m_pExecutor->signal(m_rTestApp, m_signals.sceneRender); + } + + TestApp &m_rTestApp; + MainLoopControl &m_rMainLoopCtrl; + + MainLoopSignals m_signals; +}; + +void setup_magnum_draw(TestApp &rTestApp, Session const &scene, Session const &sceneRenderer, Session const &magnumScene) +{ + OSP_DECLARE_GET_DATA_IDS(rTestApp.m_application, TESTAPP_DATA_APPLICATION); + OSP_DECLARE_GET_DATA_IDS(sceneRenderer, TESTAPP_DATA_SCENE_RENDERER); + OSP_DECLARE_GET_DATA_IDS(rTestApp.m_magnum, TESTAPP_DATA_MAGNUM); + OSP_DECLARE_GET_DATA_IDS(magnumScene, TESTAPP_DATA_MAGNUM_SCENE); + + auto &rMainLoopCtrl = top_get(rTestApp.m_topData, idMainLoopCtrl); + auto &rActiveApp = top_get(rTestApp.m_topData, idActiveApp); + auto &rCamera = top_get(rTestApp.m_topData, idCamera); + + rCamera.set_aspect_ratio(Vector2{Magnum::GL::defaultFramebuffer.viewport().size()}); + + MainLoopSignals const signals{ + .mainLoop = rTestApp.m_application.get_pipelines().mainLoop, + .inputs = rTestApp.m_windowApp.get_pipelines().inputs, + .renderSync = rTestApp.m_windowApp.get_pipelines().sync, + .renderResync = rTestApp.m_windowApp.get_pipelines().resync, + .sceneUpdate = scene.get_pipelines().update, + .sceneRender = sceneRenderer.get_pipelines().render, + }; + + rActiveApp.set_osp_app(std::make_unique(rTestApp, rMainLoopCtrl, signals)); +} // setup_magnum_draw + } // namespace testapp::scenes diff --git a/src/testapp/sessions/magnum.h b/src/testapp/sessions/magnum.h index 197cbfcd..d8e1c661 100644 --- a/src/testapp/sessions/magnum.h +++ b/src/testapp/sessions/magnum.h @@ -89,4 +89,18 @@ osp::Session setup_shader_phong( osp::Session const& magnumScene, osp::draw::MaterialId materialId = lgrn::id_null()); +void setup_magnum_draw( + TestApp& rTestApp, + osp::Session const& scene, + osp::Session const& sceneRenderer, + osp::Session const& magnumScene); + +struct MainLoopControl +{ + bool doUpdate; + bool doSync; + bool doResync; + bool doRender; +}; + } diff --git a/src/testapp/sessions/universe.cpp b/src/testapp/sessions/universe.cpp index 2734c6ab..7778f481 100644 --- a/src/testapp/sessions/universe.cpp +++ b/src/testapp/sessions/universe.cpp @@ -521,26 +521,26 @@ Session setup_landerplanet_draw( rScnRender.m_mesh[drawEnt] = rDrawing.m_meshRefCounts.ref_add(sphereMeshId); rScnRender.m_meshDirty.push_back(drawEnt); - rScnRender.m_visible.set(std::size_t(drawEnt)); - rScnRender.m_opaque.set(std::size_t(drawEnt)); - rMatPlanet.m_ents.set(std::size_t(drawEnt)); + rScnRender.m_visible.insert(drawEnt); + rScnRender.m_opaque.insert(drawEnt); + rMatPlanet.m_ents.insert(drawEnt); rMatPlanet.m_dirty.push_back(drawEnt); } rScnRender.m_mesh[rPlanetDraw.attractor] = rDrawing.m_meshRefCounts.ref_add(sphereMeshId); rScnRender.m_meshDirty.push_back(rPlanetDraw.attractor); - rScnRender.m_visible.set(std::size_t(rPlanetDraw.attractor)); - rScnRender.m_opaque.set(std::size_t(rPlanetDraw.attractor)); - rMatPlanet.m_ents.set(std::size_t(rPlanetDraw.attractor)); + rScnRender.m_visible.insert(rPlanetDraw.attractor); + rScnRender.m_opaque.insert(rPlanetDraw.attractor); + rMatPlanet.m_ents.insert(rPlanetDraw.attractor); rMatPlanet.m_dirty.push_back(rPlanetDraw.attractor); for (DrawEnt const drawEnt : rPlanetDraw.axis) { rScnRender.m_mesh[drawEnt] = rDrawing.m_meshRefCounts.ref_add(cubeMeshId); rScnRender.m_meshDirty.push_back(drawEnt); - rScnRender.m_visible.set(std::size_t(drawEnt)); - rScnRender.m_opaque.set(std::size_t(drawEnt)); - rMatAxis.m_ents.set(std::size_t(drawEnt)); + rScnRender.m_visible.insert(drawEnt); + rScnRender.m_opaque.insert(drawEnt); + rMatAxis.m_ents.insert(drawEnt); rMatAxis.m_dirty.push_back(drawEnt); }