AVBD-demo2d源代码漫游:从main.cpp到物理引擎核心组件
AVBD物理引擎是增强顶点块下降算法的2D实现,专为物理仿真场景设计。这个开源项目提供了一个简单易懂的AVBD技术演示,让开发者能够快速理解2D物理仿真的核心原理。本文将带您深入探索AVBD-demo2d的源代码结构,从程序入口到物理引擎的核心组件,为您揭开2D物理仿真的神秘面纱。
🚀 项目概览与核心架构
AVBD-demo2d是一个2D物理仿真引擎,实现了增强顶点块下降算法。项目采用简洁的C++架构,核心文件位于source/目录中,包含不到2000行代码却实现了完整的物理仿真功能。
主要文件结构:
source/
├── main.cpp # 程序入口和UI交互
├── solver.h # 求解器核心类定义
├── solver.cpp # 求解器实现
├── rigid.cpp # 刚体实现
├── joint.cpp # 关节约束
├── spring.cpp # 弹簧力
├── motor.cpp # 马达力
├── collide.cpp # 碰撞检测
├── manifold.cpp # 碰撞流形
└── maths.h # 数学工具库
🎯 main.cpp:程序入口与交互界面
main.cpp是整个应用的控制中心,负责初始化SDL窗口、OpenGL上下文和ImGui界面。它实现了用户交互逻辑,包括:
- 相机控制:支持键盘(WASD/QE)和鼠标(中键拖动/滚轮缩放)操作
- 物理交互:左键拖动刚体、右键创建新盒子
- 触摸支持:针对移动设备的双指缩放和平移手势
- 场景管理:通过下拉菜单切换不同的物理演示场景
// 主循环核心逻辑
void mainLoop() {
// 处理输入事件
while (SDL_PollEvent(&event)) {
ImGui_ImplSDL2_ProcessEvent(&event);
// ... 事件处理逻辑
}
// 更新物理状态
if (!paused) solver->step();
// 渲染场景
solver->draw();
ImGui::Render();
SDL_GL_SwapWindow(Window);
}
🔧 Solver类:物理求解器的核心
Solver类是AVBD算法的核心实现,负责管理所有刚体和力约束,并执行物理仿真计算。
核心数据结构
| 成员变量 | 类型 | 说明 |
|---|---|---|
bodies | Rigid* | 刚体链表头指针 |
forces | Force* | 力约束链表头指针 |
dt | float | 时间步长(默认1/60秒) |
gravity | float | 重力加速度(默认-10) |
iterations | int | 求解器迭代次数(默认10) |
求解流程解析
AVBD求解器的核心算法流程分为四个主要阶段:
- 初始化阶段:设置初始位置和速度
- 碰撞检测:O(n²)的宽相位碰撞检测
- 主求解循环:执行指定次数的迭代计算
- 后稳定化:可选的后处理步骤减少位置误差
void Solver::step() {
// 1. 碰撞检测
for (Rigid* bodyA = bodies; bodyA != 0; bodyA = bodyA->next) {
for (Rigid* bodyB = bodyA->next; bodyB != 0; bodyB = bodyB->next) {
if (!bodyA->constrainedTo(bodyB))
new Manifold(this, bodyA, bodyB);
}
}
// 2. 初始化刚体状态
for (Rigid* body = bodies; body != 0; body = body->next) {
body->inertial = body->position + body->velocity * dt;
if (body->mass > 0)
body->inertial += float3{ 0, gravity, 0 } * (dt * dt);
}
// 3. 主求解循环
for (int it = 0; it < totalIterations; it++) {
// 原始变量更新
for (Rigid* body = bodies; body != 0; body = body->next) {
// 构建线性系统并求解
}
// 对偶变量更新
if (it < iterations) {
for (Force* force = forces; force != 0; force = force->next) {
// 更新拉格朗日乘子
}
}
}
}
📦 Rigid类:刚体物理的实现
Rigid类定义了2D刚体的物理属性,包括位置、速度、质量和摩擦力等:
struct Rigid {
float3 position; // 位置 (x, y, 角度)
float3 velocity; // 速度 (vx, vy, 角速度)
float2 size; // 尺寸 (宽度, 高度)
float mass; // 质量
float moment; // 转动惯量
float friction; // 摩擦系数
};
刚体通过链表结构连接,支持动态创建和销毁。每个刚体可以关联多个力约束,形成复杂的物理系统。
🔗 Force约束系统:物理交互的基础
AVBD-demo2d实现了多种力约束类型,每种都继承自基类Force:
1. Joint(关节约束)
- 实现刚体间的旋转关节
- 支持角度限制和断裂阈值
- 在solver.h中定义
2. Spring(弹簧力)
- 简单的线性弹簧
- 可设置刚度和自然长度
- 用于模拟弹性连接
3. Motor(马达力)
- 施加扭矩实现角速度控制
- 支持最大扭矩限制
- 用于驱动机械系统
4. Manifold(碰撞流形)
- 处理刚体间碰撞接触
- 支持最多两个接触点
- 实现静态和动态摩擦
5. IgnoreCollision(碰撞忽略)
- 特殊力类型,无物理效果
- 仅用于标记忽略碰撞的刚体对
🎪 演示场景:物理效果的展示
scenes.h文件中定义了多个物理演示场景,展示了AVBD引擎的强大功能:
| 场景名称 | 描述 | 物理特性 |
|---|---|---|
sceneEmpty | 空场景 | 基础测试环境 |
sceneStack | 堆叠盒子 | 重力、碰撞、摩擦 |
sceneRod | 连接杆系统 | 关节约束、弹性 |
sceneSoftBody | 软体网格 | 网格连接、内部约束 |
sceneJointGrid | 关节网格 | 大规模约束系统 |
sceneMotor | 马达驱动 | 扭矩控制、运动传递 |
sceneFracture | 断裂演示 | 约束断裂、破坏效果 |
每个场景都通过简单的代码构建复杂的物理系统,例如软体场景:
static void sceneSoftBody(Solver* solver) {
const int W = 15, H = 5;
Rigid* grid[W][H];
// 创建网格节点
for (int x = 0; x < W; x++)
for (int y = 0; y < H; y++)
grid[x][y] = new Rigid(solver, { 1, 1 }, 1.0f, 0.5f,
{ (float)x, (float)y + 5.0f, 0.0f });
// 添加水平和垂直关节
for (int x = 1; x < W; x++)
for (int y = 0; y < H; y++)
new Joint(solver, grid[x-1][y], grid[x][y],
{ 0.5f, 0 }, { -0.5f, 0 }, { 1000, 1000, 100 });
}
⚙️ 数学工具库:向量与矩阵运算
maths.h提供了2D物理仿真所需的数学工具:
- 向量运算:
float2、float3的加减乘除 - 矩阵运算:
float2x2、float3x3的乘法和求逆 - 几何函数:旋转矩阵、叉积、点积
- 求解器:LDL分解求解线性系统
这些数学工具为物理计算提供了高效的基础支持。
🚀 编译与运行指南
项目支持原生编译和WebAssembly编译两种方式:
原生编译(桌面应用)
git clone --recurse-submodules https://gitcode.com/gh_mirrors/avb/avbd-demo2d
mkdir build && cd build
cmake .. && cmake --build . --config Release
./Release/avbd_demo2d
Web编译(浏览器运行)
mkdir build-web && cd build-web
emcmake cmake .. && ninja
# 打开 avbd_demo2d.html
💡 学习价值与实际应用
AVBD-demo2d虽然代码量不大,但包含了完整的物理引擎架构,具有很高的学习价值:
- 算法理解:清晰的AVBD算法实现,适合学习物理仿真原理
- 架构设计:模块化的类设计,便于扩展和维护
- 性能优化:简单的碰撞检测和求解器实现,可作为优化起点
- 跨平台:支持桌面和Web平台,展示现代图形编程技术
这个项目特别适合:
- 物理引擎初学者:理解2D物理仿真的基本原理
- 游戏开发者:学习物理约束的实现方法
- 计算机图形学学生:研究数值求解器的实际应用
- 算法爱好者:探索增强顶点块下降算法的具体实现
📚 深入学习建议
如果您想进一步探索AVBD-demo2d:
- 修改参数:尝试调整
solver->dt、solver->iterations等参数观察效果 - 添加新约束:基于现有
Force类实现新的约束类型 - 优化性能:改进碰撞检测算法(如空间划分)
- 扩展功能:添加连续碰撞检测或更复杂的材质系统
通过深入研读source/目录下的源代码,您将能够掌握2D物理仿真的核心技术,并在此基础上构建更复杂的物理系统。
AVBD物理引擎的简洁实现展示了现代物理仿真的核心思想。无论您是物理引擎的初学者还是有经验的开发者,这个项目都提供了宝贵的学习资源和实践参考。通过理解从main.cpp到各个核心组件的代码结构,您将能够更好地掌握2D物理仿真的实现原理和应用技巧。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



