#pragma once #include "entities/game_object.hpp" #include "entities/player.hpp" #include "systems/carry_system.hpp" #include "systems/collision.hpp" #include "text/handler.hpp" #include "utils/globals.hpp" namespace Nimbin { struct Projectile; struct ProjectileContactEvent { Vec3 point{}; Vec3 normal{}; GameObject* other = nullptr; Projectile* projectile = nullptr; }; class PhysicsSystem { struct SpatialGrid { DynArray> cells; double cell = 2.0; double inv = 0.5; double min_x = 0, min_z = 0; int nx = 0, nz = 0; void build(const DynArray& objs); int index(int cx, int cz) const { return cz * nx + cx; } }; SpatialGrid _grid; static void resolve_WorldBounds(GameObject& obj); bool resolve_SingleBoxCollision(Projectile& proj, const Vec3& box_min, const Vec3& box_max, const Vec3& word_he, double restitution, Vec3& cur, Vec3& prev, Vec3& dir, Collision::SweptResult& out_sw); void resolve_ProjectileStatics (Projectile& proj, const DynArray& statics, Vec3& cur, Vec3& prev, Vec3& dir, const Vec3& word_he, DynArray* contacts); void resolve_ProjectileLabels (Projectile& proj, const DynArray& labels, Vec3& cur, Vec3& prev, Vec3& dir, const Vec3& word_he); void try_Pair(GameObject* a, GameObject* b); void collide_Grid(const DynArray& active); public: void update_Player (Player& player, double acc_x, double acc_z, double dt); void update_Objects(const DynArray& objects, double dt, double gravity); void update_Projectiles (DynArray& projectiles, double dt, const DynArray& words); void resolve_Projectiles(DynArray& projectiles, const DynArray* statics, const DynArray* labels, DynArray* contacts); void resolve_PlayerVsObjects(Player& player, CarriedLine& carried, const DynArray& colliders); }; } // namespace Nimbin