Code:
public static class Camera
{
public static ProcessSharp ProcessSharp { get; private set; }
public static int CameraOffset { get; } = 0x3330;
internal static IntPtr BaseAddress
{
get
{
var ptr = ProcessSharp.Memory.Read<IntPtr>(Offsets.CameraBase);
return ProcessSharp.Memory.Read<IntPtr>(ptr + CameraOffset);
}
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct CGCamera
{
private readonly IntPtr vTable; // 0x0
private readonly int unk0; // 0x4
public Vector3 Position; // 0x8
private fixed float Facing[9]; // 0x14 (3x3 Matrix)
public readonly float NearClip; // 0x38
public readonly float FarClip; // 0x3C
public readonly float FieldOfView; // 0x40
public readonly float Aspect; // 0x44
}
private static CGCamera cam => ProcessSharp.Memory.Read<CGCamera>(BaseAddress);
public static float X => cam.Position.X;
public static float Y => cam.Position.Y;
public static float Z => cam.Position.Z;
public static float FOV => cam.FieldOfView;
public static float NearClip => cam.NearClip;
public static float FarClip => cam.FarClip;
public static float Aspect => cam.Aspect;
private static Matrix Matrix
{
get
{
var bCamera = ProcessSharp.Memory.Read(BaseAddress + 0x1C, 36); // was 0x14 not 0x1C in 1.12.1
var m = new Matrix();
m[0, 0] = BitConverter.ToSingle(bCamera, 0);
m[0, 1] = BitConverter.ToSingle(bCamera, 4);
m[0, 2] = BitConverter.ToSingle(bCamera, 8);
m[1, 0] = BitConverter.ToSingle(bCamera, 12);
m[1, 1] = BitConverter.ToSingle(bCamera, 16);
m[1, 2] = BitConverter.ToSingle(bCamera, 20);
m[2, 0] = BitConverter.ToSingle(bCamera, 24);
m[2, 1] = BitConverter.ToSingle(bCamera, 28);
m[2, 2] = BitConverter.ToSingle(bCamera, 32);
return m;
}
}
public static Vector2 WorldToScreen(float x, float y, float z)
{
var Projection = Matrix.PerspectiveFovRH(FOV * 0.5f, Aspect, NearClip, FarClip);
var eye = new Vector3(X, Y, Z);
var lookAt = new Vector3(X + Matrix[0, 0], Y + Matrix[0, 1], Z + Matrix[0, 2]);
var up = new Vector3(0f, 0f, 1f);
var View = Matrix.LookAtRH(eye, lookAt, up);
var World = Matrix.Identity;
var WorldPosition = new Vector3(x, y, z);
var ScreenPosition = Vector3.Project(WorldPosition, 0f, 0f, WindowHelper.WindowWidth, WindowHelper.WindowHeight, NearClip, FarClip, World * View * Projection);
return new Vector2(ScreenPosition.X, ScreenPosition.Y - 20f);
}
public static void Initialize(ProcessSharp processSharp)
{
ProcessSharp = processSharp;
WindowHelper.Initialize(processSharp);
Log.Write("Camera Ready", Color.Green);
Log.Write($"Camera Base 0x{BaseAddress.ToString("X")}");
Log.Write($"FOV = {FOV}");
Log.Write($"Aspect = {Aspect}");
Log.Write($"NearClip = {NearClip}");
Log.Write($"FarClip = {FarClip}");
Log.Write($"Camera X = {X}");
Log.Write($"Camera Y = {Y}");
Log.Write($"Camera Z = {Z}");
Log.Write($"Matrix[0, 0] = {Matrix[0, 0]}");
Log.Write($"Matrix[0, 1] = {Matrix[0, 1]}");
Log.Write($"Matrix[0, 2] = {Matrix[0, 2]}");
Log.Write($"WindowWidth = {WindowHelper.WindowWidth}");
Log.Write($"WindowHeight = {WindowHelper.WindowHeight}");
}
}