From b3f80f777138df259718d62011e897326e0fb8f3 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Fri, 8 May 2026 23:40:31 -0400 Subject: [PATCH 1/4] Add missing physics classes There was a bunch of (potentially useful) physics classes that haven't been created yet, which contain data about collisions and constraints. I didn't map out their fields and vfuncs yet, but the inheritance structure as detailed in classinformer is now set up. Collision objects are kept in BonePhysicsModule, and constraint objects are kept in BoneSimulator. --- .../Graphics/Physics/BonePhysicsModule.cs | 10 +++ .../Client/Graphics/Physics/BoneSimulator.cs | 1 + .../Client/Graphics/Physics/CollisionBase.cs | 27 ++++++++ .../Graphics/Physics/CollisionCapsule.cs | 12 ++++ .../Graphics/Physics/CollisionEllipsoid.cs | 12 ++++ .../Graphics/Physics/CollisionNormalPlane.cs | 13 ++++ .../Client/Graphics/Physics/CollisionPlane.cs | 12 ++++ .../Graphics/Physics/CollisionSphere.cs | 12 ++++ .../Physics/CollisionThreePointPlane.cs | 13 ++++ .../Graphics/Physics/ConstraintAttract.cs | 11 ++++ .../Client/Graphics/Physics/ConstraintBase.cs | 21 ++++++ .../Client/Graphics/Physics/ConstraintPin.cs | 11 ++++ .../Graphics/Physics/ConstraintSpring.cs | 11 ++++ ida/data.yml | 65 +++++++++++++++++++ 14 files changed, 231 insertions(+) create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionBase.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionCapsule.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionEllipsoid.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionNormalPlane.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionPlane.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionSphere.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionThreePointPlane.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintAttract.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintBase.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintPin.cs create mode 100644 FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintSpring.cs diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs index 31efb97ec..aab45dcb1 100644 --- a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs @@ -13,6 +13,15 @@ public struct BoneSimulators { [FieldOffset(0x60)] public StdVector> BoneSimulator_5; } +[StructLayout(LayoutKind.Explicit, Size = 0x78)] +public struct BoneCollisions { + [FieldOffset(0x00)] public StdVector> BoneCollision_1; + [FieldOffset(0x18)] public StdVector> BoneCollision_2; + [FieldOffset(0x30)] public StdVector> BoneCollision_3; + [FieldOffset(0x48)] public StdVector> BoneCollision_4; + [FieldOffset(0x60)] public StdVector> BoneCollision_5; +} + // Client::Graphics::Physics::BonePhysicsModule [StructLayout(LayoutKind.Explicit, Size = 0x590)] [GenerateInterop] @@ -23,6 +32,7 @@ public unsafe partial struct BonePhysicsModule { [FieldOffset(0x94)] public float WindVariation; [FieldOffset(0x98)] public Skeleton* Skeleton; [FieldOffset(0xA0)] public BoneSimulators BoneSimulators; + [FieldOffset(0x118)] public BoneCollisions BoneCollisions; [FieldOffset(0x190), FixedSizeArray] internal FixedSizeArray5> _bonePhysicsResourceHandles; [FieldOffset(0x1B8)] public float FrameDeltaTime; [FieldOffset(0x578)] public float OverrideSimulationTime; diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BoneSimulator.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BoneSimulator.cs index e05570452..49fdb463d 100644 --- a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BoneSimulator.cs +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BoneSimulator.cs @@ -16,6 +16,7 @@ public unsafe partial struct BoneSimulator { // They are hardcoded to roughly 1/60 (0.016666668) and 60 (59.999996) in cases where the sheet isn't used. [FieldOffset(0x50)] public float SimulationTime; [FieldOffset(0x54)] public float SimulationTimeInv; // 1/SimulationTime + [FieldOffset(0x90)] public StdVector Constraints; [FieldOffset(0xF6)] public bool IsStarted; // Flag that is set to true when the simulator starts, and is quickly reset [FieldOffset(0xF7)] public bool IsStopped; // Same as Start, but when the simulator is requested to stop [FieldOffset(0xF8)] public bool IsReset; // When set to true, resets the bone simulator diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionBase.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionBase.cs new file mode 100644 index 000000000..07b02cfb2 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionBase.cs @@ -0,0 +1,27 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::CollisionBase +// Client::Graphics::ReferencedClassBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x90)] +[GenerateInterop(isInherited: true)] +public unsafe partial struct CollisionBase { + /// Set in constructor. + [FieldOffset(0x80)] public CollisionShape Shape; + + public enum CollisionShape : byte { + /// Corresponds to CollisionCapsule. + Capsule = 0, + /// Corresponds to CollisionEllipsoid. + Ellipsoid = 1, + /// Corresponds to CollisionNormalPlane. + NormalPlane = 2, + /// Corresponds to CollisionThreePointPlane. + ThreePointPlane = 3, + /// Corresponds to CollisionSphere. + Sphere = 4, + } + + [MemberFunction("C7 41 ?? ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 01 48 8B C1")] + public partial CollisionBase* Ctor(CollisionShape shape); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionCapsule.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionCapsule.cs new file mode 100644 index 000000000..8f58abd3a --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionCapsule.cs @@ -0,0 +1,12 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::CollisionCapsule +// Client::Graphics::Physics::CollisionBase +// Client::Graphics::ReferencedClassBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x120)] +[GenerateInterop] +public unsafe partial struct CollisionCapsule { + [MemberFunction("E8 ?? ?? ?? ?? 48 8B D8 48 89 5C 24")] + public partial CollisionCapsule* Ctor(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionEllipsoid.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionEllipsoid.cs new file mode 100644 index 000000000..d9e544696 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionEllipsoid.cs @@ -0,0 +1,12 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::CollisionEllipsoid +// Client::Graphics::Physics::CollisionBase +// Client::Graphics::ReferencedClassBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x160)] +[GenerateInterop] +public unsafe partial struct CollisionEllipsoid { + [MemberFunction("40 53 48 83 EC ?? B2 ?? 48 8B D9 E8 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 03 B8 ?? ?? ?? ?? 0F 28 05")] + public partial CollisionEllipsoid* Ctor(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionNormalPlane.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionNormalPlane.cs new file mode 100644 index 000000000..3502d60ed --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionNormalPlane.cs @@ -0,0 +1,13 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::CollisionThreePointPlane +// Client::Graphics::Physics::CollisionPlane +// Client::Graphics::Physics::CollisionBase +// Client::Graphics::ReferencedClassBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x110)] +[GenerateInterop] +public unsafe partial struct CollisionNormalPlane { + [MemberFunction("40 53 48 83 EC ?? B2 ?? 48 8B D9 E8 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 03 B8 ?? ?? ?? ?? 66 89 83")] + public partial CollisionNormalPlane* Ctor(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionPlane.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionPlane.cs new file mode 100644 index 000000000..54864f650 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionPlane.cs @@ -0,0 +1,12 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::CollisionPlane +// Client::Graphics::Physics::CollisionBase +// Client::Graphics::ReferencedClassBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0xE0)] +[GenerateInterop(isInherited: true)] +public unsafe partial struct CollisionPlane { + [MemberFunction("E8 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 03 B8 ?? ?? ?? ?? 66 89 83 ?? ?? ?? ?? 33 C0")] + public partial CollisionPlane* Ctor(CollisionBase.CollisionShape shape); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionSphere.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionSphere.cs new file mode 100644 index 000000000..74b0ae955 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionSphere.cs @@ -0,0 +1,12 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::CollisionSphere +// Client::Graphics::Physics::CollisionBase +// Client::Graphics::ReferencedClassBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0xD0)] +[GenerateInterop] +public unsafe partial struct CollisionSphere { + [MemberFunction("40 53 48 83 EC ?? B2 ?? 48 8B D9 E8 ?? ?? ?? ?? 33 C9")] + public partial CollisionSphere* Ctor(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionThreePointPlane.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionThreePointPlane.cs new file mode 100644 index 000000000..133e69842 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/CollisionThreePointPlane.cs @@ -0,0 +1,13 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::CollisionThreePointPlane +// Client::Graphics::Physics::CollisionPlane +// Client::Graphics::Physics::CollisionBase +// Client::Graphics::ReferencedClassBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x120)] +[GenerateInterop] +public unsafe partial struct CollisionThreePointPlane { + [MemberFunction("40 53 48 83 EC ?? B2 ?? 48 8B D9 E8 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? BA")] + public partial CollisionThreePointPlane* Ctor(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintAttract.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintAttract.cs new file mode 100644 index 000000000..e067bbcee --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintAttract.cs @@ -0,0 +1,11 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::ConstraintAttract +// Client::Graphics::Physics::ConstraintBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x60)] +[GenerateInterop] +public unsafe partial struct ConstraintAttract { + [MemberFunction("E8 ?? ?? ?? ?? 48 8B F0 EB ?? 33 F6 F3 0F 10 44 24")] + public partial ConstraintAttract* Ctor(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintBase.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintBase.cs new file mode 100644 index 000000000..c891d3ed8 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintBase.cs @@ -0,0 +1,21 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::ConstraintBase +[StructLayout(LayoutKind.Explicit, Size = 0x18)] +[GenerateInterop(isInherited: true)] +public unsafe partial struct ConstraintBase { + /// Set in constructor. + [FieldOffset(0x10)] public ConstraintType Shape; + + public enum ConstraintType : uint { + /// Corresponds to ConstraintSpring. + Spring = 0, + /// Corresponds to ConstraintAttract. + Attract = 1, + /// Corresponds to ConstraintPin. + Pin = 2, + } + + [MemberFunction("48 C7 41 ?? ?? ?? ?? ?? 48 89 01 48 8B C1 89 51 ?? C3")] // don't use the lea instruction sig + public partial ConstraintBase* Ctor(ConstraintType type); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintPin.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintPin.cs new file mode 100644 index 000000000..b67444d80 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintPin.cs @@ -0,0 +1,11 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::ConstraintPin +// Client::Graphics::Physics::ConstraintBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x50)] +[GenerateInterop] +public unsafe partial struct ConstraintPin { + [MemberFunction("E8 ?? ?? ?? ?? 48 8B F0 48 8B 57")] + public partial ConstraintPin* Ctor(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintSpring.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintSpring.cs new file mode 100644 index 000000000..f83a0eee5 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/ConstraintSpring.cs @@ -0,0 +1,11 @@ +namespace FFXIVClientStructs.FFXIV.Client.Graphics.Physics; + +// Client::Graphics::Physics::ConstraintSpring +// Client::Graphics::Physics::ConstraintBase +[Inherits] +[StructLayout(LayoutKind.Explicit, Size = 0x38)] +[GenerateInterop] +public unsafe partial struct ConstraintSpring { + [MemberFunction("E8 ?? ?? ?? ?? 48 8B F0 EB ?? 33 F6 F3 0F 10 84 24")] + public partial ConstraintSpring* Ctor(); +} diff --git a/ida/data.yml b/ida/data.yml index 432c5fa69..4176d623c 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -25741,6 +25741,71 @@ classes: Common::Component::BGCollision::Math::AABB: funcs: 0x14206C9A0: ctorTransformed + Client::Graphics::Physics::CollisionBase: + vtbls: + - ea: 0x142451CA0 + base: Client::Graphics::ReferencedClassBase + funcs: + 0x141C832D0: Ctor + Client::Graphics::Physics::CollisionEllipsoid: + vtbls: + - ea: 0x142429B40 + base: Client::Graphics::Physics::CollisionBase + funcs: + 0x141BD7530: Ctor + Client::Graphics::Physics::CollisionPlane: + vtbls: + - ea: 0x142429B90 + base: Client::Graphics::Physics::CollisionBase + funcs: + 0x141BD8A90: Ctor + Client::Graphics::Physics::CollisionNormalPlane: + vtbls: + - ea: 0x142429BE0 + base: Client::Graphics::Physics::CollisionPlane + funcs: + 0x141BD9450: Ctor + Client::Graphics::Physics::CollisionSphere: + vtbls: + - ea: 0x142429938 + base: Client::Graphics::Physics::CollisionBase + funcs: + 0x141BD2950: Ctor + Client::Graphics::Physics::CollisionThreePointPlane: + vtbls: + - ea: 0x142429C30 + base: Client::Graphics::Physics::CollisionPlane + funcs: + 0x141BD99D0: Ctor + Client::Graphics::Physics::CollisionCapsule: + vtbls: + - ea: 0x142429988 + base: Client::Graphics::Physics::CollisionBase + funcs: + 0x141BD4720: Ctor + Client::Graphics::Physics::ConstraintBase: + vtbls: + - ea: 0x14242FEE0 + funcs: + 0x141C89310: Ctor + Client::Graphics::Physics::ConstraintAttract: + vtbls: + - ea: 0x14242FF08 + base: Client::Graphics::Physics::ConstraintBase + funcs: + 0x141C29600: Ctor + Client::Graphics::Physics::ConstraintPin: + vtbls: + - ea: 0x142430090 + base: Client::Graphics::Physics::ConstraintBase + funcs: + 0x141C29A60: Ctor + Client::Graphics::Physics::ConstraintSpring: + vtbls: + - ea: 0x1424300B8 + base: Client::Graphics::Physics::ConstraintBase + funcs: + 0x141C29C50: Ctor # havok hkArrayUtil: funcs: From 63db70e59c9a4465b87611a632c860ac6ee8b3c4 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Fri, 8 May 2026 23:42:03 -0400 Subject: [PATCH 2/4] Expand on jobs for BonePhysicsUpdater More documentation is added for the existing job data, and then I mapped out the one used for updating collision objects now that we have those. There's also a function used to allocate and create the job data in BonePhysicsModule which is useful to know about. --- .../Client/Graphics/Physics/BonePhysicsModule.cs | 4 ++++ .../Client/Graphics/Physics/BonePhysicsUpdater.cs | 14 +++++++++++++- ida/data.yml | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs index aab45dcb1..0c24ecfab 100644 --- a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs @@ -46,4 +46,8 @@ public unsafe partial struct BonePhysicsModule { /// Limits the returned value to 60 FPS, used to set BoneSimulator.SimulationTime. [MemberFunction("E8 ?? ?? ?? ?? F3 0F 5E F0 F3 0F 11 43")] public partial float GetSimulationTime(); + + /// Creates job data based on the lists in BoneSimulators and BoneCollisions. + [MemberFunction("E8 ?? ?? ?? ?? 48 8D 7F ?? 48 83 EB ?? 75 ?? 48 8B 45")] + public partial void CreateJobData(BonePhysicsUpdater* updater); } diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsUpdater.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsUpdater.cs index 04e413fa2..5eed0a5bb 100644 --- a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsUpdater.cs +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsUpdater.cs @@ -8,14 +8,26 @@ public unsafe partial struct BonePhysicsUpdater { [FieldOffset(0xE0)] public JobSystem BoneSimulatorJob; [FieldOffset(0x1A0)] public JobSystem TransformUpdaterJob; - /// This is executed by BoneSimulatorUpdateJob. + /// This is executed by BoneSimulatorJob. [MemberFunction("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC ?? ?? ?? ?? 33 ED 4C 8B F2")] // don't use the lea instruction sig public partial void BoneSimulatorTask(UpdateBoneSimulatorJobData* data); + /// This is executed by CollisionObjectJob. + [MemberFunction("48 89 5C 24 ?? 57 48 83 EC ?? 48 8B 3A 48 8B 5F")] + public partial void CollisionObjectTask(CollisionObjectJobData* data); + + /// Structure passed to BoneSimulatorTask. [GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 0x10)] public partial struct UpdateBoneSimulatorJobData { [FieldOffset(0x0)] public BoneSimulator* BoneSimulator; [FieldOffset(0x8)] public BonePhysicsModule* BonePhysicsModule; } + + /// Structure passed to CollisionObjectTask. + [GenerateInterop] + [StructLayout(LayoutKind.Explicit, Size = 0x8)] + public partial struct CollisionObjectJobData { + [FieldOffset(0x0)] public CollisionBase* CollisionObject; + } } diff --git a/ida/data.yml b/ida/data.yml index 4176d623c..69d0bddd4 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -24953,6 +24953,7 @@ classes: 0x1417ECF30: ctor 0x1417ED0C0: Initialize 0x1417EDB20: Update + 0x1417EE080: CollisionObjectTask 0x1417EE0E0: BoneSimulatorTask Client::Graphics::Physics::BonePhysicsModule: vtbls: @@ -24963,6 +24964,7 @@ classes: 0x1418B0CA0: ctor 0x1418B0E00: Finalizer 0x1418B0EE0: Initialize + 0x1418B14D0: CreateJobData 0x1418B44F0: GetSimulationTime 0x1418B4590: GetSimulationTimeInv Client::Graphics::Physics::BoneKineDriverModule: From 91cee35309a2f712cbe06bf41709a43cae023bc4 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Fri, 8 May 2026 23:43:37 -0400 Subject: [PATCH 3/4] BonePhysicsModule: Add Load function This is used to load the PHYB resource file and was helpful in figuring out how collision data was structured. --- .../FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs | 4 ++++ ida/data.yml | 1 + 2 files changed, 5 insertions(+) diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs index 0c24ecfab..f42511c56 100644 --- a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BonePhysicsModule.cs @@ -50,4 +50,8 @@ public unsafe partial struct BonePhysicsModule { /// Creates job data based on the lists in BoneSimulators and BoneCollisions. [MemberFunction("E8 ?? ?? ?? ?? 48 8D 7F ?? 48 83 EB ?? 75 ?? 48 8B 45")] public partial void CreateJobData(BonePhysicsUpdater* updater); + + /// Loads data into the vector in BoneSimulators and BoneCollisions corresponding to resourceIndex. This resource handle is then stored in BonePhysicsResourceHandles. + [MemberFunction("E8 ?? ?? ?? ?? 48 8B 03 48 8B CB FF C6")] + public partial void Load(ResourceHandle* handle, uint resourceIndex); } diff --git a/ida/data.yml b/ida/data.yml index 69d0bddd4..480cbded5 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -24965,6 +24965,7 @@ classes: 0x1418B0E00: Finalizer 0x1418B0EE0: Initialize 0x1418B14D0: CreateJobData + 0x1418B1600: Load 0x1418B44F0: GetSimulationTime 0x1418B4590: GetSimulationTimeInv Client::Graphics::Physics::BoneKineDriverModule: From c35dbbb248a0c549ca167413d2648456d00c5738 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Fri, 8 May 2026 23:44:50 -0400 Subject: [PATCH 4/4] BoneSimulator: Smaller field and member function additions The fields were found in the Load function and correspond to how VFXEditor claims they are used (hence why the naming is taken from there.) The functions are for making the disassembly automatically more readable. --- .../Client/Graphics/Physics/BoneSimulator.cs | 22 +++++++++++++++++++ ida/data.yml | 7 +++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BoneSimulator.cs b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BoneSimulator.cs index 49fdb463d..7296c1c18 100644 --- a/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BoneSimulator.cs +++ b/FFXIVClientStructs/FFXIV/Client/Graphics/Physics/BoneSimulator.cs @@ -17,6 +17,8 @@ public unsafe partial struct BoneSimulator { [FieldOffset(0x50)] public float SimulationTime; [FieldOffset(0x54)] public float SimulationTimeInv; // 1/SimulationTime [FieldOffset(0x90)] public StdVector Constraints; + [FieldOffset(0x6C)] public ushort ConstraintLoop; + [FieldOffset(0x6E)] public ushort CollisionLoop; [FieldOffset(0xF6)] public bool IsStarted; // Flag that is set to true when the simulator starts, and is quickly reset [FieldOffset(0xF7)] public bool IsStopped; // Same as Start, but when the simulator is requested to stop [FieldOffset(0xF8)] public bool IsReset; // When set to true, resets the bone simulator @@ -24,6 +26,9 @@ public unsafe partial struct BoneSimulator { [FieldOffset(0x444)] public bool IsSimulating; [FieldOffset(0x445)] public bool IsTimeIntegrating; // Whether the simulator is integrating (time stepping) on this frame [FieldOffset(0x446)] public bool IsCollidable; + [FieldOffset(0x447)] public bool ContinuousCollisions; + [FieldOffset(0x448)] public bool UsingGroundPlane; + [FieldOffset(0x449)] public bool FixedLength; /// Non-exhaustive list of physics groups public enum PhysicsGroup : uint { @@ -37,6 +42,19 @@ public enum PhysicsGroup : uint { Ears = 18, } + [MemberFunction("E8 ?? ?? ?? ?? 48 8B 74 24 ?? 4C 8B E8")] + public partial BoneSimulator* Ctor(); + + [MemberFunction("48 89 5C 24 ?? 57 48 83 EC ?? 48 8D 05 ?? ?? ?? ?? 48 8B D9 48 89 01 48 81 C1 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B 93")] + public partial void Finalizer(); + + [VirtualFunction(0)] + public partial void Dtor(byte freeFlags); + + /// Resets a lot of stuff and clears the Skeleton field? + [VirtualFunction(1)] + public partial void ClearSkeleton(); + /// Called when IsTimeIntegrating is true. [MemberFunction("40 55 53 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 44 0F 29 94 24")] public partial void Update(BonePhysicsModule* bonePhysicsModule); @@ -48,4 +66,8 @@ public enum PhysicsGroup : uint { /// Reset this bone simulator. [MemberFunction("E8 ?? ?? ?? ?? 48 8B 77 ?? 48 8D 8E")] public partial void Reset(); + + /// Sets the skeleton for this bone simulator, also calls Reset. + [MemberFunction("E8 ?? ?? ?? ?? 41 0F B6 44 24 ?? 41 89 45")] + public partial void SetSkeleton(Skeleton* skeleton); } diff --git a/ida/data.yml b/ida/data.yml index 480cbded5..dfdf794a6 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -24983,8 +24983,13 @@ classes: Client::Graphics::Physics::BoneSimulator: vtbls: - ea: 0x14230F390 + vfuncs: + 0: Dtor + 1: ClearSkeleton funcs: - 0x1419315B0: ctor + 0x1419315B0: Ctor + 0x1419318A0: Finalizer + 0x141931AA0: SetSkeleton 0x141931D40: Reset 0x141931F10: Update 0x1419335E0: UpdateWithoutIntegration