|
import math |
|
|
|
HIT_RANGE = 3 |
|
|
|
class Hit_ray: |
|
def __init__(self, world, rotation, starting_position): |
|
self.world = world |
|
|
|
|
|
|
|
|
|
self.vector = ( |
|
math.cos(rotation[0]) * math.cos(rotation[1]), |
|
math.sin(rotation[1]), |
|
math.sin(rotation[0]) * math.cos(rotation[1])) |
|
|
|
|
|
self.position = list(starting_position) |
|
|
|
|
|
self.block = tuple(map(lambda x: int(round(x)), self.position)) |
|
|
|
|
|
self.distance = 0 |
|
|
|
|
|
|
|
def check(self, hit_callback, distance, current_block, next_block): |
|
if self.world.get_block_number(next_block): |
|
hit_callback(current_block, next_block) |
|
return True |
|
|
|
else: |
|
self.position = list(map(lambda x: self.position[x] + self.vector[x] * distance, range(3))) |
|
|
|
self.block = next_block |
|
self.distance += distance |
|
|
|
return False |
|
|
|
def step(self, hit_callback): |
|
bx, by, bz = self.block |
|
|
|
|
|
local_position = list(map(lambda x: self.position[x] - self.block[x], range(3))) |
|
|
|
|
|
|
|
|
|
|
|
sign = [1, 1, 1] |
|
absolute_vector = list(self.vector) |
|
|
|
for component in range(3): |
|
if self.vector[component] < 0: |
|
sign[component] = -1 |
|
|
|
absolute_vector[component] = -absolute_vector[component] |
|
local_position[component] = -local_position[component] |
|
|
|
lx, ly, lz = local_position |
|
vx, vy, vz = absolute_vector |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if vx: |
|
x = 0.5 |
|
y = (0.5 - lx) / vx * vy + ly |
|
z = (0.5 - lx) / vx * vz + lz |
|
|
|
if y >= -0.5 and y <= 0.5 and z >= -0.5 and z <= 0.5: |
|
distance = math.sqrt((x - lx) ** 2 + (y - ly) ** 2 + (z - lz) ** 2) |
|
|
|
|
|
|
|
|
|
return self.check(hit_callback, distance, (bx, by, bz), (bx + sign[0], by, bz)) |
|
|
|
if vy: |
|
x = (0.5 - ly) / vy * vx + lx |
|
y = 0.5 |
|
z = (0.5 - ly) / vy * vz + lz |
|
|
|
if x >= -0.5 and x <= 0.5 and z >= -0.5 and z <= 0.5: |
|
distance = math.sqrt((x - lx) ** 2 + (y - ly) ** 2 + (z - lz) ** 2) |
|
return self.check(hit_callback, distance, (bx, by, bz), (bx, by + sign[1], bz)) |
|
|
|
if vz: |
|
x = (0.5 - lz) / vz * vx + lx |
|
y = (0.5 - lz) / vz * vy + ly |
|
z = 0.5 |
|
|
|
if x >= -0.5 and x <= 0.5 and y >= -0.5 and y <= 0.5: |
|
distance = math.sqrt((x - lx) ** 2 + (y - ly) ** 2 + (z - lz) ** 2) |
|
return self.check(hit_callback, distance, (bx, by, bz), (bx, by, bz + sign[2])) |