Skip to content
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

Another lander game #270

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ OSP-MAGNUM.cbp
CMakeSettings.json
out/
.vs/
.vscode/
build/
2 changes: 1 addition & 1 deletion src/osp/util/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*/
#pragma once

#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
#include <spdlog/spdlog.h>

namespace osp
Expand Down
3 changes: 2 additions & 1 deletion src/testapp/identifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ struct PlNewton
#define TESTAPP_DATA_NEWTON_ACCEL 1, \
idAcceleration


#define TESTAPP_DATA_NEWTON_ORIGIN_TRANSLATE 1, \
idNwtSync

#define TESTAPP_DATA_ROCKETS_NWT 1, \
idRocketsNwt
Expand Down
1 change: 1 addition & 0 deletions src/testapp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ void start_magnum_async()
g_testApp.close_session(g_testApp.m_windowApp);

OSP_LOG_INFO("Closed Magnum Application");
std::exit(0);
});
g_magnumThread.swap(t);
}
Expand Down
98 changes: 98 additions & 0 deletions src/testapp/scenarios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,104 @@ 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, nwtGravSet, nwtGrav, vehicleSpawnNwt, nwtRocketSet, rocketsNwt, \
machRocket, machRcsDriver, nwtFollow
#define SCENE_SESSIONS_COUNT 21
#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<SCENE_SESSIONS_COUNT>(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);
nwtGravSet = setup_newton_factors (builder, rTopData);
nwtGrav = setup_newton_force_grav_nbody(builder, rTopData, newton, nwtGravSet, uniCore, uniPlanet, uniScnFrame);
nwtFollow = setup_newton_origin_translate(builder, rTopData, scene, uniScnFrame, newton, 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<ACtxVehicleSpawn> (rTopData, idVehicleSpawn);
auto &rVehicleSpawnVB = top_get<ACtxVehicleSpawnVB> (rTopData, idVehicleSpawnVB);
auto &rPrebuiltVehicles = top_get<PrebuiltVehicles> (rTopData, idPrebuiltVehicles);

rVehicleSpawn.spawnRequest.push_back(
{
.position = {400.0f, 400.0f, 10.0f},
.velocity = {-5.0f, -5.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<SCENE_SESSIONS_COUNT>(rTestApp.m_scene.m_sessions);
auto & [RENDERER_SESSIONS] = resize_then_unpack<RENDERER_SESSIONS_COUNT>(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;
});

return scenarioMap;
}

Expand Down
153 changes: 153 additions & 0 deletions src/testapp/sessions/newton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#include <osp/core/Resources.h>
#include <osp/drawing/drawing.h>
#include <osp/vehicles/ImporterData.h>
#include <osp/universe/coordinates.h>
#include <osp/universe/universetypes.h>
#include <osp/universe/universe.h>

#include <adera/machines/links.h>

Expand Down Expand Up @@ -710,6 +713,156 @@ Session setup_rocket_thrust_newton(
} // setup_rocket_thrust_newton


static void nbody_grav_force(NewtonBody const* pBody, BodyId const body, ACtxNwtWorld const& rNwt, ACtxNwtWorld::ForceFactorFunc::UserData_t data, Vector3& rForce, Vector3& rTorque) noexcept
{
using namespace osp::universe;

auto &rUniverse = *reinterpret_cast<Universe*>(data[0]);
auto &rMainSpace = *reinterpret_cast<CoSpaceId*>(data[1]);
auto &rScnFrame = *reinterpret_cast<SceneFrame*>(data[2]);

CoSpaceCommon &rMainSpaceCommon = rUniverse.m_coordCommon[rMainSpace];

float const invCommonScale = osp::math::mul_2pow<float, int>(1.0f, -rMainSpaceCommon.m_precision);
float const sceneScale = osp::math::mul_2pow<float, int>(1.0f, rScnFrame.m_precision);

// get the positions of all the planets
auto const [x, y, z] = sat_views(rMainSpaceCommon.m_satPositions, rMainSpaceCommon.m_data, rMainSpaceCommon.m_satCount);

// get the position/mass of this physics body
Vector3 pos = Vector3(0.0f);
float mass = 0.0f;
float dummy = 0.0f;
NewtonBodyGetPosition(pBody, pos.data());
NewtonBodyGetMass(pBody, &mass, &dummy, &dummy, &dummy);

// transform our local scene position to the universe space
Vector3g const bodyPos{rScnFrame.m_rotation.transformVector(Vector3d(rScnFrame.m_scenePosition) + Vector3d(pos))};
Vector3g const areaPos{rScnFrame.m_position + bodyPos * sceneScale};

uint32_t const planetCount = rMainSpaceCommon.m_satCount;

// sum up the forces
for (uint32_t i = 0; i < planetCount; ++i)
{
Vector3 const diff = (Vector3( x[i], y[i], z[i]) - Vector3(areaPos)) * invCommonScale;
float const r = diff.length();
float const factor = 1000000.f;
Vector3 const accel = diff * factor / (r * r * r);

rForce += accel * mass;
}
}

osp::Session setup_newton_force_grav_nbody(
TopTaskBuilder& rBuilder,
ArrayView<entt::any> topData,
Session const& newton,
Session const& nwtFactors,
Session const& uniCore,
Session const& uniPlanets,
Session const& uniScnFrame)
{
using namespace osp::universe;
using UserData_t = ACtxNwtWorld::ForceFactorFunc::UserData_t;
using CoSpaceIdVec_t = std::vector<CoSpaceId>;
using Corrade::Containers::Array;

OSP_DECLARE_GET_DATA_IDS(newton, TESTAPP_DATA_NEWTON);
OSP_DECLARE_GET_DATA_IDS(nwtFactors, TESTAPP_DATA_NEWTON_FORCES);

auto &rNwt = top_get<ACtxNwtWorld>(topData, idNwt);

OSP_DECLARE_GET_DATA_IDS(uniCore, TESTAPP_DATA_UNI_CORE);
auto &rUniverse = top_get< Universe >(topData, idUniverse);

OSP_DECLARE_GET_DATA_IDS(uniPlanets, TESTAPP_DATA_UNI_PLANETS);
auto& rPlanetMainSpace = top_get<CoSpaceId>(topData, idPlanetMainSpace);

OSP_DECLARE_GET_DATA_IDS(uniScnFrame, TESTAPP_DATA_UNI_SCENEFRAME);
auto& rScnFrame = top_get<SceneFrame>(topData, idScnFrame);

Session out;
OSP_DECLARE_CREATE_DATA_IDS(out, topData, TESTAPP_DATA_NEWTON_ACCEL);

ACtxNwtWorld::ForceFactorFunc const factor
{
.m_func = nbody_grav_force,
.m_userData = {&rUniverse, &rPlanetMainSpace, &rScnFrame}
};

// Register force

std::size_t const index = rNwt.m_factors.size();
rNwt.m_factors.emplace_back(factor);

auto factorBits = lgrn::bit_view(top_get<ForceFactors_t>(topData, idNwtFactors));
factorBits.set(index);

return out;
} // setup_newton_force_accel

Session setup_newton_origin_translate(
TopTaskBuilder& rBuilder,
ArrayView<entt::any> topData,
Session const& scene,
Session const& sceneFrame,
Session const& newton,
Session const& physics)
{
using namespace osp::universe;

OSP_DECLARE_GET_DATA_IDS(scene, TESTAPP_DATA_SCENE);
auto const tgScn = scene.get_pipelines<PlScene>();

OSP_DECLARE_GET_DATA_IDS(newton, TESTAPP_DATA_NEWTON);
auto const tgNwt = newton.get_pipelines<PlNewton>();

OSP_DECLARE_GET_DATA_IDS(sceneFrame, TESTAPP_DATA_UNI_SCENEFRAME);
auto const tgScnFrame = sceneFrame.get_pipelines<PlUniSceneFrame>();

OSP_DECLARE_GET_DATA_IDS(physics, TESTAPP_DATA_PHYSICS);
auto const tgPhys = physics.get_pipelines<PlPhysics>();

Session out;
OSP_DECLARE_CREATE_DATA_IDS(out, topData, TESTAPP_DATA_NEWTON_ORIGIN_TRANSLATE);

rBuilder.task()
.name ("Update scene origin if body strays too far")
.run_on ({tgScn.update(Run)})
.sync_with ({tgNwt.nwtBody(Prev), tgScnFrame.sceneFrame(Modify)})
.push_to (out.m_tasks)
.args ({idNwt, idScnFrame, idPhys})
.func([] (ACtxNwtWorld& rNwt, SceneFrame& rScnFrame, ACtxPhysics& rPhysics) noexcept
{
for (auto& pBody : rNwt.m_bodyPtrs)
{
Vector3 pos = Vector3(0.0f);
NewtonBodyGetPosition(pBody.get(), pos.data());

float const maxDist = 512.0f;
Vector3 const translate = sign(pos) * floor(abs(pos) / maxDist) * maxDist;

if ( ! translate.isZero())
{
Vector3 const rotated = Quaternion(rScnFrame.m_rotation).transformVector(translate);
rScnFrame.m_position += Vector3g(math::mul_2pow<Vector3, int>(rotated, rScnFrame.m_precision));

rPhysics.m_originTranslate -= translate;
// printf("Recentering local scene\n, new origin: %ld, %ld, %ld\n", rScnFrame.m_position.x(), rScnFrame.m_position.y(), rScnFrame.m_position.z());

SysNewton::update_translate(rPhysics, rNwt);
}

// TODO: do the same but for velocity

break; // We're just taking the first newton body because i am very lazy
}
});

return out;
} // setup_newton_scene_follow

} // namespace testapp::scenes


23 changes: 23 additions & 0 deletions src/testapp/sessions/newton.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,29 @@ osp::Session setup_newton_force_accel(
osp::Session const& nwtFactors,
osp::Vector3 accel);

/**
* @brief Setup a gravity force for every satellite in the universe which acts on the newton scene
*/
osp::Session setup_newton_force_grav_nbody(
osp::TopTaskBuilder& rBuilder,
osp::ArrayView<entt::any> topData,
osp::Session const& newton,
osp::Session const& nwtFactors,
osp::Session const& uniCore,
osp::Session const& uniPlanets,
osp::Session const& uniScnFrame);

/**
* @brief Set the scene origin to follow a Newton Dynamics object
*/
osp::Session setup_newton_origin_translate(
osp::TopTaskBuilder& rBuilder,
osp::ArrayView<entt::any> topData,
osp::Session const& scene,
osp::Session const& sceneFrame,
osp::Session const& newton,
osp::Session const& physics);

/**
* @brief Support for Shape Spawner physics using Newton Dynamics
*/
Expand Down
Loading
Loading