Skip to content

Commit

Permalink
Add nbody gravity newton force factor
Browse files Browse the repository at this point in the history
  • Loading branch information
dylan-mcleod committed May 3, 2024
1 parent 0779681 commit 2db2f3b
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 60 deletions.
2 changes: 1 addition & 1 deletion src/testapp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int main(int argc, char** argv)
{
Corrade::Utility::Arguments args;
args.addSkippedPrefix("magnum", "Magnum options")
.addOption("scene", "lander") .setHelp("scene", "Set the scene to launch")
.addOption("scene", "none") .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!)")
Expand Down
12 changes: 7 additions & 5 deletions src/testapp/scenarios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,9 @@ static ScenarioMap_t make_scenarios()
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, \
newton, nwtGravSet, nwtGrav, vehicleSpawnNwt, nwtRocketSet, rocketsNwt, \
machRocket, machRcsDriver
#define SCENE_SESSIONS_COUNT 18
#define SCENE_SESSIONS_COUNT 20
#define RENDERER_SESSIONS sceneRenderer, magnumScene, planetDraw, \
cameraCtrl, cameraFree, shVisual, shFlat, shPhong, \
prefabDraw, vehicleDraw, vehicleCtrl, cameraVehicle
Expand Down Expand Up @@ -411,6 +411,8 @@ static ScenarioMap_t make_scenarios()
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);
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);
Expand All @@ -426,8 +428,8 @@ static ScenarioMap_t make_scenarios()

rVehicleSpawn.spawnRequest.push_back(
{
.position = {30.0f, 0.0f, 0.0f},
.velocity = {0.0f, 0.0f, 0.0f},
.position = {400.0f, 400.0f, 10.0f},
.velocity = {-5.0f, -5.0f, 0.0f},
.rotation = {}
});
rVehicleSpawnVB.dataVB.push_back(rPrebuiltVehicles[gc_pbvSimpleCommandServiceModule].get());
Expand All @@ -453,7 +455,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);
Expand Down
92 changes: 92 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,95 @@ 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

} // namespace testapp::scenes


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

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 Support for Shape Spawner physics using Newton Dynamics
*/
Expand Down
57 changes: 12 additions & 45 deletions src/testapp/sessions/universe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ Session setup_uni_sceneframe(
} // setup_uni_sceneframe






Session setup_uni_landerplanet(
TopTaskBuilder& rBuilder,
ArrayView<entt::any> topData,
Expand All @@ -104,7 +108,7 @@ Session setup_uni_landerplanet(
auto &rUniverse = top_get< Universe >(topData, idUniverse);

constexpr int precision = 10;
constexpr int planetCount = 1;
constexpr int planetCount = 2;

// Create coordinate spaces
CoSpaceId const mainSpace = rUniverse.m_coordIds.create();
Expand Down Expand Up @@ -155,7 +159,7 @@ Session setup_uni_landerplanet(

for (std::size_t i = 0; i < planetCount; ++i)
{
// Assign each planet random positions and velocities
// Place the planet at the origin
x[i] = 0;
y[i] = 0;
z[i] = 0;
Expand All @@ -170,6 +174,10 @@ Session setup_uni_landerplanet(
qw[i] = 1.0;
}

x[1] = 1000000;
y[1] = 1000000;
z[1] = 0;

auto &rScnFrame = top_get<SceneFrame>(topData, idScnFrame);
rScnFrame.m_parent = mainSpace;
rScnFrame.m_position = math::mul_2pow<Vector3g, int>({400, 400, 400}, precision);
Expand All @@ -182,7 +190,7 @@ Session setup_uni_landerplanet(
top_emplace< CoSpaceIdVec_t > (topData, idSatSurfaceSpaces, std::move(satSurfaceSpaces));

return out;
}
} // setup_uni_landerplanet

Session setup_uni_testplanets(
TopTaskBuilder& rBuilder,
Expand Down Expand Up @@ -403,8 +411,6 @@ Session setup_uni_testplanets(
} // setup_uni_testplanets




struct PlanetDraw
{
DrawEntVec_t drawEnts;
Expand Down Expand Up @@ -446,38 +452,6 @@ Session setup_landerplanet_draw(
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<Vector3, int>(rotated, rScnFrame.m_precision));
}

rScnFrame.m_scenePosition = Vector3g(math::mul_2pow<Vector3, int>(rCamCtrl.m_target.value(), rScnFrame.m_precision));
});

rBuilder.task()
.name ("Resync test planets, create DrawEnts")
.run_on ({tgWin.resync(Run)})
Expand Down Expand Up @@ -523,13 +497,6 @@ Session setup_landerplanet_draw(
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);
Expand Down Expand Up @@ -836,4 +803,4 @@ Session setup_testplanets_draw(
} // setup_testplanets_draw


} // namespace testapp::scenes
} // namespace testapp::scenes
34 changes: 25 additions & 9 deletions src/testapp/sessions/universe.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,30 +46,46 @@ osp::Session setup_uni_sceneframe(
osp::TopTaskBuilder& rBuilder,
osp::ArrayView<entt::any> topData,
osp::Session const& uniCore);

/**
* @brief A single planet setup for landing on
* @brief Unrealistic planets test, allows SceneFrame to move around and get captured into planets
*/
osp::Session setup_uni_landerplanet(
osp::Session setup_uni_testplanets(
osp::TopTaskBuilder& rBuilder,
osp::ArrayView<entt::any> topData,
osp::Session const& uniCore,
osp::Session const& uniScnFrame);


/**
* @brief Unrealistic planets test, allows SceneFrame to move around and get captured into planets
* @brief Draw universe, specifically designed for setup_uni_test_planets
*/
osp::Session setup_uni_testplanets(
osp::Session setup_testplanets_draw(
osp::TopTaskBuilder& rBuilder,
osp::ArrayView<entt::any> 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& 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
* @brief A single planet setup for landing on
*/
osp::Session setup_testplanets_draw(
osp::Session setup_uni_landerplanet(
osp::TopTaskBuilder& rBuilder,
osp::ArrayView<entt::any> topData,
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<entt::any> topData,
osp::Session const& windowApp,
Expand All @@ -81,4 +97,4 @@ osp::Session setup_testplanets_draw(
osp::Session const& uniTestPlanets,
osp::draw::MaterialId const matPlanets,
osp::draw::MaterialId const matAxis);
}
}

0 comments on commit 2db2f3b

Please sign in to comment.