Box2d collision
最近学习了一下box2d的源码,主要学习collision部分,记录一下。
dynamic_tree
box2d的dynamic_tree使用的BVH aabb包围盒,新建节点的时候会将包围盒的aabb增大0.1米(参数可修改,调节精度和效率)然后寻找一个兄弟节点使得合并之后的父节点aabb周长最小。
shape
box2d支持的shape有 circle,polygon,edge,chain。
不支持扇形,可以考虑用polygon模拟,具体误差还没有测。
shape拥有skin,一般是0.01m(应该是),用来防止碰撞检测失败,提高碰撞检测效率。
关于edge 和 chain,chain其实就是多个edge连接起来的,连接处存在一个ghost顶点,为了防止碰撞检测失败的。
world body fixture
这部分主要想说的是world,body,fixture他们之间的关系。
一个world可以创建多个body,body之间用链表连接,一个body可以创建多个fixture,也是用链表连接,一个fixture可以创建多个fixture proxy(即fixture节点信息)
一般来说,一个fixture只有一个fixture proxy,但是对于chain shape来说,他可能会有多个edge,所以就会有多个fixture proxy。
body负责的是刚体,如果不考虑物理效果,其实就是一个中心点,不加fixture就没有任何实际意义。
fixture里面会负责shape,以及与body的相对坐标,body变换的时候,body上的所有fixture会跟着变换。
fixture proxy会存fixture的aabb信息等到dynamic_tree里面,每个fixture proxy有一个proxy id,这个id是全局唯一的。
raycast
raycast一般会有一个起点和终点,raycast的流程:
-
先找到相交的最大的aabb盒子
-
依照子节点创建顺序继续遍历盒子,直到碰撞位置
关于这点其实并不太确定,没有仔细去看,不过按照测试的数据来说应该是这个样子的。并不是所按照离起点的距离为标准来的。
RaycastCallback函数中的fraction会代表碰撞离起点的比例。
返回值一共有4个
- -1 代表着忽视所有的碰撞
- 0 代表这碰到第一个就终止 注意:这个就是上面说的,其实并不一定是最近的那一个
- fraction 代表从fraction这里截断继续做raycast。 这个参数取值范围是0~1,初始值为1,每次都会降低,所以返回值是fraction的话就代表着取离起点最近的那个点。
- 1 代表着会经过所有的碰撞
暂时就这些,以后学到了再做补充。如有错误欢迎指正,非常感谢。