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