(十三)Flax Engine游戏引擎物理引擎 physics(2)

2021SC@SDUSC

        上篇我们进行flax Engine游戏引擎中物理引擎中physics(物理)内容的部分分析。讲述了光线和模拟物理系统中的一些函数定义和变量的源代码,本次我们紧接着上次的内容继续对flax Engine物理引擎中最关键的内容physics进行源代码的分析。

        

    API_FUNCTION() static bool SphereCast(const Vector3& center, float radius, const Vector3& direction, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true);

        此函数的功能是使用球体几何体对场景中的对象执行扫描测试。

参数为1:center 球体中心的位置 2:radius:球体半径 3:direction:投射球体的标准化方向 4:maxDistance:光线应检查碰撞的最大距离 5:layerMask:将命中触发器,否则将跳过它们 5:hitTriggers:如果球体命中匹配对象,则为True,否则为false。

    API_FUNCTION() static bool SphereCastAll(const Vector3& center, float radius, const Vector3& direction, API_PARAM(Out) Array<RayCastHit, HeapAllocation>& results, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true);

        此函数的功能是使用球体几何体对场景中的所有对象执行扫描测试。

与上述方法不同的是参数多了一个results:结果命中,仅当方法返回true时有效。

    API_FUNCTION() static bool CapsuleCast(const Vector3& center, float radius, float height, const Vector3& direction, const Quaternion& rotation = Quaternion::Identity, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true);

        此函数的功能是使用胶囊几何体对场景中的对象执行扫描测试。

相关参数:1:center:胶囊中心 2:radius:胶囊的半径 3:height:胶囊的高度,不包括顶部和底部球体 4:diection:投射胶囊的标准化方向 5:rotation:胶囊旋转 6:maxDIstance:光线应检查碰撞的最大距离 7:layerMask:如果设置为<c>true,将命中触发器,否则将跳过它们 8:返回值:如果胶囊命中匹配对象,则为True,否则为false。

    API_FUNCTION() static bool CapsuleCastAll(const Vector3& center, float radius, float height, const Vector3& direction, API_PARAM(Out) Array<RayCastHit, HeapAllocation>& results, const Quaternion& rotation = Quaternion::Identity, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true);

        此函数的功能是使用胶囊几何体对场景中的所有对象执行扫描测试。

与上述函数的区别是多一个参数:result 结果命中。仅当方法返回true时有效。

    API_FUNCTION() static bool ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, const Quaternion& rotation = Quaternion::Identity, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true);

        此函数的功能是使用凸面网格对场景中的对象执行扫描测试。

相关参数:1:center :凸面网格中心 2:convexMesh :凸面网格的比例 3:scale:投影凸面网格的规格化方向 4:direction:投影凸面网格的规格化方向 5:rotation:凸面网格旋转 6:maxDistance:光线应检查碰撞的最大距离 7:hitTiggers: 如果设置为<c>true,将命中触发器,否则将跳过它们 8:返回值:如果凸面网格命中匹配对象,则为True,否则为false。

    API_FUNCTION() static bool ConvexCastAll(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, API_PARAM(Out) Array<RayCastHit, HeapAllocation>& results, const Quaternion& rotation = Quaternion::Identity, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true);

        此函数的功能是使用凸面网格对场景中的所有对象执行扫描测试。

于上述函数相比结果命中。仅当方法返回true时有效。

    API_FUNCTION() static bool CheckBox(const Vector3& center, const Vector3& halfExtents, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true);

        此函数检查给定框是否与其他碰撞器重叠。

相关参数:1center:框的中心 2:halfExtents:框在每个方向上的一半大小 3:rotation框旋转 4:hitTriggers:如果设置为<c>true,将命中触发器,否则将跳过它们 5:返回值如果框与任何匹配对象重叠,则为True,否则为false。


    API_FUNCTION() static bool OverlapSphere(const Vector3& center, float radius, API_PARAM(Out) Array<Collider*, HeapAllocation>& results, uint32 layerMask = MAX_uint32, bool hitTriggers = true);

        此函数是查找与给定球体接触或位于其内部的所有碰撞器。

相关参数:1:center:球体中心 2:radius:球体的半径 3:result:与给定球体重叠的结果碰撞器。仅当方法返回true时有效 4:hitTriggers:如果设置为<c>true,将命中触发器,否则将跳过它们。

.h文件中的public 公共函数:

1:启动函数,用来启动引擎的物理模拟

    API_FUNCTION() static void Simulate(float dt);

在主机循环期间调用以启动物理模拟。之后使用CollectResults。

参数:三角洲时间。

.c文件中此函数的具体实现。

void Physics::Simulate(float dt)
{
    ASSERT(IsInMainThread() && !_isDuringSimulation);
    ASSERT(CPhysX);
    const auto& settings = *PhysicsSettings::Get();

    // Flush the old/new objects and the other requests before the simulation
    FlushRequests();

    // Clamp delta
    dt = Math::Clamp(dt, 0.0f, settings.MaxDeltaTime);

    // Prepare util objects
    if (ScratchMemory == nullptr)
    {
        ScratchMemory = Allocator::Allocate(SCRATCH_BLOCK_SIZE, 16);
    }
    if (Stepper == nullptr)
    {
        Stepper = New<FixedStepper>();
    }
    if (settings.EnableSubstepping)
    {
        // Use substeps
        Stepper->Setup(settings.SubstepDeltaTime, settings.MaxSubsteps);
    }
    else
    {
        // Use single step
        Stepper->Setup(dt);
    }

    // Start simulation (may not be fired due to too small delta time)
    _isDuringSimulation = true;
    if (Stepper->advance(PhysicsScene, dt, ScratchMemory, SCRATCH_BLOCK_SIZE) == false)
        return;
    EventsCallback.Clear();
    LastDeltaTime = dt;

    // TODO: move this call after rendering done
    Stepper->renderDone();
}

 FlushRequests();在模拟之前刷新旧/新对象和其他请求

dt = Math::Clamp(dt, 0.0f, settings.MaxDeltaTime);抓紧

//准备util对象

  if (ScratchMemory == nullptr)
    {
        ScratchMemory = Allocator::Allocate(SCRATCH_BLOCK_SIZE, 16);
    }
    if (Stepper == nullptr)
    {
        Stepper = New<FixedStepper>();
    }
    if (settings.EnableSubstepping)
    {
        // 使用子同步
        Stepper->Setup(settings.SubstepDeltaTime, settings.MaxSubsteps);
    }
    else
    {
        //使用单步
        Stepper->Setup(dt);
    }

启动模拟

    if (Stepper->advance(PhysicsScene, dt, ScratchMemory, SCRATCH_BLOCK_SIZE) == false)
        return;

渲染完成后移动此调用

    Stepper->renderDone();

2:公共函数:在主机循环期间调用,以收集物理模拟结果并将其应用于火灾碰撞事件。

    API_FUNCTION() static void CollectResults();

在.c文件中的实现:

由于此函数的实现很长,我们在此仅仅对其重要的内容进行源代码的分析工作。

    if (!_isDuringSimulation)
        return;
    ASSERT(IsInMainThread());
    ASSERT(CPhysX && Stepper);

    {
        PROFILE_CPU_NAMED("Physics.Fetch");

        // Gather results (with waiting for the end)
        Stepper->wait(PhysicsScene);
    }

首先:等待收集结果

  if (WheelVehicles.HasItems()):如果有车

直接改变驾驶模式时自动换档

  WheelVehiclesCache.Clear();
        WheelVehiclesCache.EnsureCapacity(WheelVehicles.Count());
        int32 wheelsCount = 0;
        for (auto wheelVehicle : WheelVehicles)
        {.........}

更新批次查询缓存

 if (wheelsCount > WheelQueryResults.Count())
        {
            if (WheelRaycastBatchQuery)
                WheelRaycastBatchQuery->release();
            WheelQueryResults.Resize(wheelsCount, false);
            WheelHitResults.Resize(wheelsCount, false);
            PxBatchQueryDesc desc(wheelsCount, 0, 0);
            desc.queryMemory.userRaycastResultBuffer = WheelQueryResults.Get();
            desc.queryMemory.userRaycastTouchBuffer = WheelHitResults.Get();
            desc.queryMemory.raycastTouchBufferSize = wheelsCount;
            desc.preFilterShader = WheelRaycastPreFilter;
            WheelRaycastBatchQuery = PhysicsScene->createBatchQuery(desc);
        }

3:公共函数:
检查物理模拟是否正在运行如果模拟处于活动状态,则为True,否则为false

    API_PROPERTY() static bool IsDuringSimulation();

.c文件中的相关源代码的现实:

bool Physics::IsDuringSimulation()
{
    return _isDuringSimulation;
}

直接返回相关bool变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值