2021SC@SDUSC
最后我们进行flax Engine游戏引擎中物理引擎中physics(物理)的分析,这个包中含有所有用到的物理系统的相关应用,包括四个大类的定义:1:物理对撞机 2:铰链 3:碰撞机 4:碰撞数据。
物理数据的定义:1:光线 2:模拟物理系统
pyhsics 为flax Engine中物理引擎提供物理作用,如重力的作用,碰撞后的结果,线性加速度,空气阻力等等。也提供了我们之前分析的actor,joints,Collider的相关操作,所以这是我们最后的一个重点。我们将仔细分析其中的源代码的内容,所以在分析的时候我们再不像之前的先分析.h文件然后再分析.c文件,而是将两者结合,一起分析其中变量和函数的定义和相应的实现来体会物理引擎的任务和相应的功能。
注:1:flax Engine游戏引擎中使用了PhysX技术:
PhysX技术简而言之就是一种物理加速图像引擎。主要使用在显卡上使物理效果更加逼真的一种技术。
2:CCD元件:
CCD元件是电荷耦合元件。可以称为CCD图像传感器,也叫图像控制器。CCD是一种半导体器件,能够把光学影像转化为电信号,在Flax Engine游戏引擎中我们使用了CCD模块控制单元来对图像进行像素点的转化。
由于相关内容很多,所以我将采用一个.h文件的定义和.c文件源代码实现相结合的方式来进行最后的physics类的源代码的分析。在接下来的几次中我将分部对其进行源代码的分析。
API_STRUCT() struct RayCastHit
1:光线投影的结构体:
1:其中定义了被击中的碰撞器 physicsColliderActor
2:光线照射到的曲面的法线: Normal
3:从光线原点到命中位置的距离:distance
4:世界空间中光线撞击对撞机的点:Point
5:三角形网格和高度场的碰撞点重心坐标:UV
定义相关的函数:使用physX技术
void Gather(const PxRaycastHit& hit)
收集命中的数据。
void Gather(const PxSweepHit& hit);
收集命中数据。
API_FIELD() PhysicsColliderActor* Collider;
/// <summary>
/// The normal of the surface the ray hit.
/// </summary>
API_FIELD() Vector3 Normal;
/// <summary>
/// The distance from the ray's origin to the hit location.
/// </summary>
API_FIELD() float Distance;
/// <summary>
/// The point in the world space where ray hit the collider.
/// </summary>
API_FIELD() Vector3 Point;
/// <summary>
/// The barycentric coordinates of hit point, for triangle mesh and height field.
/// </summary>
API_FIELD() Vector2 UV;
下面是关于模拟物理系统的相关内容。
API_CLASS(Static) class FLAXENGINE_API Physics
static PxPhysics* GetPhysics();
首先是定义了一个静态的物理主变量。
是一个辅助物理变量。
static PxCooking* GetCooking()
/// <summary>
/// Gets PhysX scene object
/// </summary>
static PxScene* GetScene();
/// <summary>
/// Gets PhysX characters controller manager object
/// </summary>
static PxControllerManager* GetControllerManager();
/// <summary>
/// Gets the physics tolerances scale.
/// </summary>
static PxTolerancesScale* GetTolerancesScale();
/// <summary>
/// Gets the default query filter callback used for the scene queries.
/// </summary>
static PxQueryFilterCallback* GetQueryFilterCallback();
/// <summary>
/// Gets the default query filter callback used for the character controller collisions detection.
/// </summary>
static PxQueryFilterCallback* GetCharacterQueryFilterCallback();
/// <summary>
/// Gets the default physical material.
/// </summary>
static PxMaterial* GetDefaultMaterial();
flax engine使用PhysX技术。
1:static PxScene* GetScene() :获取PhysX场景对象
在.c文件中的函数现实返回之前定义的PhysicsScene。
PxScene* Physics::GetScene()
{
return PhysicsScene;
}
2:PxControllerManager* GetControllerManager():获取PhysX字符控制器管理器对象
在c文件中具体实现如下:
PxControllerManager* Physics::GetControllerManager()
{
return ControllerManager;
}
3:PxTolerancesScale* GetTolerancesScale():获取物理公差量表
4:PxQueryFilterCallback* GetQueryFilterCallback():获取用于场景查询的默认查询筛选器回调
5:PxQueryFilterCallback* GetCharacterQueryFilterCallback();获取用于字符控制器冲突检测的默认查询筛选器回调
6: PxMaterial* GetDefaultMaterial();/获取默认的物理材质
c文件中实现的方式于上述三个类似,都是返回定义的变量。
static bool AutoSimulation
自动模拟功能。如果在自动更新后执行物理模拟,则为True,否则用户应执行此操作
static Vector3 GetGravity();
获取当前重力。
Vector3 Physics::GetGravity()
{
return PhysicsScene ? P2C(PhysicsScene->getGravity()) : Vector3::Zero;
}
c文件的具体现实为是否是当前场景,返回vector2中重力。
API_PROPERTY() static void SetGravity(const Vector3& value);
设置当前重力。
void Physics::SetGravity(const Vector3& value)
{
if (PhysicsScene)
PhysicsScene->setGravity(C2P(value));
}
c文件的函数实现判断是否是场景,如果是将重力赋值。
API_PROPERTY() static bool GetEnableCCD();
获取CCD启用标志。
bool Physics::GetEnableCCD()
{
return PhysicsScene ? (PhysicsScene->getFlags() & PxSceneFlag::eENABLE_CCD) == PxSceneFlag::eENABLE_CCD : !PhysicsSettings::Get()->DisableCCD;
}
c文件中的函数现实,判断在当前场景下CCD是否已经启用,如果启用就设置为True,否则为Flase。
static void SetEnableCCD(bool value)
设置CCD启用标志。
void Physics::SetEnableCCD(const bool value)
{
if (PhysicsScene)
PhysicsScene->setFlag(PxSceneFlag::eENABLE_CCD, value);
}
c文件设置CCD当前场景下CCD标志位。
API_PROPERTY() static float GetBounceThresholdVelocity();
API_PROPERTY() static void SetBounceThresholdVelocity(float value);
获取对象反弹所需的最小相对速度。
设置对象反弹所需的最小相对速度。
float Physics::GetBounceThresholdVelocity()
{
return PhysicsScene ? PhysicsScene->getBounceThresholdVelocity() : PhysicsSettings::Get()->BounceThresholdVelocity;
}
void Physics::SetBounceThresholdVelocity(const float value)
{
if (PhysicsScene)
PhysicsScene->setBounceThresholdVelocity(value);
}
c文件中具体函数的实现。
uint32 LayerMasks[32]
碰撞层遮罩。用于定义基于层的碰撞检测。
API_FUNCTION() static bool RayCast(const Vector3& origin, const Vector3& direction, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
上述函数是对场景中的对象执行光线投射。
参数:origin:光线的原点 direction:光线的规格化方向 maxDistance:光线应检查碰撞的最大距离 hitTriggers:如果设置为true,将命中触发器,否则将跳过它们。
API_FUNCTION() static bool RayCastAll(const Vector3& origin, 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 BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, const Quaternion& rotation = Quaternion::Identity, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
使用长方体几何体对场景中的对象执行扫描测试。
参数:center:框的中心 halfExtents:框在每个方向上的一半大小 direction:用于投射长方体的规范化方向 rotation:框旋转 maxDistance:光线应检查碰撞的最大距离 layerMask:用于过滤结果的图层掩码。 hitTriggers:如果设置为true,将命中触发器,否则将跳过它们。
API_FUNCTION() static bool BoxCastAll(const Vector3& center, const Vector3& halfExtents, 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);
改写BoxCastAll方法 添加result参数:结果令人满意。仅当方法返回true时有效
API_FUNCTION() static bool CheckSphere(const Vector3& center, float radius, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
检查给定球体是否与其他碰撞器重叠。
参数:center球体中心位置 radius:球体的半径 layerMask:用于过滤结果的图层掩码 hitTriggers:如果球体与任何匹配对象重叠,则为True,否则为false。
本次我们先对physics这些源代码进行分析,在下次我们继续对flax Engine游戏引擎中physics 相关内容进行源代码的分析工作。