2021SC@SDUSC
本次我们将继续针对flaxEngine游戏引擎中的物理引擎中的joints(关节)进行源代码的分析,由于joints(关节)相关的源代码的内容相对较少,所以我们进行对剩下连接(关节)进行源代码的分析。
一:Distance Joint固定关节
距离铰链
其核心就是在两个物体之间的距离上保持上限或下限(或两者)的物理关节。
(1)Distance Joint.h文件:
API_ENUM(Attributes="Flags") enum class DistanceJointFlag
{
/// <summary>
/// The none limits.
/// </summary>
None = 0,
/// <summary>
/// The minimum distance limit.
/// </summary>
MinDistance = 0x1,
/// <summary>
/// Uses the maximum distance limit.
/// </summary>
MaxDistance = 0x2,
/// <summary>
/// Uses the spring when maintaining limits
/// </summary>
Spring = 0x4,
};
首先是Distance Joint控制距离的选项:
1:没有距离限制
2:最小,最近距离限制
3:最大距离限制
4:维持原有距离
private:
DistanceJointFlag _flags;
float _minDistance;
float _maxDistance;
float _tolerance;
SpringParameters _spring;
构造函数中的private变量,1铰链之间的距离 2铰链之间的最小距离 3铰链之间的最大距离 4铰链之间的承受能力
API_PROPERTY(Attributes="EditorOrder(100), DefaultValue(DistanceJointFlag.MinDistance | DistanceJointFlag.MaxDistance)")
FORCE_INLINE DistanceJointFlag GetFlags() const
{
return _flags;
}
get函数 获取关节模式标志。控制联合行为。
API_PROPERTY() void SetFlags(DistanceJointFlag value);
setFlags函数 设置关节模式标志。控制联合行为
API_PROPERTY(Attributes="EditorOrder(110), DefaultValue(0.0f), Limit(0.0f), EditorDisplay(\"Joint\")")
FORCE_INLINE float GetMinDistance() const
{
return _minDistance;
}
仅当设置了DistanceJointFlag.MinDistance标志时使用。最小距离不得超过最大距离。默认值:0,范围:[0,float.MaxValue]
API_PROPERTY(Attributes="EditorOrder(120), DefaultValue(10.0f), Limit(0.0f), EditorDisplay(\"Joint\")")
FORCE_INLINE float GetMaxDistance() const
{
return _maxDistance;
}
仅在设置了DistanceJointFlag.MaxDistance标志时使用。最大距离不得小于最小距离。默认值:0,范围:[0,float.MaxValue]。
API_PROPERTY(Attributes="EditorOrder(130), DefaultValue(25.0f), Limit(0.0f), EditorDisplay(\"Joint\")")
FORCE_INLINE float GetTolerance() const
{
return _tolerance;
}
关节激活前超出关节[min,max]范围的距离。默认值:25,范围:[0.1,float.MaxValue]。
API_PROPERTY(Attributes="EditorOrder(140), EditorDisplay(\"Joint\")")
FORCE_INLINE SpringParameters GetSpringParameters() const
{
return _spring;
}
获取弹簧参数
API_PROPERTY() float GetCurrentDistance() const;
public:
// [Joint]
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
protected:
// [Joint]
PxJoint* CreateJoint(JointData& data) override;
获取关节的当前距离
(2)Distance Joint.c文件:
DistanceJoint::DistanceJoint(const SpawnParams& params)
: Joint(params)
, _flags(DistanceJointFlag::MinDistance | DistanceJointFlag::MaxDistance)
, _minDistance(0.0f)
, _maxDistance(10.0f)
, _tolerance(25.0f)
{
}
首先是Distance Joint的构造函数
对Distance Joint.h头文件中的相应参数进行了初始化。
void DistanceJoint::SetFlags(DistanceJointFlag value)
{
if (_flags == value)
return;
_flags = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setDistanceJointFlags(static_cast<PxDistanceJointFlag::Enum>(value));
}
}
setFlags 相应的实现,如果flags等于value 之间返回,如果不是添加铰链。
void DistanceJoint::SetMinDistance(float value)
{
value = Math::Clamp(value, 0.0f, _maxDistance);
if (Math::NearEqual(value, _minDistance))
return;
_minDistance = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setMinDistance(value);
}
}
setMinDistance 相应的实现 判断是否有,如果没有添加距离参数和相应的铰链。
void DistanceJoint::SetMaxDistance(float value)
{
value = Math::Max(_minDistance, value);
if (Math::NearEqual(value, _maxDistance))
return;
_maxDistance = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setMaxDistance(value);
}
}
添加最大距离。
void DistanceJoint::SetTolerance(float value)
{
value = Math::Max(0.1f, value);
if (Math::NearEqual(value, _tolerance))
return;
_tolerance = value;
if (_joint)
{
static_cast<PxDistanceJoint*>(_joint)->setTolerance(value);
}
}
添加容忍度。
PxJoint* DistanceJoint::CreateJoint(JointData& data)
{
const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0));
const PxTransform trans1(C2P(data.Pos1), C2P(data.Rot1));
auto joint = PxDistanceJointCreate(*data.Physics, data.Actor0, trans0, data.Actor1, trans1);
joint->setMinDistance(_minDistance);
joint->setMaxDistance(_maxDistance);
joint->setTolerance(_tolerance);
joint->setDistanceJointFlags(static_cast<PxDistanceJointFlag::Enum>(_flags));
joint->setStiffness(_spring.Stiffness);
joint->setDamping(_spring.Damping);
return joint;
创建一个连接。
二::Fixed Joint固定关节(固定铰链)
固定关节组件用于约束一个游戏对象对另一个游戏对象的运动。
固定关节适用于以下的情形:当希望将对象较容易与另—个对象分开时,或者连接两个没有父子关系的对象使其一起运动,使用固定关节的对象自身需要有—个刚体组件。
(1)Fixed joint.h 文件
API_CLASS() class FLAXENGINE_API FixedJoint : public Joint
{
DECLARE_SCENE_OBJECT(FixedJoint);
protected:
// [Joint]
PxJoint* CreateJoint(JointData& data) override;
};
在两个附着体之间保持固定距离和方向的物理关节。
(2)Fixed joint.c 文件
FixedJoint::FixedJoint(const SpawnParams& params)
: Joint(params)
{
}
PxJoint* FixedJoint::CreateJoint(JointData& data)
{
const PxTransform trans0(C2P(data.Pos0), C2P(data.Rot0));
const PxTransform trans1(C2P(data.Pos1), C2P(data.Rot1));
return PxFixedJointCreate(*data.Physics, data.Actor0, trans0, data.Actor1, trans1);
}
构造函数,和初始化内容。
因为Fixed joint代码内容相对较少,所以本次是放了两个内容进行讲解。