def beam_hole_split(axis: str, min_pos: Vec, max_pos: Vec): """Break up floor beams to fit around holes.""" # Go along the shape. For each point, check if a hole is present, # and split at that. # Our positions are centered, but we return ones at the ends. # Inset in 4 units from each end to not overlap with the frames. start_pos = min_pos - Vec.with_axes(axis, 60) if HOLES: hole_size_large = vbsp_options.get(float, 'glass_hole_size_large') / 2 hole_size_small = vbsp_options.get(float, 'glass_hole_size_small') / 2 # Extract normal from the z-axis. grid_height = min_pos.z // 128 * 128 + 64 if grid_height < min_pos.z: normal = (0, 0, 1) else: normal = (0, 0, -1) import vbsp for pos in min_pos.iter_line(max_pos, 128): try: hole_type = HOLES[(pos.x, pos.y, grid_height), normal] except KeyError: continue else: if hole_type is HoleType.SMALL: size = hole_size_small elif hole_type is HoleType.LARGE: size = hole_size_large else: raise AssertionError(hole_type) yield start_pos, pos - Vec.with_axes(axis, size) start_pos = pos + Vec.with_axes(axis, size) # Last segment, or all if no holes. yield start_pos, max_pos + Vec.with_axes(axis, 60)
def export(self, vmf: VMF, *, wall_conf: AntType, floor_conf: AntType) -> None: """Add the antlines into the map.""" # First, do some optimisation. If corners aren't defined, try and # optimise those antlines out by merging the straight segment # before/after it into the corners. collapse_line: list[Segment | None] if not wall_conf.tex_corner or not floor_conf.tex_corner: collapse_line = list(self.line) for i, seg in enumerate(collapse_line): if seg is None or seg.type is not SegType.STRAIGHT: continue if (floor_conf if seg.on_floor else wall_conf).tex_corner: continue for corner_ind in [i-1, i+1]: if i == -1: continue try: corner = collapse_line[corner_ind] except IndexError: # Each end of the list. continue if ( corner is not None and corner.type is SegType.CORNER and corner.normal == seg.normal ): corner_pos = corner.start if (seg.start - corner_pos).mag_sq() == 8 ** 2: # The line segment is at the border between them, # the corner is at the center. So move double the # distance towards the corner, so it reaches to the # other side of the corner and replaces it. seg.start += 2 * (corner_pos - seg.start) # Remove corner by setting to None, so we aren't # resizing the list constantly. collapse_line[corner_ind] = None # Now merge together the tiledefs. seg.tiles.update(corner.tiles) elif (seg.end - corner_pos).mag_sq() == 8 ** 2: seg.end += 2 * (corner_pos - seg.end) collapse_line[corner_ind] = None seg.tiles.update(corner.tiles) self.line[:] = [seg for seg in collapse_line if seg is not None] LOGGER.info('Collapsed {} antline corners', collapse_line.count(None)) for seg in self.line: conf = floor_conf if seg.on_floor else wall_conf # Check tiledefs in the voxels, and assign just in case. # antline corner items don't have them defined, and some embedfaces don't work # properly. But we keep any segments actually defined also. mins, maxs = Vec.bbox(seg.start, seg.end) norm_axis = seg.normal.axis() u_axis, v_axis = Vec.INV_AXIS[norm_axis] for pos in Vec.iter_line(mins, maxs, 128): pos[u_axis] = pos[u_axis] // 128 * 128 + 64 pos[v_axis] = pos[v_axis] // 128 * 128 + 64 pos -= 64 * seg.normal try: tile = tiling.TILES[pos.as_tuple(), seg.normal.as_tuple()] except KeyError: pass else: seg.tiles.add(tile) rng = rand.seed(b'antline', seg.start, seg.end) if seg.type is SegType.CORNER: mat: AntTex if rng.randrange(100) < conf.broken_chance: mat = rng.choice(conf.broken_corner or conf.broken_straight) else: mat = rng.choice(conf.tex_corner or conf.tex_straight) # Because we can, apply a random rotation to mix up the texture. orient = Matrix.from_angle(seg.normal.to_angle( rng.choice((0.0, 90.0, 180.0, 270.0)) )) self._make_overlay( vmf, seg, seg.start, 16.0 * orient.left(), 16.0 * orient.up(), mat, ) else: # Straight # TODO: Break up these segments. for a, b, is_broken in seg.broken_iter(conf.broken_chance): if is_broken: mat = rng.choice(conf.broken_straight) else: mat = rng.choice(conf.tex_straight) self._make_straight( vmf, seg, a, b, mat, )