10#include <unordered_map>
11#include <unordered_set>
28 int32_t m_collision_group = 0;
29 std::vector<std::shared_ptr<FxEntity>> m_members;
33 const std::string&
get_name()
const {
return m_name; }
34 const std::vector<std::shared_ptr<FxEntity>>&
members()
const {
return m_members; }
35 size_t size()
const {
return m_members.size(); }
37 for (
auto& e : m_members) {
40 if (enabled) e->wake();
61 struct FxContactPairSlot {
63 float jn[2] = {0.0f, 0.0f};
64 float jt[2] = {0.0f, 0.0f};
70 uint64_t step_stamp = 0;
71 size_t step_slot = kNoStepSlot;
73 static constexpr size_t kNoStepSlot =
static_cast<size_t>(-1);
76 static constexpr size_t m_enitities_limit = 4096;
78 static constexpr double m_max_time_step = 0.06;
79 static constexpr double m_min_time_step = 1e-3;
82 size_t m_substeps = 14;
83 size_t m_velocity_passes = 4;
85 bool m_entities_dirty =
false;
87 double m_time_elapsed = 0.0;
91 std::vector<FxContactPairSlot> m_contact_slots;
92 std::unordered_map<uint64_t, uint32_t> m_contact_slot_index;
93 std::vector<uint32_t> m_free_contact_slots;
97 std::vector<uint32_t> m_pair_slot;
100 uint64_t m_step_counter = 0;
104 std::vector<FxContact> m_step_contacts;
105 std::unordered_map<uint64_t, size_t> m_step_contact_index;
106 std::vector<FxContact> m_prev_contacts;
107 std::unordered_map<uint64_t, size_t> m_prev_contact_index;
108 std::vector<FxContactEvent> m_begin_contacts;
109 std::vector<FxContactEvent> m_end_contacts;
114 std::vector<std::shared_ptr<FxEntity>> m_step_pins;
115 std::vector<std::shared_ptr<FxEntity>> m_prev_pins;
121 std::vector<FxContactSolverData> m_contact_solver_data;
127 std::vector<uint32_t> m_contact_colors;
128 std::vector<uint32_t> m_colored_contacts;
137 std::vector<FxBatchRun> m_batch_runs;
140 void record_contact(
const FxContact& contact);
143 void pin_contact_entities();
145 void solve_contact_velocities(std::vector<FxContact>&
contacts,
146 const std::vector<std::shared_ptr<FxEntity>>& entities_vec,
151 void bind_contact_slot(
FxContact& contact,
size_t pair_index);
153 void evict_stale_contact_slots();
155 void build_contact_events();
196 m_func_step_callback = callback;
201 m_func_reset_callback = callback;
214 std::shared_ptr<FxEntity>
get_entity(
const std::string& name)
const;
229 std::shared_ptr<FxJoint>
get_joint(
const std::string& name)
const;
247 const std::vector<FxContact>&
contacts()
const {
return m_step_contacts; }
263 std::vector<FxRayHit>& out_hits)
const;
267 std::vector<std::shared_ptr<FxEntity>>& out)
const;
270 std::vector<std::shared_ptr<FxEntity>>& out)
const;
272 std::vector<std::shared_ptr<FxEntity>>& out)
const;
294 std::shared_ptr<FxEntityGroup>
create_group(
const std::string& name,
bool self_collide =
false);
297 const std::shared_ptr<FxEntity>& entity);
298 std::shared_ptr<FxEntityGroup>
get_group(
const std::string& name)
const {
318 template<
typename ExecPolicy,
typename Func>
324 template<
typename ExecPolicy,
typename Func>
326 ExecPolicy&& policy, Func&& func,
327 std::vector<std::invoke_result_t<Func, std::shared_ptr<FxEntity>>>& results) {
333 void sweep_dead_constraints();
335 void sweep_dead_joints();
338 std::function<void(
FxScene&,
double dt)> m_func_step_callback;
339 std::function<void(
FxScene&)> m_func_reset_callback;
342 std::vector<std::shared_ptr<FxEntity>> m_initial_entities;
343 std::vector<std::shared_ptr<FxConstraint>> m_initial_constraints;
344 std::vector<std::shared_ptr<FxJoint>> m_initial_joints;
346 std::vector<std::pair<std::shared_ptr<FxEntityGroup>, std::vector<std::shared_ptr<FxEntity>>>>
348 int32_t m_next_collision_group = -1;
349 bool m_has_initial_snapshot =
false;
A named collection of entities managed as one unit.
void set_enabled(bool enabled)
const std::string & get_name() const
const std::vector< std::shared_ptr< FxEntity > > & members() const
FxEntityGroup(const std::string &name)
void enable_collision(const std::string &entity1_name, const std::string &entity2_name)
void disable_collision(const std::string &entity1_name, const std::string &entity2_name)
A named rigid body with state, material properties, geometry, and forces.
std::string make_unique_name(const std::string &base) const
size_t size() const noexcept
std::shared_ptr< T > get(const std::string &name) const
T * get_rawptr(const std::string &name) const noexcept
void for_each(ExecPolicy &&policy, Func &&func)
void transform(ExecPolicy &&policy, Func &&func, std::vector< std::invoke_result_t< Func, std::shared_ptr< T > > > &results)
Owns a simulated world and advances it with step().
void set_gravity(const FxVec2f &o_gravity)
FxNamedRegistry< FxConstraint > m_constraints
size_t entity_count() const
void transform_entities(ExecPolicy &&policy, Func &&func, std::vector< std::invoke_result_t< Func, std::shared_ptr< FxEntity > > > &results)
const std::vector< FxContactEvent > & begin_contact_events() const
std::shared_ptr< FxEntity > entity_at_point(const FxVec2f &point) const
bool add_joint(const std::shared_ptr< FxJoint > &joint)
bool delete_joint(const std::string &name)
FxMouseJoint m_mouse_joint
void enable_mouse_drag(bool enable)
FxScene(FxVec2ui SceneSize)
void capture_initial_state()
void step(double step_dt)
void overlap_shape(const FxShape &shape, const FxVec3f &pose, std::vector< std::shared_ptr< FxEntity > > &out) const
void for_each_entity(ExecPolicy &&policy, Func &&func)
void overlap_point(const FxVec2f &point, std::vector< std::shared_ptr< FxEntity > > &out) const
void raycast_all(const FxVec2f &origin, const FxVec2f &direction, float max_distance, std::vector< FxRayHit > &out_hits) const
void set_reset_callback(const std::function< void(FxScene &)> &callback)
void overlap_circle(const FxVec2f ¢re, float radius, std::vector< std::shared_ptr< FxEntity > > &out) const
double time_elapsed() const
void overlap_box(const FxVec2f ¢re, const FxVec2f &extents, std::vector< std::shared_ptr< FxEntity > > &out) const
void enable_collision(const std::string &entity1_name, const std::string &entity2_name)
size_t group_count() const
bool constraint_exists(const std::string &name) const
bool mouse_drag_enabled() const
void set_fillTexture(const std::string &filePath)
const FxMouseJoint & mouse_joint() const
std::shared_ptr< FxEntityGroup > create_group(const std::string &name, bool self_collide=false)
const std::vector< FxContactEvent > & end_contact_events() const
std::shared_ptr< FxConstraint > get_constraint(const std::string &name) const
std::shared_ptr< FxJoint > get_joint(const std::string &name) const
size_t constraint_count() const
bool delete_constraint(const std::string &name)
bool joint_exists(const std::string &name) const
size_t joint_count() const
const FxInput & input() const
FxMouseJoint & mouse_joint()
void set_substeps(const size_t &substeps)
std::shared_ptr< FxEntity > get_entity(const std::string &name) const
std::string unique_entity_name(const std::string &base) const
void set_step_callback(const std::function< void(FxScene &, double dt)> &callback)
const std::vector< FxContact > & contacts() const
void set_velocity_passes(size_t passes)
bool entity_exists(const std::string &name) const
void set_fillColor(const FxVec4ui8 &color)
std::shared_ptr< FxEntityGroup > get_group(const std::string &name) const
FxEntityRegistry m_entities
bool delete_entity(const std::string &name)
bool add_entity(const std::shared_ptr< FxEntity > &entity)
bool add_constraint(const std::shared_ptr< FxConstraint > &constraint)
std::string fillTexturePath
void disable_collision(const std::string &entity1_name, const std::string &entity2_name)
FxNamedRegistry< FxEntityGroup > m_groups
bool delete_group(const std::string &name)
bool add_to_group(const std::shared_ptr< FxEntityGroup > &group, const std::shared_ptr< FxEntity > &entity)
FxNamedRegistry< FxJoint > m_joints
bool raycast(const FxVec2f &origin, const FxVec2f &direction, float max_distance, FxRayHit &out_hit) const
Single-precision 2D vector.
Single-precision three-component vector, including poses.
Result from a ray cast against the scene.
Unified circle, capsule, polygon, edge, and chain representation.