Пример #1
0
    def _side_color(
        self,
        side: Side,
        normal: Vec,
        min_pos: Vec,
        used_tex_func: Callable[[str], None],
    ) -> None:
        """Output the side texture for fields.

        used_tex_func is called with each material we use.
        """
        if not self.side_color:
            # Just apply nodraw.
            side.mat = const.Tools.NODRAW
            return

        # Produce a hex colour string, and use that as the material name.
        side.mat = 'BEE2/fizz_sides/side_color_{:02X}{:02X}{:02X}'.format(
            round(self.side_color.x * 255),
            round(self.side_color.y * 255),
            round(self.side_color.z * 255),
        )
        used_tex_func(side.mat)

        # FLip orientation if needed.
        if not side.uaxis.vec().dot(normal):
            side.vaxis, side.uaxis = side.uaxis, side.vaxis
        # The texture width is 32 pixels.
        side.scale = self.thickness / 32
        side.uaxis.offset = 16 + 2 * self.thickness * side.uaxis.vec().dot(
            min_pos) % 32
Пример #2
0
    def _side_color(self, side: Side, normal: Vec, min_pos: Vec,
                    used_tex_func):
        """Output the side texture for fields."""
        if not self.side_color:
            # Just apply nodraw.
            side.mat = const.Tools.NODRAW
            return

        import vbsp

        # Produce a hex colour string, and use that as the material name.
        side.mat = 'BEE2/fizz_sides/side_color_{:02X}{:02X}{:02X}'.format(
            round(self.side_color.x * 255),
            round(self.side_color.y * 255),
            round(self.side_color.z * 255),
        )
        used_tex_func(side.mat)

        # Pack the file.
        vbsp.PACK_FILES.add('materials/{}.vmt'.format(side.mat))
        # Pack the auxiliary texture needed.
        vbsp.PACK_FILES.add('materials/BEE2/fizz/fizz_side.vtf')

        # FLip orientation if needed.
        if not side.uaxis.vec().dot(normal):
            side.vaxis, side.uaxis = side.uaxis, side.vaxis
        # The texture width is 32 pixels.
        side.scale = self.thickness / 32
        side.uaxis.offset = 16 + 2 * self.thickness * side.uaxis.vec().dot(
            min_pos) % 32
Пример #3
0
    def _texture_fit(
        self,
        side: Side,
        tex_size: float,
        field_length: float,
        fizz: Fizzler,
        neg: Vec,
        pos: Vec,
        is_laserfield=False,
    ) -> None:
        """Calculate the texture offsets required for fitting a texture."""
        if side.vaxis.vec() != -fizz.up_axis:
            # Rotate it
            rot_angle = side.normal().rotation_around()
            for _ in range(4):
                side.uaxis = side.uaxis.rotate(rot_angle)
                side.vaxis = side.vaxis.rotate(rot_angle)
                if side.vaxis.vec() == -fizz.up_axis:
                    break
            else:
                LOGGER.warning("Can't fix rotation for {} -> {}", side.vaxis, fizz.up_axis)

        side.uaxis.offset = -(tex_size / field_length) * neg.dot(side.uaxis.vec())
        side.vaxis.offset = -(tex_size / 128) * neg.dot(side.vaxis.vec())

        #  The above fits it correctly, except it's vertically half-offset.
        # For laserfields that's what we want, for fizzlers we want it normal.
        if not is_laserfield:
            side.vaxis.offset += tex_size / 2

        side.uaxis.scale = field_length / tex_size
        side.vaxis.scale = 128 / tex_size

        side.uaxis.offset %= tex_size
        side.vaxis.offset %= tex_size
Пример #4
0
    def _texture_fit(
        self,
        side: Side,
        tex_size: float,
        field_length: float,
        fizz: Fizzler,
        neg: Vec,
        pos: Vec,
        is_laserfield=False,
    ) -> None:
        """Calculate the texture offsets required for fitting a texture."""
        if side.vaxis.vec() != -fizz.up_axis:
            # Rotate it
            rot_angle = side.normal().rotation_around()
            for _ in range(4):
                side.uaxis = side.uaxis.rotate(rot_angle)
                side.vaxis = side.vaxis.rotate(rot_angle)
                if side.vaxis.vec() == -fizz.up_axis:
                    break
            else:
                LOGGER.warning("Can't fix rotation for {} -> {}", side.vaxis, fizz.up_axis)

        side.uaxis.offset = -(tex_size / field_length) * neg.dot(side.uaxis.vec())
        side.vaxis.offset = -(tex_size / 128) * neg.dot(side.vaxis.vec())

        #  The above fits it correctly, except it's vertically half-offset.
        # For laserfields that's what we want, for fizzlers we want it normal.
        if not is_laserfield:
            side.vaxis.offset += tex_size / 2

        side.uaxis.scale = field_length / tex_size
        side.vaxis.scale = 128 / tex_size

        side.uaxis.offset %= tex_size
        side.vaxis.offset %= tex_size
Пример #5
0
    def _side_color(
        self,
        side: Side,
        normal: Vec,
        min_pos: Vec,
        used_tex_func: Callable[[str], None],
    ) -> None:
        """Output the side texture for fields.

        used_tex_func is called with each material we use.
        """
        if not self.side_color:
            # Just apply nodraw.
            side.mat = const.Tools.NODRAW
            return

        # Produce a hex colour string, and use that as the material name.
        side.mat = 'bee2/fizz_sides/side_color_{:02X}{:02X}{:02X}'.format(
            round(self.side_color.x * 255),
            round(self.side_color.y * 255),
            round(self.side_color.z * 255),
        )
        used_tex_func(side.mat)

        # FLip orientation if needed.
        if not side.uaxis.vec().dot(normal):
            side.vaxis, side.uaxis = side.uaxis, side.vaxis
        # The texture width is 32 pixels.
        side.scale = self.thickness / 32
        side.uaxis.offset = 16 + 2 * self.thickness * side.uaxis.vec().dot(min_pos) % 32
Пример #6
0
def fix_base_brush(vmf: VMF, solid: Solid, face: Side):
    """Retexture the brush forming the bottom of a pit."""
    if SETTINGS['skybox'] != '':
        face.mat = 'tools/toolsskybox'
    else:
        # We have a pit shell, we don't want a bottom.
        vmf.remove_brush(solid)
Пример #7
0
def fix_base_brush(vmf: VMF, solid: Solid, face: Side):
    """Retexture the brush forming the bottom of a pit."""
    if SETTINGS['skybox'] != '':
        face.mat = 'tools/toolsskybox'
        vbsp.IGNORED_FACES.add(face)
    else:
        # We have a pit shell, we don't want a bottom.
        vmf.remove_brush(solid)
Пример #8
0
def apply(cat: GenCat,
          face: Side,
          tex_name: str,
          portalable: Portalable = None,
          normal: Vec = None,
          loc: Vec = None):
    """Apply directly to a face, optionally using that to retrieve the location."""
    if cat is GenCat.SPECIAL or cat is GenCat.OVERLAYS:
        generator = GENERATORS[cat]
    else:
        if normal is None:
            normal = face.normal()
            normal.z = -normal.z
        generator = gen(cat, normal, portalable)

    if loc is None:
        loc = face.get_origin()

    face.mat = generator.get(loc, tex_name)
Пример #9
0
def make_displacement(
    face: Side,
    noise: SimplexNoise,
    power=3,
    offset=0,
):
    """Convert the given face to a displacement with random paint alpha."""
    bbox_min, bbox_max = face.get_bbox()
    face.is_disp = True
    face.disp_elev = offset  # An overall +- to z.
    face.disp_flags = 0  # Leave it solid
    face.disp_is_subdiv = False
    face.disp_power = power
    face.disp_pos = bbox_min.copy()
    face.disp_allowed_verts = {
        '10': '-1 -1 -1 -1 -1 -1 -1 -1 -1 -1',
    }

    LOGGER.debug('Making displacement from {} to {}', bbox_min, bbox_max)

    # Number of rows/columns needed
    grid_size = 2**power + 1

    # The width/height of the vertextes - this ensures neighbouring
    # noise matches up correctly.
    x_vert = (bbox_max.x - bbox_min.x) / grid_size
    y_vert = (bbox_max.y - bbox_min.y) / grid_size

    face.disp_data = {
        # We just want these values repeated the right number of times!
        'normals': '0 0 1',
        'distances': '0',
        'offsets': '0',
        'offset_normals': '0 0 1',
        'triangle_tags': '9',  # Walkable
    }
    for key, val in face.disp_data.items():
        # We can duplicate immutable strings fine..
        face.disp_data[key] = [val * grid_size] * grid_size

    face.disp_data['alphas'] = [
        ' '.join(
            str(512 * get_noise(
                Vec(
                    bbox_min.x + x * x_vert,
                    bbox_min.y + y * y_vert,
                    bbox_min.z,
                ) // max(x_vert, y_vert),
                noise,
            )) for x in range(grid_size)) for y in range(grid_size)
    ]
Пример #10
0
 def apply(self, face: Side, *, change_mat=True):
     """Apply the template to a face."""
     mat, face.uaxis, face.vaxis, face.ham_rot = self[face.normal().as_tuple()]
     if change_mat:
         face.mat = mat
Пример #11
0
def make_displacement(
        face: Side,
        noise: SimplexNoise,
        power=3,
        offset=0,
        ):
    """Convert the given face to a displacement with random paint alpha."""
    bbox_min, bbox_max = face.get_bbox()
    face.is_disp = True
    face.disp_elev = offset  # An overall +- to z.
    face.disp_flags = 0  # Leave it solid
    face.disp_is_subdiv = False
    face.disp_power = power
    face.disp_pos = bbox_min.copy()
    face.disp_allowed_verts = {
        '10': '-1 -1 -1 -1 -1 -1 -1 -1 -1 -1',
    }

    LOGGER.debug('Making displacement from {} to {}', bbox_min, bbox_max)

    # Number of rows/columns needed
    grid_size = 2 ** power + 1

    # The width/height of the vertextes - this ensures neighbouring
    # noise matches up correctly.
    x_vert = (bbox_max.x - bbox_min.x) / grid_size
    y_vert = (bbox_max.y - bbox_min.y) / grid_size

    face.disp_data = {
        # We just want these values repeated the right number of times!
        'normals': '0 0 1',
        'distances': '0',
        'offsets': '0',
        'offset_normals': '0 0 1',
        'triangle_tags': '9',  # Walkable
    }
    for key, val in face.disp_data.items():
        # We can duplicate immutable strings fine..
        face.disp_data[key] = [val * grid_size] * grid_size

    face.disp_data['alphas'] = [
        ' '.join(
            str(512 * get_noise(
                Vec(
                    bbox_min.x + x * x_vert,
                    bbox_min.y + y * y_vert,
                    bbox_min.z,
                ) // max(x_vert, y_vert),
                noise,
            ))
            for x in
            range(grid_size)
        )
        for y in range(grid_size)
    ]