2021SC@SDUSC
前八次文章我们分析了flax Engine 游戏引擎中物理引擎的Actors(角色)包下的相关的源码的分析,从本次开始我们将针对flax Engine 游戏引擎中的物理引擎中的Joints(关节)这个包进行,源码的分析。在分析之前我们先要了解一下Joints(关节)这个包主要的功能是什么,了解这个以后可以对我们分析源码起到不小的帮助。
在查阅相关资料后我们可以发现:Joints (关节)主要是针对两个物体间进行连接的物理量。
简而言之就是用来连接物体的关节。
在flax Engine 游戏引擎中定了5种不同的joints(关节)。
(1)Hinge Joint 铰链关节
其作用是将两个刚体束缚在一起,在两者之间产生铰链效果
(2)Fixed Joint 固定关节
固定关节组件用于约束一个游戏对象对另一个游戏对象的运动。
固定关节适用于以下的情形:当希望将对象较容易与另—个对象分开时,或者连接两个没有父子关系的对象使其一起运动,使用固定关节的对象自身需要有—个刚体组件。
(3)Spring Joint 弹簧关节
弹簧关节组件可将两个刚体连接在—起,使其像连接着弹簧那样运动。
(4) Distance Joint 固定距离关节
两个刚体之间固定距离。
(5)D6 Joint :不知道具体用途在网上也找不到相关内容,在之后查看源码后,进行相关内容的解释。
本次分析就flaxengine 游戏引擎的物理系统的大致框架来进行分析。下次我将深入源代码进行物理引擎的分析。
在接下来的几次种,我将针对不同的Joints(关节)进行源码的分析。
一:HingeJoint(铰链关节):
本次我们将针对flax Engine 游戏引擎物理引擎中的HingeJoint(铰链关节)进行源码的分析。
(1)HingeJoint.h 文件
按照管理我们首先分析HingeJoint.h文件。
API_ENUM(Attributes="Flags") enum class HingeJointFlag { /// <summary> /// The none. /// </summary> None = 0, /// <summary> /// The joint limit is enabled. /// </summary> Limit = 0x1, /// <summary> /// The joint drive is enabled. /// </summary> Drive = 0x2, };
首先是头文件的枚举类型的类:定义了limit:关节限制和drive:关节驱动
DECLARE_SCRIPTING_TYPE_MINIMAL(HingeJointDrive); /// <summary> /// Target velocity of the joint. /// </summary> API_FIELD(Attributes="Limit(0)") float Velocity = 0.0f; /// <summary> /// Maximum torque the drive is allowed to apply. /// </summary> API_FIELD(Attributes="Limit(0)") float ForceLimit = MAX_float; /// <summary> /// Scales the velocity of the first body, and its response to drive torque is scaled down. /// </summary> API_FIELD(Attributes="Limit(0)") float GearRatio = 1.0f; /// <summary> /// If the joint is moving faster than the drive's target speed, the drive will try to break. /// If you don't want the breaking to happen set this to true. /// </summary> API_FIELD() bool FreeSpin = false;
其次是铰链关节的构造函数:
定义了:
1:关节的目标速度
2:驱动器允许施加的最大扭矩
3:缩放第一个实体的速度,并缩小其对驱动扭矩的响应
4:如果关节的移动速度超过驱动器的目标速度,驱动器将尝试断开。如果你不想破坏发生,将其设置为真
public: /// <summary> /// Compares two objects. /// </summary> /// <param name="other">The other.</param> /// <returns>True if both objects are equal.</returns> bool operator==(const HingeJointDrive& other) const { return Velocity == other.Velocity && ForceLimit == other.ForceLimit && GearRatio == other.GearRatio && FreeSpin && other.FreeSpin; } };
public:比较两个对象。如果两个对象相等,则为True
DECLARE_SCENE_OBJECT(HingeJoint); private: HingeJointFlag _flags; LimitAngularRange _limit; HingeJointDrive _drive; public:
从其两个附着的实体(例如门铰链)移除除单个旋转自由度以外的所有旋转自由度的物理关节。
API_PROPERTY(Attributes="EditorOrder(100), DefaultValue(HingeJointFlag.Limit | HingeJointFlag.Drive)") FORCE_INLINE HingeJointFlag GetFlags() const { return _flags; }
获取关节模式标志。控制联合行为。
API_PROPERTY() void SetFlags(const HingeJointFlag value);
设置关节模式标志。控制联合行为
API_PROPERTY(Attributes="EditorOrder(110), EditorDisplay(\"Joint\")") FORCE_INLINE LimitAngularRange GetLimit() const { return _limit; }
确定关节的限制。“限制”将运动约束到指定的角度范围。必须在关节上启用限制标志才能识别该标记。
API_PROPERTY() void SetDrive(const HingeJointDrive& value); public: /// <summary> /// Gets the current angle of the joint (in radians, in the range (-Pi, Pi]). /// </summary> API_PROPERTY() float GetCurrentAngle() const; /// <summary> /// Gets the current velocity of the joint. /// </summary> API_PROPERTY() float GetCurrentVelocity() 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; };
1:确定关节的驱动特性。它会将关节的角速度推向特定值。必须启用关节上的驱动标志,才能激活驱动。
2:获取关节的当前角度(以弧度为单位,范围为(-Pi,Pi])。
3:获取关节的当前速度
(2):HingeJoint.c 文件
HingeJoint::HingeJoint(const SpawnParams& params) : Joint(params) , _flags(HingeJointFlag::Limit | HingeJointFlag::Drive) { _limit.Lower = -90.0f; _limit.Upper = 90.0f; }
铰链的构造函数:设置limit 和 joint
void HingeJoint::SetFlags(const HingeJointFlag value) { if (_flags == value) return; _flags = value; if (_joint) { auto joint = static_cast<PxRevoluteJoint*>(_joint); joint->setRevoluteJointFlag(PxRevoluteJointFlag::eLIMIT_ENABLED, (_flags & HingeJointFlag::Limit) != 0); joint->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_ENABLED, (_flags & HingeJointFlag::Drive) != 0); } }
设置Flags:
如果flags等于value 则返回,如果不是则将value赋值给flags。初始化joint。
void HingeJoint::SetLimit(const LimitAngularRange& value) { if (_limit == value) return; _limit = value; if (_joint) { auto joint = static_cast<PxRevoluteJoint*>(_joint); PxJointAngularLimitPair limit(value.Lower * DegreesToRadians, value.Upper * DegreesToRadians, value.ContactDist); limit.stiffness = value.Spring.Stiffness; limit.damping = value.Spring.Damping; limit.restitution = value.Restitution; joint->setLimit(limit); } }
设置Limit:
如果limit等于value 则返回,如果不是则将value赋值给limit。初始化joint。
void HingeJoint::SetDrive(const HingeJointDrive& value) { if (_drive == value) return; _drive = value; if (_joint) { auto joint = static_cast<PxRevoluteJoint*>(_joint); joint->setDriveVelocity(Math::Max(value.Velocity, 0.0f)); joint->setDriveForceLimit(Math::Max(value.ForceLimit, 0.0f)); joint->setDriveGearRatio(Math::Max(value.GearRatio, 0.0f)); joint->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_FREESPIN, value.FreeSpin); } }
设置Drive:
如果drive等于value 则返回,如果不是则将value赋值给drive。初始化joint。
void HingeJoint::Serialize(SerializeStream& stream, const void* otherObj) { // Base Joint::Serialize(stream, otherObj); SERIALIZE_GET_OTHER_OBJ(HingeJoint); SERIALIZE_MEMBER(Flags, _flags); SERIALIZE_MEMBER(ContactDist, _limit.ContactDist); SERIALIZE_MEMBER(Restitution, _limit.Restitution); SERIALIZE_MEMBER(Stiffness, _limit.Spring.Stiffness); SERIALIZE_MEMBER(Damping, _limit.Spring.Damping); SERIALIZE_MEMBER(LowerLimit, _limit.Lower); SERIALIZE_MEMBER(UpperLimit, _limit.Upper); SERIALIZE_MEMBER(Velocity, _drive.Velocity); SERIALIZE_MEMBER(ForceLimit, _drive.ForceLimit); SERIALIZE_MEMBER(GearRatio, _drive.GearRatio); SERIALIZE_MEMBER(FreeSpin, _drive.FreeSpin); }
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/151226.html