本文整理汇总了Python中srctools.Vec.with_axes方法的典型用法代码示例。如果您正苦于以下问题:Python Vec.with_axes方法的具体用法?Python Vec.with_axes怎么用?Python Vec.with_axes使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类srctools.Vec
的用法示例。
在下文中一共展示了Vec.with_axes方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: _calc_fizz_angles
# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import with_axes [as 别名]
def _calc_fizz_angles() -> None:
"""Generate FIZZ_ANGLES."""
it = itertools.product('xyz', (-1, 1), 'xyz', (-1, 1))
for norm_axis, norm_mag, roll_axis, roll_mag in it:
if norm_axis == roll_axis:
# They can't both be the same...
continue
norm = Vec.with_axes(norm_axis, norm_mag)
roll = Vec.with_axes(roll_axis, roll_mag)
# Norm is Z, roll is X, we want y.
angle = roll.to_angle_roll(norm)
up_dir = norm.cross(roll)
FIZZ_ANGLES[norm.as_tuple(), up_dir.as_tuple()] = angle
示例2: beam_hole_split
# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import with_axes [as 别名]
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)
示例3: test_hole_spot
# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import with_axes [as 别名]
def test_hole_spot(origin: Vec, normal: Vec, hole_type: HoleType):
"""Check if the given position is valid for holes.
We need to check that it's actually placed on glass/grating, and that
all the parts are the same. Otherwise it'd collide with the borders.
"""
try:
center_type = BARRIERS[origin.as_tuple(), normal.as_tuple()]
except KeyError:
LOGGER.warning('No center barrier at {}, {}', origin, normal)
return False
if hole_type is HoleType.SMALL:
return True
u, v = Vec.INV_AXIS[normal.axis()]
# The corners don't matter, but all 4 neighbours must be there.
for u_off, v_off in [
(-128, 0),
(0, -128),
(128, 0),
(0, 128),
]:
pos = origin + Vec.with_axes(u, u_off, v, v_off)
try:
off_type = BARRIERS[pos.as_tuple(), normal.as_tuple()]
except KeyError:
# No side
LOGGER.warning('No offset barrier at {}, {}', pos, normal)
return False
if off_type is not center_type:
# Different type.
LOGGER.warning('Wrong barrier type at {}, {}', pos, normal)
return False
return True
示例4: add_glass_floorbeams
# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import with_axes [as 别名]
#.........这里部分代码省略.........
continue
pos = Vec(origin) + normal * 62
groups[pos.as_tuple()] = [pos]
# Loop over every pos and check in the +x/y directions for another glass
# piece. If there, merge the two lists and set every pos in the group to
# point to the new list.
# Once done, every unique list = a group.
for pos_tup in groups.keys():
pos = Vec(pos_tup)
for off in ((128, 0, 0), (0, 128, 0)):
neighbour = (pos + off).as_tuple()
if neighbour in groups:
our_group = groups[pos_tup]
neigh_group = groups[neighbour]
if our_group is neigh_group:
continue
# Now merge the two lists. We then need to update all dict locs
# to point to the new list.
if len(neigh_group) > len(our_group):
small_group, large_group = our_group, neigh_group
else:
small_group, large_group = neigh_group, our_group
large_group.extend(small_group)
for pos in small_group:
groups[pos.as_tuple()] = large_group
# Remove duplicates objects by using the ID as key..
groups = list({
id(group): group
for group in groups.values()
}.values())
# Side -> u, v or None
for group in groups:
bbox_min, bbox_max = Vec.bbox(group)
dimensions = bbox_max - bbox_min
LOGGER.info('Size = {}', dimensions)
# Our beams align to the smallest axis.
if dimensions.y > dimensions.x:
beam_ax = 'x'
side_ax = 'y'
rot = Vec(0, 0, 0)
else:
beam_ax = 'y'
side_ax = 'x'
rot = Vec(0, 90, 0)
# Build min, max tuples for each axis in the other direction.
# This tells us where the beams will be.
beams = {} # type: Dict[int, Tuple[int, int]]
# Add 128 so the first pos isn't a beam.
offset = bbox_min[side_ax] + 128
for pos in group:
side_off = pos[side_ax]
beam_off = pos[beam_ax]
# Skip over non-'sep' positions..
if (side_off - offset) % separation != 0:
continue
try:
min_pos, max_pos = beams[side_off]
except KeyError:
beams[side_off] = beam_off, beam_off
else:
beams[side_off] = min(min_pos, beam_off), max(max_pos, beam_off)
detail = vmf.create_ent('func_detail')
for side_off, (min_off, max_off) in beams.items():
for min_pos, max_pos in beam_hole_split(
beam_ax,
Vec.with_axes(side_ax, side_off, beam_ax, min_off, 'z', bbox_min),
Vec.with_axes(side_ax, side_off, beam_ax, max_off, 'z', bbox_min),
):
if min_pos[beam_ax] >= max_pos[beam_ax]:
raise ValueError(min_pos, max_pos, beam_ax)
# Make the beam.
# Grab the end face and snap to the length we want.
beam_end_off = max_pos[beam_ax] - min_pos[beam_ax]
assert beam_end_off > 0, beam_end_off
for plane in beam_end_face.planes:
plane.x = beam_end_off
new_beam = beam_template.copy(vmf_file=vmf)
new_beam.localise(min_pos, rot)
detail.solids.append(new_beam)
示例5: make_barriers
# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import with_axes [as 别名]
def make_barriers(vmf: VMF, get_tex: Callable[[str], str]):
"""Make barrier entities. get_tex is vbsp.get_tex."""
glass_temp = template_brush.get_scaling_template(
vbsp_options.get(str, "glass_template")
)
grate_temp = template_brush.get_scaling_template(
vbsp_options.get(str, "grating_template")
)
# Avoid error without this package.
if HOLES:
# Grab the template solids we need.
hole_temp = template_brush.get_template(
vbsp_options.get(str, 'glass_hole_temp')
)
hole_world, hole_detail, _ = hole_temp.visgrouped({'small'})
hole_temp_small = hole_world + hole_detail
hole_world, hole_detail, _ = hole_temp.visgrouped({'large'})
hole_temp_large = hole_world + hole_detail
hole_world, hole_detail, _ = hole_temp.visgrouped({'large_corner'})
hole_temp_corner = hole_world + hole_detail
else:
hole_temp_small = hole_temp_large = hole_temp_corner = None
floorbeam_temp = vbsp_options.get(str, 'glass_floorbeam_temp')
if vbsp_options.get_itemconf('BEE_PELLET:PelletGrating', False):
# Merge together these existing filters in global_pti_ents
vmf.create_ent(
origin=vbsp_options.get(Vec, 'global_pti_ents_loc'),
targetname='@grating_filter',
classname='filter_multi',
filtertype=0,
negated=0,
filter01='@not_pellet',
filter02='@not_paint_bomb',
)
else:
# Just skip paint bombs.
vmf.create_ent(
origin=vbsp_options.get(Vec, 'global_pti_ents_loc'),
targetname='@grating_filter',
classname='filter_activator_class',
negated=1,
filterclass='prop_paint_bomb',
)
# Group the positions by planes in each orientation.
# This makes them 2D grids which we can optimise.
# (normal_dist, positive_axis, type) -> [(x, y)]
slices = defaultdict(set) # type: Dict[Tuple[Tuple[float, float, float], bool, BarrierType], Set[Tuple[float, float]]]
# We have this on the 32-grid so we can cut squares for holes.
for (origin, normal), barr_type in BARRIERS.items():
origin = Vec(origin)
normal = Vec(normal)
norm_axis = normal.axis()
u, v = origin.other_axes(norm_axis)
norm_pos = Vec.with_axes(norm_axis, origin)
slice_plane = slices[
norm_pos.as_tuple(), # distance from origin to this plane.
normal[norm_axis] > 0,
barr_type,
]
for u_off in [-48, -16, 16, 48]:
for v_off in [-48, -16, 16, 48]:
slice_plane.add((
(u + u_off) // 32,
(v + v_off) // 32,
))
# Remove pane sections where the holes are. We then generate those with
# templates for slanted parts.
for (origin, normal), hole_type in HOLES.items():
barr_type = BARRIERS[origin, normal]
origin = Vec(origin)
normal = Vec(normal)
norm_axis = normal.axis()
u, v = origin.other_axes(norm_axis)
norm_pos = Vec.with_axes(norm_axis, origin)
slice_plane = slices[
norm_pos.as_tuple(),
normal[norm_axis] > 0,
barr_type,
]
if hole_type is HoleType.LARGE:
offsets = (-80, -48, -16, 16, 48, 80)
hole_temp = hole_temp_large.copy()
else:
offsets = (-16, 16)
hole_temp = hole_temp_small.copy()
for u_off in offsets:
for v_off in offsets:
# Skip the corners on large holes.
# Those aren't actually used, so skip them. That way
# we can have them diagonally or without glass in the corner.
if u_off in (-80, 80) and v_off in (-80, 80):
continue
slice_plane.discard((
#.........这里部分代码省略.........
示例6: make_frames
# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import with_axes [as 别名]
def make_frames(vmf: VMF, targ: str, conf: dict, bbox_min: Vec, bbox_max: Vec, norm: Vec):
"""Generate frames for a rectangular glass item."""
def make_frame(frame_type, loc, angles):
"""Make a frame instance."""
vmf.create_ent(
classname='func_instance',
targetname=targ,
file=conf['frame_' + frame_type],
# Position at the center of the block, instead of at the glass.
origin=loc - norm * 64,
angles=angles,
)
if bbox_min == bbox_max:
# 1x1 glass..
make_frame('single', bbox_min, norm.to_angle())
return
norm_axis = norm.axis()
u_axis, v_axis = Vec.INV_AXIS[norm_axis]
u_norm = Vec()
v_norm = Vec()
u_norm[u_axis] = 1
v_norm[v_axis] = 1
single_u = bbox_min[u_axis] == bbox_max[u_axis]
single_v = bbox_min[v_axis] == bbox_max[v_axis]
# If single in either direction, it needs a u-bend.
if single_u:
ubend_axis = v_axis
elif single_v:
ubend_axis = u_axis
else:
ubend_axis = None
if ubend_axis is not None:
for bend_mag, bbox in [(1, bbox_min), (-1, bbox_max)]:
make_frame(
'ubend',
bbox,
norm.to_angle_roll(Vec.with_axes(ubend_axis, bend_mag)),
)
else:
# Make 4 corners - one in each roll direction.
for roll in range(0, 360, 90):
angles = norm.to_angle(roll)
# The two directions with a border in the corner instance.
# We want to put it on those sides.
corner_a = Vec(y=-1).rotate(*angles)
corner_b = Vec(z=-1).rotate(*angles)
# If the normal is positive, we want to be bbox_max in that axis,
# otherwise bbox_min.
pos = Vec.with_axes(
norm_axis, bbox_min,
corner_a.axis(),
(bbox_max if corner_a >= (0, 0, 0) else bbox_min),
corner_b.axis(),
(bbox_max if corner_b >= (0, 0, 0) else bbox_min),
)
make_frame(
'corner',
pos,
angles,
)
# Make straight sections.
straight_u_pos = norm.to_angle_roll(v_norm)
straight_u_neg = norm.to_angle_roll(-v_norm)
straight_v_pos = norm.to_angle_roll(u_norm)
straight_v_neg = norm.to_angle_roll(-u_norm)
for u_pos in range(int(bbox_min[u_axis] + 128), int(bbox_max[u_axis]), 128):
make_frame(
'edge',
Vec.with_axes(u_axis, u_pos, v_axis, bbox_min, norm_axis, bbox_min),
straight_u_pos,
)
make_frame(
'edge',
Vec.with_axes(u_axis, u_pos, v_axis, bbox_max, norm_axis, bbox_min),
straight_u_neg,
)
for v_pos in range(int(bbox_min[v_axis] + 128), int(bbox_max[v_axis]), 128):
make_frame(
'edge',
Vec.with_axes(v_axis, v_pos, u_axis, bbox_min, norm_axis, bbox_min),
straight_v_pos,
)
make_frame(
'edge',
Vec.with_axes(v_axis, v_pos, u_axis, bbox_max, norm_axis, bbox_min),
straight_v_neg,
)
示例7: res_make_tag_fizzler
# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import with_axes [as 别名]
#.........这里部分代码省略.........
else:
offset = Vec(0, sign_offset, 0).rotate(*inst_angle)
blue_loc = loc + offset
oran_loc = loc - offset
else:
inst['file'] = inst_frame_single
# They're always centered
blue_loc = loc
oran_loc = loc
if inst_normal.z != 0:
# If on floors/ceilings, rotate to point at the fizzler!
sign_floor_loc = sign_loc.copy()
sign_floor_loc.z = 0 # We don't care about z-positions.
# Grab the data saved earlier in res_find_potential_tag_fizzlers()
axis, side_min, side_max, normal = calc_fizzler_orient(fizzler)
# The Z-axis fizzler (horizontal) must be treated differently.
if axis == 'z':
# For z-axis, just compare to the center point.
# The values are really x, y, z, not what they're named.
sign_dir = sign_floor_loc - (side_min, side_max, normal)
else:
# For the other two, we compare to the line,
# or compare to the closest side (in line with the fizz)
other_axis = 'x' if axis == 'y' else 'y'
if abs(sign_floor_loc[other_axis] - normal) < 32:
# Compare to the closest side. Use ** to swap x/y arguments
# appropriately. The closest side is the one with the
# smallest magnitude.
sign_dir = min(
sign_floor_loc - Vec.with_axes(
axis,side_min,
other_axis, normal,
),
sign_floor_loc - Vec.with_axes(
axis, side_max,
other_axis, normal,
),
key=Vec.mag,
)
else:
# Align just based on whether we're in front or behind.
sign_dir = Vec()
sign_dir[other_axis] = sign_floor_loc[other_axis] - normal
sign_angle = math.degrees(
math.atan2(sign_dir.y, sign_dir.x)
)
# Round to nearest 90 degrees
# Add 45 so the switchover point is at the diagonals
sign_angle = (sign_angle + 45) // 90 * 90
# Rotate to fit the instances - south is down
sign_angle = int(sign_angle + 90) % 360
if inst_normal.z > 0:
sign_angle = '0 {} 0'.format(sign_angle)
elif inst_normal.z < 0:
# Flip upside-down for ceilings
sign_angle = '0 {} 180'.format(sign_angle)
else:
# On a wall, face upright
sign_angle = PETI_INST_ANGLE[inst_normal.as_tuple()]