ShitEngine 1.4.2
基于 C++20 与 SDL3 的轻量级 2D 游戏引擎
载入中...
搜索中...
未找到
PhysicsSystem2D.h
浏览该文件的文档.
1#pragma once
2#include "../Core/Core.h"
3#include "../Math.h"
4#include "../System/System.h"
5#include <cstdint>
6#include <unordered_set>
7#include <vector>
8
9namespace Shit {
10 class RigidBody2D;
11 class Joint2D;
12 class GameObject;
13
30class SHIT_API SHIT_REFLECT(BlackList) PhysicsSystem2D final : public System {
32 public:
33 explicit PhysicsSystem2D(int priority = 50);
34 ~PhysicsSystem2D() override;
35
36 void init() override;
37 void update() override;
39 void fixedUpdate(float fixedDt) override;
40 void destroy() override;
41
42 // 反射字段被检查器直写后回调(把重力等变更实时同步到 Box2D 世界)
43 void onFieldChanged(const std::string& fieldName) override;
44
45 // 组件认领:RigidBody2D(创建/销毁物理体)
46 bool onComponentAttached(Component* component) override;
47 void onComponentDetached(Component* component) override;
48
49 // --- 配置(必须在 init() 之前调用) ---
50 void setGravity(const Vector2& gravity);
51 const Vector2& getGravity() const { return m_gravity; }
52
54 void setPixelsPerMeter(float ppm);
56 float getPixelsPerMeter() const { return m_pixelsPerMeter; }
57
58 // --- 供 RigidBody2D 内部调用 ---
65
66 // --- 供 Joint2D 内部调用 ---
68 void registerJoint(Joint2D* joint);
72 void createJoint(Joint2D* joint);
74 void destroyJoint(Joint2D* joint);
76 void rebuildJoint(Joint2D* joint);
77
78private:
79 friend class RigidBody2D;
80
82 struct ContactPair {
83 const RigidBody2D* a = nullptr;
84 const RigidBody2D* b = nullptr;
85 bool operator==(const ContactPair& o) const { return a == o.a && b == o.b; }
86 };
87 struct ContactPairHash {
88 size_t operator()(const ContactPair& p) const {
89 std::hash<const void*> h;
90 return h(p.a) ^ (h(p.b) << 1);
91 }
92 };
93
95 enum class CollisionPhase { Enter, Stay, Exit };
96
98 static ContactPair makeContactPair(const RigidBody2D* a, const RigidBody2D* b);
99
101 RigidBody2D* findRigidBody(int32_t bodyIndex, uint16_t world0, uint16_t generation) const;
102
104 void cleanupContactPairs(const RigidBody2D* body);
105
108 void collectContactEvents(std::vector<ContactPair>& entered, std::vector<ContactPair>& exited);
109
111 void ensureSimulationState();
113 void syncTransformsFromBodies();
115 void processContactEventsForStep();
116
118 void dispatchContact(const ContactPair& pair, CollisionPhase phase);
119
121 void invokeCollisionCallbacks(GameObject* self, GameObject* other, CollisionPhase phase);
122
123 SHIT_META(({.displayName = "Gravity", .tooltip = "重力(像素/秒²)"}))
124 Vector2 m_gravity{ 0.0f, 320.0f };
125
126 SHIT_META(Disable)
127 std::vector<RigidBody2D*> m_bodies;
128 SHIT_META(Disable)
129 std::vector<Joint2D*> m_joints;
130 // 当前接触中的刚体对集合(进入/持续/结束 基于它判定;元素仅作键,不触碰指针所指对象)
131 SHIT_META(Disable)
132 std::unordered_set<ContactPair, ContactPairHash> m_activeContacts;
133 // b2WorldId = {uint16_t index1; uint16_t generation;}
134 SHIT_META(Disable)
135 uint16_t m_worldIndex = 0;
136 SHIT_META(Disable)
137 uint16_t m_worldGeneration = 0;
138 SHIT_META(Disable)
139 bool m_initialized = false;
140
141 // 像素↔米比例(实例字段;init() 时应用 b2SetLengthUnitsPerMeter——
142 // 该 API 是 Box2D 进程级全局,多实例不同比例时后者生效,属 Box2D 限制)
143 SHIT_META(({.displayName = "Pixels Per Meter", .tooltip = "每米对应的像素数(默认 32,下次 init 生效)", .range = {1, 1024}, .step = 1}))
144 float m_pixelsPerMeter = 32.0f;
145 };
146}
#define SHIT_API
定义 Core.h:14
#define SHIT_REFLECT_BODY(Type)
定义 Macros.h:89
#define SHIT_REFLECT(Mode)
定义 Macros.h:86
#define SHIT_META(...)
定义 Macros.h:95
组件基类
定义 Component.h:25
游戏物体类
定义 GameObject.h:23
2D 物理关节组件
定义 Joint2D.h:36
void registerRigidBody(RigidBody2D *body)
void setGravity(const Vector2 &gravity)
重力(像素/秒²),默认 {0, 320}
~PhysicsSystem2D() override
void destroyJoint(Joint2D *joint)
销毁 Joint2D 的 Box2D 关节并重置标志
void createJoint(Joint2D *joint)
为 Joint2D 创建 Box2D 关节(幂等;bodyA/bodyB 就绪才创建)
void destroyRigidBody(RigidBody2D *body)
销毁 RigidBody2D 的物理体并注销(组件卸下时调用)
const Vector2 & getGravity() const
定义 PhysicsSystem2D.h:51
void update() override
每帧更新(纯虚)
void fixedUpdate(float fixedDt) override
固定步阶段(Scene 固定步循环节拍调用):补建自愈 → 步进一次 → 同步 Transform → 收集派发本步接触事件
void rebuildJoint(Joint2D *joint)
重建 Box2D 关节(字段改动/类型切换/目标变更后调用):销毁旧关节按当前字段重建
PhysicsSystem2D(int priority=50)
float getPixelsPerMeter() const
当前像素↔米比例(实例字段,各物理系统独立)
定义 PhysicsSystem2D.h:56
void unregisterRigidBody(RigidBody2D *body)
void setPixelsPerMeter(float ppm)
设置像素↔米比例(必须在 init() 之前调用),默认 32
bool onComponentAttached(Component *component) override
组件挂载时调用。返回 true 表示本系统认领并处理了该组件(组件据此确定已注册)。
void onComponentDetached(Component *component) override
组件卸下时调用。
void createRigidBody(RigidBody2D *body)
为 RigidBody2D 创建物理体(组件认领时调用,从 Transform 读初始位姿)
void onFieldChanged(const std::string &fieldName) override
反射字段被编辑器直写后回调(供子系统把字段变更实时同步到运行时状态)
void registerJoint(Joint2D *joint)
注册关节组件(onAttach 时调用),并尝试创建 Box2D 关节
void init() override
初始化(可覆写)
void unregisterJoint(Joint2D *joint)
注销关节组件(onDetach/onDestroy 时调用)
friend class RigidBody2D
定义 PhysicsSystem2D.h:79
void destroy() override
销毁(纯虚)
刚体组件
定义 RigidBody2D.h:24
System(int priority=0)
定义 AnimationClip.h:12
glm::vec2 Vector2
定义 Math.h:7