vendredi 23 août 2019

Why does the box I am using for hit test in opengl follow the cursor?

I am trying to implement a hit test in my Minecraft clone, and the box used to highlight a block the reticle is hitting is following the reticle instead of surrounding the block. How do I fix this problem so the box surrounds the block instead of following my cursor?

I have already tried adjusting some parameter values, but that just seems to increase/decrease the size of the box. I don't want to change the algorithm for the hit test because it is not my original code and I don't know how the math works for it.

Here are the methods I am using for the hit test

def cube_vertices(vertex, n):
    """
    Return the vertices of the cube at position x, y, z with size 2*n.
    """
    x, y, z = vertex
    return [
        x-n,y+n,z-n, x-n,y+n,z+n, x+n,y+n,z+n, x+n,y+n,z-n,  # top
        x-n,y-n,z-n, x+n,y-n,z-n, x+n,y-n,z+n, x-n,y-n,z+n,  # bottom
        x-n,y-n,z-n, x-n,y-n,z+n, x-n,y+n,z+n, x-n,y+n,z-n,  # left
        x+n,y-n,z+n, x+n,y-n,z-n, x+n,y+n,z-n, x+n,y+n,z+n,  # right
        x-n,y-n,z+n, x+n,y-n,z+n, x+n,y+n,z+n, x-n,y+n,z+n,  # front
        x+n,y-n,z-n, x-n,y-n,z-n, x-n,y+n,z-n, x+n,y+n,z-n,  # back
    ]    


def highlight_block(self, world):
    """
    Highlights the block at the current vertex
    :param vertex: The x, y, and z coordinates of the block
    :return: None
    """
    vector = world.player.get_sight_vector()
    hit_test = world.player.hit_test(self, world.player.pos, vector, max_distance=8)
    block = hit_test[0]
    if block:
        print("Block:", block)
        x, y, z = block
        vertex_data = cube_vertices((x, y, z-1), 0.51)
        glColor3d(0, 0, 0)
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
        pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data))
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)


def hit_test(self, model, position, vector, max_distance=8):
    """
    Highlights a block when the crosshair/reticle is pointing at it
    :param model: The instance variable that holds all of the data about the world
    :param position: The (x, y, z) position to check visibility from.
    :param vector: tuple of len 3. The line of sight vector.
    :param max_distance: The max distance to check to
    :return: None
    """
    m = 8
    x, y, z = position
    dx, dy, dz = vector
    previous = None
    for _ in range(max_distance * m):
        key = floor((x, y, z))
        # if key != previous and key in model.shown and model.world[key] not in (None, textures.AIR):
        if key != previous and key in model.world:
            return key, previous
        previous = key
        x, y, z = x + dx / m, y + dy / m, z + dz / m
    return None, None


def get_sight_vector(self):
    """
    Returns the current line of sight vector indicating the direction the player is looking.
    """
    x, y = self.rot
    # y ranges from -90 to 90, or -pi/2 to pi/2, so m ranges from 0 to 1 and
    # is 1 when looking ahead parallel to the ground and 0 when looking
    # straight up or down.
    m = math.cos(math.radians(y))
    # dy ranges from -1 to 1 and is -1 when looking straight down and 1 when
    # looking straight up.
    dy = math.sin(math.radians(y))
    dx = math.cos(math.radians(x - 90)) * m
    dz = math.sin(math.radians(x - 90)) * m
    return (dx, dy, dz)

A link to the code: https://github.com/BenMaydan/MineGlet/blob/master/render.py

I didn't get any error messages, the only thing that happened was what I said earlier

Aucun commentaire:

Enregistrer un commentaire