World2Screen - WoTLK Classic menu

User Tag List

Results 1 to 2 of 2
  1. #1
    wardrive's Avatar Active Member
    Reputation
    20
    Join Date
    Jul 2023
    Posts
    43
    Thanks G/R
    23/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    World2Screen - WoTLK Classic

    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.
    Last edited by wardrive; 08-19-2023 at 08:51 PM.

    World2Screen - WoTLK Classic
  2. #2
    wardrive's Avatar Active Member
    Reputation
    20
    Join Date
    Jul 2023
    Posts
    43
    Thanks G/R
    23/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Disregard, figured it out. I was missing a few steps. Ended up converting ChrisIsMe's solution to python by hand and walking the solution for each required piece of data.

    camera_base = 0x2DE5928
    camera_offset = 0x3930

    Base and offset values I provided are valid and work for the current patch as of this writing (3.4.2.50664)

    For anyone else playing with external python hacking for world of warcraft, if you run across this thread, here's a plug and play w2s function you'll need:

    Code:
    def world_to_screen(v_matrix, pos):
        """
        world 2 screen returns a 2d vector
        """
        try:
            game_window = get_game_window()
            
            diff = pygame.math.Vector3(pos.x - camera.pos_v3.x, pos.y - camera.pos_v3.y, pos.z - camera.pos_v3.z)
            
            v_matrix = np.linalg.inv(v_matrix)
     
            view = pygame.math.Vector3(
                v_matrix[0, 0] * diff.x + v_matrix[0, 1] * diff.y + v_matrix[0, 2] * diff.z,
                v_matrix[1, 0] * diff.x + v_matrix[1, 1] * diff.y + v_matrix[1, 2] * diff.z,
                v_matrix[2, 0] * diff.x + v_matrix[2, 1] * diff.y + v_matrix[2, 2] * diff.z
            )
            
            camera_vector = pygame.math.Vector3(-view.y, -view.z, view.x)
            
            game_screen = pygame.math.Vector2((game_window[2] / 2), (game_window[3] / 2))
    
            aspect = pygame.math.Vector2( 
                game_screen.x / math.tan(((camera.fov * 55) / 2) * math.radians(1.0)), 
                game_screen.y / math.tan(((camera.fov * 35) / 2) * math.radians(1.0))
            )
            
            screen_position = pygame.math.Vector2(
                game_screen.x + camera_vector.x * aspect.x / camera_vector.z,
                game_screen.y + camera_vector.y * aspect.y / camera_vector.z
            )
    
            return screen_position.x, screen_position.y
        except Exception as e:
            logger_function(pos)
            logger_function(v_matrix)
            logger_function(e)
    I'll leave building the view_matrix function to the reader (hint: the one I posted above was flawed), but everything you need to get started is here in this post and other posts on the forum.

    Apologies for asking for help sooner than was required.
    Last edited by wardrive; 08-21-2023 at 05:32 AM.

Similar Threads

  1. [Buying] Buying WOW WotLK Classic Gold All US + Eu Servers 24/7 Online
    By legalperson1 in forum WoW Classic Buy Sell Trade
    Replies: 23
    Last Post: 10-09-2023, 07:27 PM
  2. [Buying] Tired of playing? Let me buy your WoW SoD & ERA accounts! Instant payment!
    By MMOprovider in forum WoW Classic Buy Sell Trade
    Replies: 24
    Last Post: 12-16-2021, 10:41 AM
  3. Replies: 10
    Last Post: 09-06-2021, 04:10 PM
  4. [Selling] Cheap WoW WoTLK/Classic ERA Gold | Daily price update| ALL Servers | Instant Delivery
    By MMOprovider in forum WoW Classic Buy Sell Trade
    Replies: 1
    Last Post: 10-31-2020, 04:28 AM
  5. Replies: 1
    Last Post: 02-25-2020, 05:28 AM
All times are GMT -5. The time now is 11:48 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search