2022-08-02【BEP】Pair Overlap

2022-08-02  本文已影响0人  持刀的要迟到了

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);

分析:

  1. new Pair
    CollidableA : BroadPhaseEntry
    CollidableB : BroadPhaseEntry
  2. 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

上一篇 下一篇

猜你喜欢

热点阅读