Evening friends, hoping someone may be able to provide some clarification on this subject.
I've collected a fair amount of information to aid in the rendering of an overlay that draws a box or a line to various entities pulled from the object manager. So far I've managed to create a 2D radar that works great, but want to step up my game a little bit and draw the objects to screen. I've poured over dozens of posts on the subject of view matrices, world 2 screen functions, projection matrices, etc, and have been doing so for a week now. There's many different posted solutions for converting world coordinates to screen position, but they are all of them old, and I'm not certain they are still applicable.
The information I've collected so far:
camera_base = 0x2DE5928
camera_offset = 0x3930
IDA Reference: Screenshot - 70aa68064e9f9d6264ee5e12ed1b677b - Gyazo
Player XYZ coordinates.
Player rotation value.
Target / Entity XYZ coordinates.
Camera XYZ coordinates.
Screen Height / Width values.
I've identified several matrices in memory that respond to camera / position movement, looking straight up for 1.0, down for -1.0, viewing structures around located addresses and trying to make sense of the neighboring floats, etc. Plugging these matrices into my w2s function results in obviously inaccurate results though. Do I have to build the matrix myself? Every guide and video I've watched on the subject shows a 4x4 matrix of floats that look similar to what I'm seeing in cheatengine, but my rendered boxes are not appearing anywhere near where I would expect them to be. I feel like I'm missing something. (hindsight: I was missing something. The correct offset for starters. My matrix was also sized incorrectly.)
Relevant code portions below:
Code:
def get_game_window():
hwnd = win32gui.FindWindow(None,"World of Warcraft")
windowrect = win32gui.GetWindowRect(hwnd)
x = windowrect[0] - 5 #
y = windowrect[1]
width = windowrect[2] - x
height = windowrect[3] - y
return x, y, width, height
def view_matrix(reader):
global matrix_debug
matrix_address = reader.process.read_longlong(reader.base + view_matrix_pointer)
"""
reads 16 (16 * 4 bytes) floats from the view matrix pointer <-----WRONG
"""
try:
matrix = list()
offset = 0 # Used to manually adjust, perform some trial and error
for _ in range(16): <-----WRONG
value = reader.process.read_float(matrix_address + offset)
value = round(value, 2)
matrix.append(value)
offset += 4
matrix = np.array(matrix).reshape((4, 4), order='F') <-----WRONG
matrix_debug = matrix
return matrix
except Exception as e:
logger_function(reader)
logger_function(e)
def world_to_screen(v_matrix, pos):
try:
game_window = get_game_window()
clip_x = pos.x * v_matrix[0, 0] + pos.y * v_matrix[0, 1] + pos.z * v_matrix[0, 2] + v_matrix[0, 3]
clip_y = pos.x * v_matrix[1, 0] + pos.y * v_matrix[1, 1] + pos.z * v_matrix[1, 2] + v_matrix[1, 3]
clip_z = pos.x * v_matrix[2, 0] + pos.y * v_matrix[2, 1] + pos.z * v_matrix[2, 2] + v_matrix[2, 3]
clip_w = pos.x * v_matrix[3, 0] + pos.y * v_matrix[3, 1] + pos.z * v_matrix[3, 2] + v_matrix[3, 3]
# Calculate normalized device coordinates (NDC)
ndc_x = clip_x / clip_w
ndc_y = clip_y / clip_w
# Calculate screen coordinates
# screen_x = int(((ndc_x + 1) / 2) * game_window[2])
# screen_y = int(((-ndc_y + 1) / 2) * game_window[3]) #I've tried both of these screen_x / screen_y formulas.
screen_x = (game_window[2] / 2 * ndc_x) + (ndc_x + game_window[2] / 2); #2 width
screen_y = -(game_window[3] / 2 * ndc_y) + (ndc_y + game_window[3] / 2); #3 height
return screen_x, screen_y
except Exception as e:
logger_function(pos)
logger_function(v_matrix)
logger_function(e)
The loop I'm running parses the collected objects and pipes their object.pos (a vector3(x,y,z) object assigned to that attribute) through the world2screen function. The output is just way off, which leads me to believe that I'm either not looking at the correct matrix (I was right) or my math is fubar (also this). Drawing to those coordinates (if they're even on screen), has the boxes rendered in africa. They do move correlating to object movement, but the positioning and angles are all wacked.
1. Am I doing the math correctly here? (I wasn't)
2. Does wow have a view matrix or must it be created manually? (yes, it does. No, you don't.)
3. Assuming there is a view matrix at play here, could someone provide a snip of what the values look like I should be expecting? Floats obviously, but more the structure (doesn't even have to have the offsets in the image). I added what I believe to be the camera and viewmatrix below.
4. Some of the matrices I've been looking at have quite small values in them, others contain the camera coordinates. Didn't see much information in the offset dump posts recently beyond camera_base and camera_offset regarding a view matrix. (because that's all you need to find it). Just confused, would be grateful for some assistance.
Camera + ViewMatrix[?] : Screenshot - d59037d1393b50471e0865458148056d - Gyazo (this was wrong)
2D Radar: Screen capture - fb149338a9d3922010acb8e14e522fcd - Gyazo
Thanks in advance for taking the time to read my post.