2021SC@SDUSC
上次我们分析flax Engine游戏引擎中物理引擎的刚体(RigidBody.h)头文件,包括了变量的定义和函数的定义,这次我将进入刚体的 RigidBody.c 文件进行刚体的源代码分析和理解。
首先是 刚体的构造函数 创建了一个脚本(spawnParams)对象 创建physicsActor对象这个
physicsActor对象我们在上次刚体的头文件中已经分析过它具体的含义,在此不多做解释。以及下
面这些物理参数的初始化,物理参数的定义我们在上次头文件中也已经逐个分析过了它们各自代表
的物理属性,总之构造函数就是创建了一个刚体脚本对象,并赋予了其基本的物理属性。
创建一个对象(实体)
1:首先判断是否创建成功:如果不成果返回空
2:创建一个内存栈和刚体实力(body)Create rigid body
const PxTransform trans(C2P(_transform.Translation), C2P(_transform.Orientation));
_actor = CPhysX->createRigidDynamic(trans);
_actor->userData = this;
3:设置标志位:
const bool isActive = _enableSimulation && IsActiveInHierarchy();
if (!isActive)
actorFlags |= PxActorFlag::eDISABLE_SIMULATION;
if (!_enableGravity)
actorFlags |= PxActorFlag::eDISABLE_GRAVITY;
_actor->setActorFlags(actorFlags);
if (_useCCD)
_actor->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_CCD, true);
if (_isKinematic)
_actor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
4:应用属性的初始化
_actor->setLinearDamping(_linearDamping);
_actor->setAngularDamping(_angularDamping);
_actor->setMaxAngularVelocity(_maxAngularVelocity);
_actor->setRigidDynamicLockFlags(static_cast<PxRigidDynamicLockFlag::Enum>(_constraints));
5:查找要附加的碰撞器
for (int32 i = 0; i < Children.Count(); i++)
{
auto collider = dynamic_cast<Collider*>(Children[i]);
if (collider && collider->CanAttach(this))
{
collider->Attach(this);
}
}
6: UpdateMass();这个函数的定义我将在下面进行分析。
if (!_centerOfMassOffset.IsZero())
{
PxTransform pose = _actor->getCMassLocalPose();
pose.p += C2P(_centerOfMassOffset);
_actor->setCMassLocalPose(pose);
}
7:质心偏移技术
// Register actor
const bool putToSleep = !_startAwake && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy();
Physics::AddActor(_actor, putToSleep);
// Update cached data
UpdateBounds();
8:注册对象将对象实例化,这样就完成了一个刚体对象的创建。
下面是针对头文件中定义的get()和set()方法的具体化。对于不同物理属性的get(), set()
方法。在此我仅仅对其中一个set()和get()方法进行解读,其他的set()和get()方法也是
大同小异 。
上面的两种图片是针对线性速度的set()和get()方法。
线性速度的get():返回actor 对象的线性速度(保存在P2C中,P2C是一个vector 如果能actor存在返回之,若不存在则返回ZERO零)
线性速度的set():函数参数是线性速度的集合Vector(线性速度包括加速度,不同地域上的速度具体定义在其他包括这里不进行详细的讲解)将对象的速度保存在C2P中 并且将其唤醒。
在flax Engine游戏引擎中 mass代表物体的质量,其质量和重力,碰撞后的冲力有关。上面源代码是有关更新物体重力的操作。
首先如果物体是空的那么它就没有质量,直接return
定义两个有关质量的物理量:float densityKGPerCubicUU = 1.0f;
float raiseMassToPower = 0.75f;
链接物理材质或曝光密度参数:PxRigidBodyExt::updateMassAndInertia(*_actor, densityKGPerCubicUU);
获取之前的oldmass :const float oldMass = _actor->getMass(); (目的是在保持惯性张量的同时应用新的质量)
定义新的物理质量:float newMass;
如果 重写质量是false的话:则应用用户定义的质量缩放
否则的话使用最大的质量
因为游戏引擎保证物体的质量不为零,所以要判定>0
最后将用户定义的质量保存到actor对象属性中去。就完成对一个刚体质量的更新。
接下来就是针对刚体一些参数的添加,就是根据游戏引擎的使用者在编制一个游戏角色时要针对其添加不同属性比如: force,Torque等等物理属性的定义。
最后开始游戏和结束游戏的对刚体的操作
void RigidBody::BeginPlay(SceneBeginData* data)
{
CreateActor();
// Base
PhysicsActor::BeginPlay(data);
}
开始游戏时:创建一个刚体对象并将刚体数据初始化。
void RigidBody::EndPlay()
{
// Detach all the shapes
PxShape* shapes[8];
while (_actor && _actor->getNbShapes() > 0)
{
const uint32 count = _actor->getShapes(shapes, 8, 0);
for (uint32 i = 0; i < count; i++)
{
_actor->detachShape(*shapes[i], false);
}
}
// Base
PhysicsActor::EndPlay();
if (_actor)
{
// Remove actor
Physics::RemoveActor(_actor);
_actor = nullptr;
}
}
结束游戏时先拆除形状再将游戏结束。
以上便是flaxEngine游戏引擎中物理引擎中刚体的全部介绍。