Пример #1
0
def save_connectionpoint(item: Item, vmf: VMF) -> None:
    """Write connectionpoints to a VMF."""
    for side, points in item.antline_points.items():
        yaw = side.yaw
        inv_orient = Matrix.from_yaw(-yaw)
        for point in points:
            ant_pos = Vec(point.pos.x, -point.pos.y, -64)
            sign_pos = Vec(point.sign_off.x, -point.sign_off.y, -64)

            offset = (ant_pos - sign_pos) @ inv_orient
            try:
                skin = CONN_OFFSET_TO_SKIN[offset.as_tuple()]
            except KeyError:
                LOGGER.warning(
                    'Pos=({}), Sign=({}) -> ({}) is not a valid offset for signs!',
                    point.pos, point.sign_off, offset)
                continue
            pos: Vec = round((ant_pos + sign_pos) / 2.0 * 16.0, 0)

            vmf.create_ent(
                'bee2_editor_connectionpoint',
                origin=Vec(pos.x - 56, pos.y + 56, -64),
                angles=f'0 {yaw} 0',
                skin=skin,
                priority=point.priority,
                group_id='' if point.group is None else point.group,
            )
Пример #2
0
def res_temp_reset_gridded(inst: Entity):
    """Temporary result - reset gridded state on a surface.

    Used for antline routers to undo ItemLightStrip's 4x4 texturing.
    This should be removed after geometry is done.
    """
    pos = Vec(0, 0, -64)
    pos.localise(
        Vec.from_str(inst['origin']),
        Vec.from_str(inst['angles'])
    )
    norm = Vec(z=-1).rotate_by_str(inst['angles'])
    for axis in 'xyz':
        # Don't realign things in the normal's axis -
        # those are already fine.
        if not norm[axis]:
            pos[axis] //= 128
            pos[axis] *= 128
            pos[axis] += 64
    brush = SOLIDS.get(pos.as_tuple(), None)

    if brush is None:
        return

    if brush.color is template_brush.MAT_TYPES.white:
        brush.face.mat = const.WhitePan.WHITE_1x1
    else:
        brush.face.mat = const.BlackPan.BLACK_1
Пример #3
0
def pose(f, rot):
    global FRAME
       
    # Calculate the piston's rotation.
    
    # First find the real position of the piston hinge.
    hinge_pos = Vec(-43, 0, 10.5)
    hinge_pos.x -= 64
    hinge_pos.rotate(float(rot), 0, 0)
    hinge_pos.x += 64
    
	# Where we want the end of the piston to be.
    anchor_point = Vec(z=-96, x=rot*1.5 + 96)
    
    piston_off = hinge_pos - anchor_point
    print(piston_off)
    piston_rot = math.degrees(math.atan2(piston_off.z, -piston_off.x))
    
    f.write(frame_temp.format(
        time=FRAME,
        rot=-round(math.radians(rot), 6),
        # Cancel the effect of rot on pist_rot
        pist_rot=round(math.radians((piston_rot + rot) % 360), 6),
        len=-piston_off.mag(),
        marker=Vec(z=anchor_point.z, y=-anchor_point.x),
    ))
    FRAME += 1
Пример #4
0
def test_bbox() -> None:
    """Test the bounding box behaviour against a brute-force loop."""
    rand = Random(1234)  # Ensure reproducibility.
    SIZE = 128.0
    # Build a set of points and keys.
    points = [(Vec(rand.uniform(-SIZE, SIZE), rand.uniform(-SIZE, SIZE),
                   rand.uniform(-SIZE, SIZE)),
               Vec(rand.uniform(-SIZE, SIZE), rand.uniform(-SIZE, SIZE),
                   rand.uniform(-SIZE, SIZE)),
               rand.getrandbits(64).to_bytes(8, 'little')) for _ in range(200)]
    tree = RTree()
    for a, b, data in points:
        tree.insert(a, b, data)

    # Pick a random bounding box.
    bb_min, bb_max = Vec.bbox(
        Vec(
            rand.uniform(-SIZE, SIZE),
            rand.uniform(-SIZE, SIZE),
            rand.uniform(-SIZE, SIZE),
        ),
        Vec(
            rand.uniform(-SIZE, SIZE),
            rand.uniform(-SIZE, SIZE),
            rand.uniform(-SIZE, SIZE),
        ))
    expected = [
        data for a, b, data in points
        if Vec.bbox_intersect(*Vec.bbox(a, b), bb_min, bb_max)
    ]
    found = set(tree.find_bbox(bb_min, bb_max))
    # Order is irrelevant, but duplicates must all match.
    assert sorted(expected) == sorted(found)
Пример #5
0
def test_reorder_helper() -> None:
    """Test the reorder helper."""
    assert reorder((1, 2, 3), 'xyz', 0, 0, 0) == Vec(1, 2, 3)
    assert reorder((1, 2, 3), 'yzx', 0, 0, 0) == Vec(2, 3, 1)
    assert reorder((1, 2, 3), 'zyx', 0, 0, 0) == Vec(3, 2, 1)
    assert reorder((1, 2, 3), 'xzy', 0, 0, 0) == Vec(1, 3, 2)
    assert reorder((-10, 30, 0), 'xyz', 8, 6, 12) == Vec(-2, 36, 12)
Пример #6
0
def test_bbox_parse_block() -> None:
    """Test parsing of a block-shaped bbox from a VMF."""
    vmf = VMF()
    ent = vmf.create_ent(
        'bee2_collision_bbox',
        coll_deco=1,
        coll_physics=1,
        coll_grating=0,
        tags='standard excellent',
    )
    ent.solids.append(vmf.make_prism(Vec(80, 10, 40), Vec(150, 220, 70)).solid)
    ent.solids.append(vmf.make_prism(Vec(-30, 45, 80), Vec(-20, 60, 120)).solid)
    bb2, bb1 =  BBox.from_ent(ent)
    # Allow it to produce in either order.
    if bb1.min_x == -30:
        bb1, bb2 = bb2, bb1
    assert_bbox(
        bb1,
        (80, 10, 40), (150, 220, 70),
        CollideType.DECORATION | CollideType.PHYSICS,
        {'standard', 'excellent'},
    )
    assert_bbox(
        bb2,
        (-30, 45, 80), (-20, 60, 120),
        CollideType.DECORATION | CollideType.PHYSICS,
        {'standard', 'excellent'},
    )
Пример #7
0
def _make_support_table():
    """Make a table of angle/offset values for each direction."""
    for norm in (xp, xn, yp, yn, zp, zn):
        table = SUPPORT_POS[norm] = []
        for x in range(0, 360, 90):
            ang = Vec(norm).to_angle(roll=x)
            table.append((ang, Vec(0, 0, -64).rotate(*ang)))
Пример #8
0
    def _parse_smd_anim(file_iter: Iterator[Tuple[int, bytes]],
                        bones: Dict[int, Bone]):
        """Parse the 'skeleton' section of SMDs."""
        frames = {}
        time = -999999999
        for line_num, line in file_iter:
            if line.startswith((b'//', b'#', b';')):
                continue
            if line.startswith(b'time'):
                try:
                    time = int(line[4:])
                except ValueError:
                    raise ParseError(line_num, 'Invalid time value!') from None
                if time in frames:
                    raise ValueError(line_num, 'Duplicate frame time {}!',
                                     time)
                frames[time] = []
            elif line == b'end':
                return frames
            else:  # Bone.
                try:
                    byt_ind, byt_x, byt_y, byt_z, byt_pit, byt_yaw, byt_rol = line.split(
                    )
                    pos = Vec(float(byt_x), float(byt_y), float(byt_z))
                    rot = Vec(float(byt_pit), float(byt_yaw), float(byt_rol))
                except ValueError:
                    raise ParseError(line_num, 'Invalid line!') from None
                try:
                    bone = bones[int(byt_ind)]
                except KeyError:
                    raise ParseError(line_num, 'Unknown bone index {}!',
                                     int(byt_ind))
                frames[time].append(BoneFrame(bone, pos, rot))

        raise ParseError('end', 'No end to skeleton section!')
Пример #9
0
def make_alpha_base(vmf: VMF, bbox_min: Vec, bbox_max: Vec,
                    noise: SimplexNoise):
    """Add the base to a CutoutTile, using displacements."""
    # We want to limit the size of brushes to 512, so the vertexes don't
    # get too far apart.
    # This now contains each point from beginning to end inclusive.
    x, y, z = bbox_min

    dim_x = bbox_max.x - bbox_min.x
    dim_y = bbox_max.y - bbox_min.y

    widths = [x for x in range(0, int(dim_x), 512)] + [dim_x]
    heights = [y for y in range(0, int(dim_y), 512)] + [dim_y]

    # Loop over two offset copies, so we get a min and max each time.
    for x1, x2 in zip(widths, widths[1:]):
        for y1, y2 in zip(heights, heights[1:]):
            # We place our displacement 1 unit above the surface, then offset
            # the verts down.
            brush = vmf.make_prism(
                Vec(x + x1, y + y1, z - FLOOR_DEPTH),
                Vec(x + x2, y + y2, z - FLOOR_DEPTH - 1),
            )
            brush.top.mat = random.choice(MATS['floorbase_disp'])
            make_displacement(
                brush.top,
                offset=-1,
                noise=noise,
            )
            vmf.add_brush(brush.solid)
Пример #10
0
 def output_norm(self, dest: DestType=DestType.PRIMARY) -> Vec:
     """Return the flow direction at the end of this curve type."""
     assert dest is DestType.PRIMARY
     if self.reversed:
         return Vec(y=-1).rotate(*self.angles)
     else:
         return Vec(z=-1).rotate(*self.angles)
Пример #11
0
def make_anim(
    root: Bone,
    sty_ang: Angle,
    new_bones: Dict[Tuple[float, float, float], Dict[Bone, Bone]],
    name: str,
    animation: Dict[int, List[BoneFrame]],
) -> None:
    """Generate the animation file."""
    print(f' - {name}...', flush=True)
    mesh = Mesh({}, {}, [])

    # Add all the bones.
    mesh.bones[ROOT_NAME] = root
    for bone_map in new_bones.values():
        for bone in bone_map.values():
            mesh.bones[bone.name] = bone

    # Do the animation
    for frame_num, frames in animation.items():
        mesh.animation[frame_num] = new_frames = [
            BoneFrame(root, Vec(), Angle()),
        ]
        for angle, bone_map in new_bones.items():
            new_frames.append(BoneFrame(bone_map[root], Vec(), Angle(angle)))
            for frame in frames:
                new_frames.append(
                    BoneFrame(bone_map[frame.bone], frame.position,
                              frame.rotation))

    with open(name + '.smd', 'wb') as f:
        mesh.export(f)
Пример #12
0
 def output_norm(self, dest: DestType = DestType.PRIMARY) -> Vec:
     """Return the flow direction at the end of the curve."""
     assert dest is DestType.PRIMARY
     if self.reversed:
         return Vec(y=self.y) @ self.matrix
     else:
         return Vec(x=1, y=-self.y).norm() @ self.matrix
Пример #13
0
 def test(x1, y1, z1, x2, y2, z2):
     """Check a Vec pair for incorrect comparisons."""
     vec1 = Vec(x1, y1, z1)
     vec2 = Vec(x2, y2, z2)
     for op_func in comp_ops:
         if op_func is op.ne:
             # special-case - != uses or, not and
             corr_result = x1 != x2 or y1 != y2 or z1 != z2
         else:
             corr_result = op_func(x1, x2) and op_func(y1, y2) and op_func(
                 z1, z2)
         comp = ('Incorrect {{}} comparison for '
                 '({} {} {}) {} ({} {} {})'.format(x1, y1, z1,
                                                   op_func.__name__, x2, y2,
                                                   z2))
         assert op_func(vec1, vec2) == corr_result, comp.format('Vec')
         assert op_func(vec1, Vec_tuple(
             x2, y2, z2)) == corr_result, comp.format('Vec_tuple')
         assert op_func(vec1,
                        (x2, y2, z2)) == corr_result, comp.format('tuple')
         # Bare numbers compare magnitude..
         assert op_func(vec1, x2) == op_func(vec1.mag(),
                                             x2), comp.format('x')
         assert op_func(vec1, y2) == op_func(vec1.mag(),
                                             y2), comp.format('y')
         assert op_func(vec1, z2) == op_func(vec1.mag(),
                                             z2), comp.format('z')
Пример #14
0
def join_markers(inst_a, inst_b, is_start=False):
    """Join two marker ents together with corners.

    This returns a list of solids used for the vphysics_motion trigger.
    """
    origin_a = Vec.from_str(inst_a['ent']['origin'])
    origin_b = Vec.from_str(inst_b['ent']['origin'])

    norm_a = Vec(-1, 0, 0).rotate_by_str(inst_a['ent']['angles'])
    norm_b = Vec(-1, 0, 0).rotate_by_str(inst_b['ent']['angles'])

    config = inst_a['conf']

    if norm_a == norm_b:
        # Either straight-line, or s-bend.
        dist = (origin_a - origin_b).mag()

        if origin_a + (norm_a * dist) == origin_b:
            make_straight(
                origin_a,
                norm_a,
                dist,
                config,
                is_start,
            )
        # else: S-bend, we don't do the geometry for this..
        return

    if norm_a == -norm_b:
        # U-shape bend..
        make_ubend(
            origin_a,
            origin_b,
            norm_a,
            config,
            max_size=inst_a['size'],
        )
        return

    try:
        corner_ang, flat_angle = CORNER_ANG[norm_a.as_tuple(),
                                            norm_b.as_tuple()]

        if origin_a[flat_angle] != origin_b[flat_angle]:
            # It needs to be flat in this angle!
            raise ValueError
    except ValueError:
        # The tubes need two corners to join together - abort for that.
        return
    else:
        make_bend(
            origin_a,
            origin_b,
            norm_a,
            norm_b,
            corner_ang,
            config,
            max_size=inst_a['size'],
        )
Пример #15
0
 def blank(root_name: str) -> 'Mesh':
     """Create an empty mesh, with a single root bone."""
     root_bone = Bone(root_name, None)
     return Mesh(
         {root_name: root_bone},
         {0: [BoneFrame(root_bone, Vec(), Vec())]},
         [],
     )
Пример #16
0
def make_tag_coop_inst(tag_loc: str):
    """Make the coop version of the tag instances.

    This needs to be shrunk, so all the logic entities are not spread
    out so much (coop tubes are small).

    This way we avoid distributing the logic.
    """
    global TAG_COOP_INST_VMF
    TAG_COOP_INST_VMF = vmf = VMF.parse(
        os.path.join(tag_loc, TAG_GUN_COOP_INST)
    )

    def logic_pos():
        """Put the entities in a nice circle..."""
        while True:
            for ang in range(0, 44):
                ang *= 360/44
                yield Vec(16*math.sin(ang), 16*math.cos(ang), 32)
    pos = logic_pos()
    # Move all entities that don't care about position to the base of the player
    for ent in TAG_COOP_INST_VMF.iter_ents():
        if ent['classname'] == 'info_coop_spawn':
            # Remove the original spawn point from the instance.
            # That way it can overlay over other dropper instances.
            ent.remove()
        elif ent['classname'] in ('info_target', 'info_paint_sprayer'):
            pass
        else:
            ent['origin'] = next(pos)

            # These originally use the coop spawn point, but this doesn't
            # always work. Switch to the name of the player, which is much
            # more reliable.
            if ent['classname'] == 'logic_measure_movement':
                ent['measuretarget'] = '!player_blue'

    # Add in a trigger to start the gel gun, and reset the activated
    # gel whenever the player spawns.
    trig_brush = vmf.make_prism(
        Vec(-32, -32, 0),
        Vec(32, 32, 16),
        mat='tools/toolstrigger',
    ).solid
    start_trig = vmf.create_ent(
        classname='trigger_playerteam',
        target_team=3,  # ATLAS
        spawnflags=1,  # Clients only
        origin='0 0 8',
    )
    start_trig.solids = [trig_brush]
    start_trig.add_out(
        # This uses the !activator as the target player so it must be via trigger.
        Output('OnStartTouchBluePlayer', '@gel_ui', 'Activate', delay=0, only_once=True),
        # Reset the gun to fire nothing.
        Output('OnStartTouchBluePlayer', '@blueisenabled', 'SetValue', 0, delay=0.1),
        Output('OnStartTouchBluePlayer', '@orangeisenabled', 'SetValue', 0, delay=0.1),
    )
Пример #17
0
def join_markers(mark_a: Marker,
                 mark_b: Marker,
                 is_start: bool = False) -> None:
    """Join two marker ents together with corners."""
    origin_a = Vec.from_str(mark_a.ent['origin'])
    origin_b = Vec.from_str(mark_b.ent['origin'])

    norm_a = Vec(-1, 0, 0).rotate_by_str(mark_a.ent['angles'])
    norm_b = Vec(-1, 0, 0).rotate_by_str(mark_b.ent['angles'])

    config = mark_a.conf

    if norm_a == norm_b:
        # Either straight-line, or s-bend.
        dist = (origin_a - origin_b).mag()

        if origin_a + (norm_a * dist) == origin_b:
            make_straight(
                origin_a,
                norm_a,
                dist,
                config,
                is_start,
            )
        # else: S-bend, we don't do the geometry for this..
        return

    if norm_a == -norm_b:
        # U-shape bend..
        make_ubend(
            origin_a,
            origin_b,
            norm_a,
            config,
            max_size=mark_a.size,
        )
        return

    try:
        corner_ang, flat_angle = CORNER_ANG[norm_a.as_tuple(),
                                            norm_b.as_tuple()]

        if origin_a[flat_angle] != origin_b[flat_angle]:
            # It needs to be flat in this angle!
            raise ValueError
    except ValueError:
        # The tubes need two corners to join together - abort for that.
        return
    else:
        make_bend(
            origin_a,
            origin_b,
            norm_a,
            norm_b,
            corner_ang,
            config,
            max_size=mark_a.size,
        )
Пример #18
0
 def vec_point(self, t: float, dest: DestType = DestType.PRIMARY) -> Vec:
     assert dest is not DestType.TERTIARY
     x, y = curve_point(64.0, t)
     if dest is DestType.SECONDARY:
         return self.origin + Vec(y, x, 0) @ self.matrix
     elif self.is_straight:
         return self.origin + Vec(y=128 * t) @ self.matrix
     else:
         return self.origin + Vec(-y, x, 0) @ self.matrix
Пример #19
0
 def output_norm(self, dest: DestType = DestType.PRIMARY) -> Vec:
     """Return the flow direction at the end of this curve type."""
     if dest is DestType.PRIMARY:
         return Vec(x=1) @ self.matrix
     elif dest is DestType.SECONDARY:
         return Vec(y=1) @ self.matrix
     elif dest is DestType.TERTIARY:
         return Vec(x=-1) @ self.matrix
     else:
         raise AssertionError(dest)
Пример #20
0
 def output_norm(self, dest: DestType = DestType.PRIMARY) -> Vec:
     """Return the flow direction at the end of this curve type."""
     if dest is DestType.SECONDARY:
         return Vec(x=1) @ self.matrix
     else:
         assert dest is DestType.PRIMARY
         if self.is_straight:
             return Vec(y=1) @ self.matrix
         else:
             return Vec(x=-1) @ self.matrix
Пример #21
0
def test_to_angle_roundtrip(py_c_vec):
    """Check Vec.to_angle() roundtrips."""
    Vec, Angle, Matrix, parse_vec_str = py_c_vec

    for x, y, z in iter_vec((-1, 0, 1)):
        if x == y == z == 0:
            continue
        norm = Vec(x, y, z).norm()
        ang = norm.to_angle()
        assert_vec(Vec(x=1).rotate(*ang), norm.x, norm.y, norm.z, ang)
Пример #22
0
def save_embeddedvoxel(item: Item, vmf: VMF) -> None:
    """Save embedded voxel volumes."""
    for bbox_min, bbox_max in bounding_boxes(item.embed_voxels):
        vmf.create_ent('bee2_editor_embeddedvoxel').solids.append(
            vmf.make_prism(
                Vec(bbox_min) * 128 + (-64.0, -64.0, -192.0),
                Vec(bbox_max) * 128 + (+64.0, +64.0, -64.0),
                # Entirely ignored, but makes it easier to distinguish.
                'tools/toolshint',
            ).solid)
Пример #23
0
def join_markers(vmf: VMF,
                 mark_a: Marker,
                 mark_b: Marker,
                 is_start: bool = False) -> None:
    """Join two marker ents together with corners."""
    origin_a = Vec.from_str(mark_a.ent['origin'])
    origin_b = Vec.from_str(mark_b.ent['origin'])

    norm_a = Vec(-1, 0, 0).rotate_by_str(mark_a.ent['angles'])
    norm_b = Vec(-1, 0, 0).rotate_by_str(mark_b.ent['angles'])

    config = mark_a.conf

    if norm_a == norm_b:
        # Either straight-line, or s-bend.
        dist = (origin_a - origin_b).mag()

        if origin_a + (norm_a * dist) == origin_b:
            make_straight(
                vmf,
                origin_a,
                norm_a,
                dist,
                config,
                is_start,
            )
        # else: S-bend, we don't do the geometry for this..
        return

    if norm_a == -norm_b:
        # U-shape bend..
        make_ubend(
            vmf,
            origin_a,
            origin_b,
            norm_a,
            config,
            max_size=mark_a.size,
        )
        return

    # Lastly try a regular curve. Check they are on the same plane.
    side_dir = Vec.cross(norm_a, norm_b)
    side_off_a = side_dir.dot(origin_a)
    side_off_b = side_dir.dot(origin_b)
    if side_off_a == side_off_b:
        make_bend(
            vmf,
            origin_a,
            origin_b,
            norm_a,
            norm_b,
            config,
            max_size=mark_a.size,
        )
Пример #24
0
    def rotate(self, angles: Vec, origin: Vec=(0, 0, 0)):
        """Rotate this template, and return a new template with those angles."""
        new_axis = {}
        origin = Vec(origin)
        for norm, (mat, axis_u, axis_v, rot) in self._axes.items():
            axis_u = axis_u.localise(origin, angles)
            axis_v = axis_v.localise(origin, angles)
            norm = Vec(norm).rotate(*angles)
            new_axis[norm.as_tuple()] = mat, axis_u, axis_v, rot

        return ScalingTemplate(self.id, new_axis)
Пример #25
0
 def vec_point(self, t: float, dest: DestType = DestType.PRIMARY) -> Vec:
     """Return the position this far through the given curve."""
     x, y = curve_point(64.0, t)
     if dest is DestType.PRIMARY:
         return self.origin + Vec(y, x, 0) @ self.matrix
     elif dest is DestType.SECONDARY:
         return self.origin + Vec(y=128 * t) @ self.matrix
     elif dest is DestType.TERTIARY:
         return self.origin + Vec(-y, x, 0) @ self.matrix
     else:
         raise AssertionError(dest)
Пример #26
0
def test_bbox_parse_plane(axis: str, mins: tuple3, maxes: tuple3) -> None:
    """Test parsing planar bboxes from a VMF.

    With 5 skip sides, the brush is flattened into the remaining plane.
    """
    vmf = VMF()
    ent = vmf.create_ent('bee2_collision_bbox', coll_solid=1)
    prism = vmf.make_prism(Vec(80, 10, 40), Vec(150, 220, 70), mat='tools/toolsskip')
    getattr(prism, axis).mat = 'tools/toolsclip'
    ent.solids.append(prism.solid)
    [bbox] = BBox.from_ent(ent)
    assert_bbox(bbox, mins, maxes, CollideType.SOLID, set())
Пример #27
0
    def __init__(
        self,
        model: str,
        origin: Vec,
        angles: Vec,
        scaling: float,
        visleafs: List[int],
        solidity: int,
        flags: StaticPropFlags = StaticPropFlags.NONE,
        skin: int = 0,
        min_fade: float = 0,
        max_fade: float = 0,
        lighting_origin: Vec = None,
        fade_scale: float = -1,
        min_dx_level: int = 0,
        max_dx_level: int = 0,
        min_cpu_level: int = 0,
        max_cpu_level: int = 0,
        min_gpu_level: int = 0,
        max_gpu_level: int = 0,
        tint: Vec = Vec(255, 255, 255),  # Rendercolor
        renderfx: int = 255,
        disable_on_xbox: bool = False,
    ) -> None:
        self.model = model
        self.origin = origin
        self.angles = angles
        self.scaling = scaling
        self.visleafs = visleafs
        self.solidity = solidity
        self.flags = flags
        self.skin = skin
        self.min_fade = min_fade
        self.max_fade = max_fade

        if lighting_origin is None:
            self.lighting = Vec(origin)
        else:
            self.lighting = lighting_origin

        self.fade_scale = fade_scale
        self.min_dx_level = min_dx_level
        self.max_dx_level = max_dx_level
        self.min_cpu_level = min_cpu_level
        self.max_cpu_level = max_cpu_level
        self.min_gpu_level = min_gpu_level
        self.max_gpu_level = max_gpu_level
        self.tint = Vec(tint)
        self.renderfx = renderfx
        self.disable_on_xbox = disable_on_xbox
Пример #28
0
    def rotate(self,
               angles: Vec,
               origin: Optional[Vec] = None) -> 'ScalingTemplate':
        """Rotate this template, and return a new template with those angles."""
        new_axis = {}
        if origin is None:
            origin = Vec()

        for norm, (mat, axis_u, axis_v, rot) in self._axes.items():
            axis_u = axis_u.localise(origin, angles)
            axis_v = axis_v.localise(origin, angles)
            v_norm = Vec(norm).rotate(*angles)
            new_axis[v_norm.as_tuple()] = mat, axis_u, axis_v, rot

        return ScalingTemplate(self.id, new_axis)
Пример #29
0
def test_vec_identities(py_c_vec) -> None:
    """Check that vectors in the same axis as the rotation don't get spun."""
    Vec, Angle, Matrix, parse_vec_str = py_c_vec

    for ang in range(0, 360, 13):
        # Check the two constructors match.
        assert_rot(Matrix.from_pitch(ang), Matrix.from_angle(Angle(pitch=ang)))
        assert_rot(Matrix.from_yaw(ang), Matrix.from_angle(Angle(yaw=ang)))
        assert_rot(Matrix.from_roll(ang), Matrix.from_angle(Angle(roll=ang)))

        # Various magnitudes to test
        for mag in (-250, -1, 0, 1, 250):
            assert_vec(Vec(y=mag) @ Matrix.from_pitch(ang), 0, mag, 0)
            assert_vec(Vec(z=mag) @ Matrix.from_yaw(ang), 0, 0, mag)
            assert_vec(Vec(x=mag) @ Matrix.from_roll(ang), mag, 0, 0)
Пример #30
0
def test_bbox_vecs() -> None:
    """Test that the vector properties don't return the same object."""
    bb = BBox(30, 60, 80, 120, 451, 730)

    assert bb.mins == Vec(30.0, 60.0, 80.0)
    assert bb.mins is not bb.mins

    assert bb.maxes == Vec(120.0, 451.0, 730.0)
    assert bb.maxes is not bb.maxes

    assert bb.size == Vec(90.0, 391.0, 650.0)
    assert bb.size is not bb.size

    assert bb.center == Vec(75.0, 255.5, 405.0)
    assert bb.center is not bb.center