2022-08-02【BEP】Pair Overlap
https://github.com/bepu/bepuphysics1/blob/master/BEPUphysics/Character/QueryManager.cs#L144
Does Bepu v1 supports query overlapped object? - BEPUphysics (bepuentertainment.com)
EntityCollidable entry = affectedEntries[i] as EntityCollidable;
if (entry.entity == detectBox)
continue;
CollidablePair pair = new CollidablePair(detectBox.CollisionInformation, entry);
CollidablePairHandler pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
if (pairHandler.CollisionRule == CollisionRule.Normal)
{
pairHandler.SuppressEvents = true;
pairHandler.UpdateCollision(0);
pairHandler.SuppressEvents = false;
if (pairHandler.Contacts.Count > 0)
touchedEntity.Add(entry.entity);
}
pairHandler.CleanUp();
pairHandler.Factory.GiveBack(pairHandler);
分析:
- new Pair
CollidableA : BroadPhaseEntry
CollidableB : BroadPhaseEntry - NarrowPhaseHelper.GetPairHandler(ref pair)
=> return CollidablePairHandler:NarrowPhasePair
2.1 BroadPhaseOverlap:CollidableA,CollidableB,Rules::Default
=> return overlap
2.2 GetPairHandler(olverlap)
=> return CollidablePairHandler
Dictionary<TypePair, NarrowPhasePairFactory> collisionManagers
工厂类型管理器,存储类型及类型对应工厂。
TypePair:找到一个复合类型作为Key的方式,就是创建一个这个对象,然后自己重写Equal。
它去工厂里找,Capsule和Box的pair工厂,但是没找到。
因此执行了默认的处理方式:Convex和Convex。
工厂结构:
static class NarrowPhaseHelper
一个静态类,持有一个静态工厂
class Factories
List<NarrowPhasePairFactory> factories
NarrowPhasePairFactory<T>static Dictionary<TypePair, NarrowPhasePairFactory> collisionManagers;
字典表:通过哈希值进行key值检索,找到value。
class A
class SubA<T> : A
泛型类,继承类A,说明这是一个组合方式,是一个有T属性的A
适用情况举例:
碰撞盒<形状> : 碰撞盒
这个类就是一个有独特形状的碰撞盒了。
核心算法:
GetContactInformation
举例,球球Contact,根据位置和速度获得相对速度:
//Compute relative velocity
Vector3 velocity;
if (EntityA != null)
{
Vector3.Subtract(ref info.Contact.Position, ref EntityA.position, out velocity);
Vector3.Cross(ref EntityA.angularVelocity, ref velocity, out velocity);
Vector3.Add(ref velocity, ref EntityA.linearVelocity, out info.RelativeVelocity);
}
else
info.RelativeVelocity = new Vector3();
if (EntityB != null)
{
Vector3.Subtract(ref info.Contact.Position, ref EntityB.position, out velocity);
Vector3.Cross(ref EntityB.angularVelocity, ref velocity, out velocity);
Vector3.Add(ref velocity, ref EntityB.linearVelocity, out velocity);
Vector3.Subtract(ref info.RelativeVelocity, ref velocity, out info.RelativeVelocity);
}
Pair计算流程:
获得两个Collidable,创建CollidablePair
获得Pair的Handler,通过新建一个BroadPhaseOverlap,去工厂里找这俩东西的类型,
如果找到对应的工厂,通过工厂重写的方法,会返回一个NarrowPhasePair的子类对象。
如果没有对应的工厂,那么使用兜底的规则:ConvexConvex工厂来返回执行。
NarrowPhasePairFactory<GeneralConvexPairHandler> ConvexConvex
StandardPairHandler->GeneralConvexContactManifold->GeneralConvexPairTester
StandardPairHandler->ContactManifold(更新激活未激活物体用)
得到Pair后,压制pair事件 suppressEvents = true
更新碰撞:StandardPairHandler.UpdateCollision
ContactManifold.Update(dt)
GeneralConvexContactManifold.Update
ContactRefresher.ContactRefresh(刷新所有已有的contact),一开始数量是0,跳出
pairTester(GeneralConvexPairTester).GenerateContactCandidate
上一个状态:分离
GJKToolbox.AreShapesIntersecting!!!!关键计算!!!!
1.把B碰撞盒(box),转换到A(胶囊体)的坐标空间
2.创建一个SimpleSimplex( GJK simplex, supporting boolean intersection tests. 支持布尔交集测试)
3.GetLocalMinkowskiExtremePoint