-
-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
385 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
| ||
using System.Runtime.InteropServices; | ||
using System; | ||
|
||
namespace Brio.Core; | ||
internal static class NativeHelpers | ||
{ | ||
public static (nint Aligned, nint Unaligned) AllocateAlignedMemory(int sizeInBytes, int alignment) | ||
{ | ||
int alignedSize = sizeInBytes + alignment - 1; | ||
nint unalignedMemory = Marshal.AllocHGlobal(alignedSize); | ||
int alignmentOffset = (int)(alignment - (unalignedMemory % alignment)); | ||
nint alignedMemory = unalignedMemory + alignmentOffset; | ||
|
||
return (alignedMemory, unalignedMemory); | ||
} | ||
|
||
public static void FreeAlignedMemory((nint Aligned, nint Unaligned) addrs) | ||
{ | ||
Marshal.FreeHGlobal(addrs.Unaligned); | ||
} | ||
|
||
public static void FreeMemory(nint addr) | ||
{ | ||
Marshal.FreeHGlobal(addr); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
using Brio.Core; | ||
using Brio.Game.Posing.Skeletons; | ||
using Dalamud.Game; | ||
using FFXIVClientStructs.Havok; | ||
using System; | ||
using System.Numerics; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Brio.Game.Posing; | ||
internal unsafe class IKService : IDisposable | ||
{ | ||
delegate* unmanaged<hkaCCDSolver*, int, float, void> _ccdSolverCtr; | ||
delegate* unmanaged<hkaCCDSolver*, byte*, hkArray<IKConstraint>*, hkaPose*, byte*> _ccdSolverSolve; | ||
|
||
private (nint Aligned, nint Unaligned) _solverAddr; | ||
private (nint Aligned, nint Unaligned) _constraintAddr; | ||
|
||
public IKService(ISigScanner scanner) | ||
{ | ||
_ccdSolverCtr = (delegate* unmanaged<hkaCCDSolver*, int, float, void>)scanner.ScanText("E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 48 C7 43"); | ||
_ccdSolverSolve = (delegate* unmanaged<hkaCCDSolver*, byte*, hkArray<IKConstraint>*, hkaPose*, byte*>)scanner.ScanText("E8 ?? ?? ?? ?? 8B 45 ?? 48 8B 75"); | ||
|
||
_solverAddr = NativeHelpers.AllocateAlignedMemory(sizeof(hkaCCDSolver), 16); | ||
_constraintAddr = NativeHelpers.AllocateAlignedMemory(sizeof(IKConstraint), 16); | ||
} | ||
|
||
public void SolveIK(hkaPose* pose, ushort startBone, ushort endBone, Vector3 target, int iterations) | ||
{ | ||
hkaCCDSolver* ccdSolver = (hkaCCDSolver*)_solverAddr.Aligned; | ||
_ccdSolverCtr(ccdSolver, iterations, 1f); | ||
|
||
IKConstraint* constraint = (IKConstraint*)_constraintAddr.Aligned; | ||
constraint->StartBone = startBone; | ||
constraint->EndBone = endBone; | ||
constraint->Target.X = target.X; | ||
constraint->Target.Y = target.Y; | ||
constraint->Target.Z = target.Z; | ||
|
||
var constraints = new hkArray<IKConstraint> | ||
{ | ||
Length = 1, | ||
CapacityAndFlags = 1, | ||
Data = constraint | ||
}; | ||
|
||
byte notSure = 0; | ||
_ccdSolverSolve(ccdSolver, ¬Sure, &constraints, pose); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
NativeHelpers.FreeAlignedMemory(_solverAddr); | ||
NativeHelpers.FreeAlignedMemory(_constraintAddr); | ||
} | ||
|
||
[StructLayout(LayoutKind.Explicit, Size = 0x18)] | ||
private struct hkaCCDSolver | ||
{ | ||
[FieldOffset(0x0)] public nint vtbl; | ||
[FieldOffset(0x10)] public uint Iterations; | ||
[FieldOffset(0x14)] public float Gain; | ||
} | ||
|
||
[StructLayout(LayoutKind.Explicit, Size = 0x2)] | ||
private struct IKConstraint | ||
{ | ||
[FieldOffset(0x0)] public ushort StartBone; | ||
[FieldOffset(0x2)] public ushort EndBone; | ||
[FieldOffset(0x10)] public hkVector4f Target; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.