mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
fix WorldToScreen and ScreenToWorld (#1885)
* fix WorldToScreen and ScreenToWorld * Update FFXIVClientStructs
This commit is contained in:
parent
cf515cbc35
commit
86f85c95ac
3 changed files with 27 additions and 72 deletions
|
|
@ -9,6 +9,8 @@ using Dalamud.IoC.Internal;
|
||||||
using Dalamud.Logging.Internal;
|
using Dalamud.Logging.Internal;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
|
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game.Control;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.String;
|
using FFXIVClientStructs.FFXIV.Client.System.String;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
|
@ -20,6 +22,7 @@ using SharpDX;
|
||||||
|
|
||||||
using Vector2 = System.Numerics.Vector2;
|
using Vector2 = System.Numerics.Vector2;
|
||||||
using Vector3 = System.Numerics.Vector3;
|
using Vector3 = System.Numerics.Vector3;
|
||||||
|
using Vector4 = System.Numerics.Vector4;
|
||||||
|
|
||||||
namespace Dalamud.Game.Gui;
|
namespace Dalamud.Game.Gui;
|
||||||
|
|
||||||
|
|
@ -33,8 +36,6 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
|
|
||||||
private readonly GameGuiAddressResolver address;
|
private readonly GameGuiAddressResolver address;
|
||||||
|
|
||||||
private readonly GetMatrixSingletonDelegate getMatrixSingleton;
|
|
||||||
|
|
||||||
private readonly Hook<SetGlobalBgmDelegate> setGlobalBgmHook;
|
private readonly Hook<SetGlobalBgmDelegate> setGlobalBgmHook;
|
||||||
private readonly Hook<HandleItemHoverDelegate> handleItemHoverHook;
|
private readonly Hook<HandleItemHoverDelegate> handleItemHoverHook;
|
||||||
private readonly Hook<HandleItemOutDelegate> handleItemOutHook;
|
private readonly Hook<HandleItemOutDelegate> handleItemOutHook;
|
||||||
|
|
@ -70,8 +71,6 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
|
|
||||||
this.handleImmHook = Hook<HandleImmDelegate>.FromAddress(this.address.HandleImm, this.HandleImmDetour);
|
this.handleImmHook = Hook<HandleImmDelegate>.FromAddress(this.address.HandleImm, this.HandleImmDetour);
|
||||||
|
|
||||||
this.getMatrixSingleton = Marshal.GetDelegateForFunctionPointer<GetMatrixSingletonDelegate>(this.address.GetMatrixSingleton);
|
|
||||||
|
|
||||||
this.toggleUiHideHook = Hook<ToggleUiHideDelegate>.FromAddress(this.address.ToggleUiHide, this.ToggleUiHideDetour);
|
this.toggleUiHideHook = Hook<ToggleUiHideDelegate>.FromAddress(this.address.ToggleUiHide, this.ToggleUiHideDetour);
|
||||||
|
|
||||||
this.utf8StringFromSequenceHook = Hook<Utf8StringFromSequenceDelegate>.FromAddress(this.address.Utf8StringFromSequence, this.Utf8StringFromSequenceDetour);
|
this.utf8StringFromSequenceHook = Hook<Utf8StringFromSequenceDelegate>.FromAddress(this.address.Utf8StringFromSequence, this.Utf8StringFromSequenceDetour);
|
||||||
|
|
@ -86,11 +85,6 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
this.utf8StringFromSequenceHook.Enable();
|
this.utf8StringFromSequenceHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshaled delegates
|
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
||||||
private delegate IntPtr GetMatrixSingletonDelegate();
|
|
||||||
|
|
||||||
// Hooked delegates
|
// Hooked delegates
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||||
|
|
@ -178,23 +172,29 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos, out bool inView)
|
public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos, out bool inView)
|
||||||
{
|
{
|
||||||
// Get base object with matrices
|
|
||||||
var matrixSingleton = this.getMatrixSingleton();
|
|
||||||
|
|
||||||
// Read current ViewProjectionMatrix plus game window size
|
// Read current ViewProjectionMatrix plus game window size
|
||||||
var windowPos = ImGuiHelpers.MainViewport.Pos;
|
var windowPos = ImGuiHelpers.MainViewport.Pos;
|
||||||
var viewProjectionMatrix = *(Matrix4x4*)(matrixSingleton + 0x1b4);
|
var viewProjectionMatrix = Control.Instance()->ViewProjectionMatrix;
|
||||||
var device = Device.Instance();
|
var device = Device.Instance();
|
||||||
float width = device->Width;
|
float width = device->Width;
|
||||||
float height = device->Height;
|
float height = device->Height;
|
||||||
|
|
||||||
var pCoords = Vector3.Transform(worldPos, viewProjectionMatrix);
|
var pCoords = Vector4.Transform(new Vector4(worldPos, 1.0f), viewProjectionMatrix);
|
||||||
screenPos = new Vector2(pCoords.X / MathF.Abs(pCoords.Z), pCoords.Y / MathF.Abs(pCoords.Z));
|
var inFront = pCoords.W > 0.0f;
|
||||||
|
|
||||||
|
if (Math.Abs(pCoords.W) < float.Epsilon)
|
||||||
|
{
|
||||||
|
screenPos = Vector2.Zero;
|
||||||
|
inView = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCoords *= MathF.Abs(1.0f / pCoords.W);
|
||||||
|
screenPos = new Vector2(pCoords.X, pCoords.Y);
|
||||||
|
|
||||||
screenPos.X = (0.5f * width * (screenPos.X + 1f)) + windowPos.X;
|
screenPos.X = (0.5f * width * (screenPos.X + 1f)) + windowPos.X;
|
||||||
screenPos.Y = (0.5f * height * (1f - screenPos.Y)) + windowPos.Y;
|
screenPos.Y = (0.5f * height * (1f - screenPos.Y)) + windowPos.Y;
|
||||||
|
|
||||||
var inFront = pCoords.Z > 0;
|
|
||||||
inView = inFront &&
|
inView = inFront &&
|
||||||
screenPos.X > windowPos.X && screenPos.X < windowPos.X + width &&
|
screenPos.X > windowPos.X && screenPos.X < windowPos.X + width &&
|
||||||
screenPos.Y > windowPos.Y && screenPos.Y < windowPos.Y + height;
|
screenPos.Y > windowPos.Y && screenPos.Y < windowPos.Y + height;
|
||||||
|
|
@ -216,53 +216,17 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
|
||||||
worldPos = default;
|
worldPos = default;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get base object with matrices
|
var camera = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CameraManager.Instance()->CurrentCamera;
|
||||||
var matrixSingleton = this.getMatrixSingleton();
|
if (camera == null)
|
||||||
|
|
||||||
// Read current ViewProjectionMatrix plus game window size
|
|
||||||
var viewProjectionMatrix = default(Matrix);
|
|
||||||
var rawMatrix = (float*)(matrixSingleton + 0x1b4).ToPointer();
|
|
||||||
|
|
||||||
for (var i = 0; i < 16; i++, rawMatrix++)
|
|
||||||
viewProjectionMatrix[i] = *rawMatrix;
|
|
||||||
|
|
||||||
var width = *rawMatrix;
|
|
||||||
var height = *(rawMatrix + 1);
|
|
||||||
|
|
||||||
viewProjectionMatrix.Invert();
|
|
||||||
|
|
||||||
var localScreenPos = new SharpDX.Vector2(screenPos.X - windowPos.X, screenPos.Y - windowPos.Y);
|
|
||||||
var screenPos3D = new SharpDX.Vector3
|
|
||||||
{
|
{
|
||||||
X = (localScreenPos.X / width * 2.0f) - 1.0f,
|
worldPos = Vector3.Zero;
|
||||||
Y = -((localScreenPos.Y / height * 2.0f) - 1.0f),
|
return false;
|
||||||
Z = 0,
|
}
|
||||||
};
|
var ray = camera->ScreenPointToRay(screenPos);
|
||||||
|
var result = BGCollisionModule.RaycastMaterialFilter(ray.Origin, ray.Direction, out var hit);
|
||||||
SharpDX.Vector3.TransformCoordinate(ref screenPos3D, ref viewProjectionMatrix, out var camPos);
|
worldPos = hit.Point;
|
||||||
|
return result;
|
||||||
screenPos3D.Z = 1;
|
|
||||||
SharpDX.Vector3.TransformCoordinate(ref screenPos3D, ref viewProjectionMatrix, out var camPosOne);
|
|
||||||
|
|
||||||
var clipPos = camPosOne - camPos;
|
|
||||||
clipPos.Normalize();
|
|
||||||
|
|
||||||
// This array is larger than necessary because it contains more info than we currently use
|
|
||||||
var worldPosArray = default(RaycastHit);
|
|
||||||
|
|
||||||
// Theory: this is some kind of flag on what type of things the ray collides with
|
|
||||||
var unknown = stackalloc int[3]
|
|
||||||
{
|
|
||||||
0x4000,
|
|
||||||
0x4000,
|
|
||||||
0x0,
|
|
||||||
};
|
|
||||||
|
|
||||||
var isSuccess = BGCollisionModule.Raycast2(camPos.ToSystem(), clipPos.ToSystem(), rayDistance, &worldPosArray, unknown);
|
|
||||||
worldPos = worldPosArray.Point;
|
|
||||||
|
|
||||||
return isSuccess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,6 @@ internal sealed class GameGuiAddressResolver : BaseAddressResolver
|
||||||
/// Gets the address of the native HandleImm method.
|
/// Gets the address of the native HandleImm method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IntPtr HandleImm { get; private set; }
|
public IntPtr HandleImm { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the address of the native GetMatrixSingleton method.
|
|
||||||
/// </summary>
|
|
||||||
public IntPtr GetMatrixSingleton { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the native ToggleUiHide method.
|
/// Gets the address of the native ToggleUiHide method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -65,9 +59,6 @@ internal sealed class GameGuiAddressResolver : BaseAddressResolver
|
||||||
this.HandleActionOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 4D 85 C0 74 1F");
|
this.HandleActionOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 4D 85 C0 74 1F");
|
||||||
this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09");
|
this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09");
|
||||||
|
|
||||||
// Client::Graphics::JobSystem<Apricot::Engine::Core>.GetSingleton()
|
|
||||||
this.GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
|
|
||||||
|
|
||||||
this.ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 44 0F B6 81");
|
this.ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 44 0F B6 81");
|
||||||
this.Utf8StringFromSequence = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8D 41 22 66 C7 41 ?? ?? ?? 48 89 01 49 8B D8");
|
this.Utf8StringFromSequence = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8D 41 22 66 C7 41 ?? ?? ?? 48 89 01 49 8B D8");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit d39475f81899cb35e874cbde7a50028667eb95c9
|
Subproject commit dd4bbedad018777d590af8c7d285504d0ee02eee
|
||||||
Loading…
Add table
Add a link
Reference in a new issue