TheOpenSpaceProgram / osp-magnum

A spaceship game
https://www.openspaceprogram.org/
MIT License
216 stars 32 forks source link

Rework Hierarchy into "Scene Graph" and Simplify Newton integration #224

Closed Capital-Asterisk closed 1 year ago

Capital-Asterisk commented 1 year ago

ok, now we got vehicles spawning again, time to make them apply thrust ...how lol?

New Scene Graph (replaces SysHierarchy)

Instead of a linked-list of entities and components, the new scene graph is just a couple of int vectors to describe entities and descendant counts.

From basic.h

struct ACtxSceneGraph
{
    // Tree structure stored using an array of descendant count in parallel with
    // identificaton (entities)
    // A(B(C(D)), E(F(G(H,I)))) -> [A,B,C,D,E,F,G,H,I] and [8,2,1,0,4,3,2,0,0]
    std::vector<ActiveEnt>  m_treeToEnt{lgrn::id_null<ActiveEnt>()};
    std::vector<uint32_t>   m_treeDescendants{std::initializer_list<uint32_t>{0}};

    std::vector<ActiveEnt>  m_entParent;
    std::vector<TreePos_t>  m_entToTreePos;

    // ...
};

Traversing a subtree is extremely fast, greatly simplifying and speeding up everything, such as calculating transforms for drawing. Other operations are far easier to do. For example, checking if an entity is a descendant of another entity is a matter of checking if its position in the vector is contained within its ancestor.

Random insertions and deletions from the tree is a bit harder, but this is never done anywhere. The architecture favors separate steps for deleting and creating new instances. All things that need to be deleted are all deleted before and all things that need to be created are created.

Entire subtrees must be inserted at once, the number of entities should be known beforehand. The SubtreeBuilder interface is added to assist with this.

Simplified Newton Dynamics integration

Previously there was some kind of 'generic physics interface' in the form of ECS-style components. ie: ACompPhysLinearVel, ACompPhysDynamic, ... in physics.h.

This is the wrong abstraction, and gets extremely complex as EVERY feature we need from the physics engine must also be implemented by generic physics.

OSP Vehicles <--code--> OSP Generic Physics <--code--> Newton Dynamics

The new architecture can cleanly handle a more direct approach.

OSP Vehicles <--code--> Newton Dynamics

Simplified snippet from scenarios.cpp. Newton-specific code is separated into their own tasks and data:

parts               = setup_parts(...)
vehicleSpawn        = setup_vehicle_spawn(... parts)
newton              = setup_newton(...)
vehicleSpawnNwt     = setup_vehicle_spawn_newton(... parts, vehicleSpawn, newton)

// just write a setup_physx and setup_vehicle_spawn_physx if we were to add PhysX support

How to Rocket thrust? Use ForceFactors!

Previously, lots of separate systems would write forces into rigid bodies. Rocket thrust, gravity, and potentially aerodynamic forces are separate calls that roughly write to a single net force value for each rigid body.

This multiple-writers scheme is simply difficult to multi-thread. Atomics would help, but the problem is best avoided entirely.

Solution: Make the physics engine read from multiple sources to calculate all factors that contribute to force for each rigid body.

Each rigid body is assigned a bitset, which describe which functions are called in order to calculate its net force (and torque too). These functions are referred to as "ForceFactors." See setup_newton_force_accel(...) in scene_newton.cpp for a constant-acceleration ForceFactor used for gravity.

Other changes

jonesmz commented 1 year ago

Something's not working right with the continuous integration

In file included from /home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.cpp:25:
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.h: At global scope:
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.h:109:18: error: declaration of ‘operator<=’ as non-function
  109 |     auto operator<=>(ChildIterator const&) const = default;
      |                  ^~
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.h:109:18: error: expected ‘;’ at end of member declaration
  109 |     auto operator<=>(ChildIterator const&) const = default;
      |                  ^~
      |                    ;
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.h:109:20: error: expected unqualified-id before ‘>’ token
  109 |     auto operator<=>(ChildIterator const&) const = default;
      |                    ^
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.cpp: In static member function ‘static osp::active::SubtreeBuilder osp::active::SysSceneGraph::add_descendants(osp::active::ACtxSceneGraph&, uint32_t, osp::active::ActiveEnt)’:
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.cpp:79:14: error: ‘shift_right’ is not a member of ‘std’
   79 |         std::shift_right(rScnGraph.m_treeToEnt.begin() + subFirst,
      |              ^~~~~~~~~~~
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.cpp:82:14: error: ‘shift_right’ is not a member of ‘std’
   82 |         std::shift_right(rScnGraph.m_treeDescendants.begin() + subFirst,
      |              ^~~~~~~~~~~
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.cpp: In static member function ‘static void osp::active::SysSceneGraph::do_delete(osp::active::ACtxSceneGraph&)’:
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.cpp:200:14: error: ‘shift_left’ is not a member of ‘std’
  200 |         std::shift_left(itTreeDescFirst + done, itTreeDescFirst + keepLast, shift);
      |              ^~~~~~~~~~
/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.cpp:201:14: error: ‘shift_left’ is not a member of ‘std’
  201 |         std::shift_left(itTreeEntsFirst + done, itTreeEntsFirst + keepLast, shift);
      |              ^~~~~~~~~~
make[3]: *** [src/CMakeFiles/osp-magnum.dir/build.make:174: src/CMakeFiles/osp-magnum.dir/osp/Active/SysSceneGraph.cpp.o] Error 1
make[3]: *** Waiting for unfinished jobs....

Looks like ubuntu 18.04, and 22.04 both work, but not ubuntu 20.04.

Similarly, Mac is broken.

Can you see if you can get at least all the linux targets to work?

If you want to drop support for an older OS that's fine with me, I really don't care about anything older than $CurrentMajorRelease beyond the extra compatibility checking that we have to do to even pretend supporting older stuff.

Capital-Asterisk commented 1 year ago

Something's not working right with the continuous integration ....

Various C++20 features, the spaceship operator specifically, just isn't supported on some of the compilers unfortunately. I recall one of them is using gcc 9.4.

jonesmz commented 1 year ago

/home/runner/work/osp-magnum/osp-magnum/3rdparty/longeronpp/src/longeron/id_management/registry_stl.hpp:101:18: warning: attributes at the beginning of statement are ignored [-Wattributes] 101 | else [[likely]] | ^~~~~~

jonesmz commented 1 year ago

/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.h:31:10: fatal error: compare: No such file or directory 31 | #include | ^~~~~

Capital-Asterisk commented 1 year ago

/home/runner/work/osp-magnum/osp-magnum/3rdparty/longeronpp/src/longeron/id_management/registry_stl.hpp:101:18: warning: attributes at the beginning of statement are ignored [-Wattributes]

Longeron++ issue, thinking of removing this eventually.

/home/runner/work/osp-magnum/osp-magnum/src/osp/Active/SysSceneGraph.h:31:10: fatal error: compare: No such file or directory

C++20 not fully supported