Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to also parse player clippings #376

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions awpy/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,12 @@ def parse_mapdata(overview_dir: Path) -> None:
@awpy_cli.command(name="tri", help="Parse triangles (*.tri) from a .vphys file.", hidden=True)
@click.argument("vphys_file", type=click.Path(exists=True))
@click.option("--outpath", type=click.Path(), help="Path to save the parsed triangle.")
def generate_tri(vphys_file: Path, *, outpath: Path | None = None) -> None:
@click.option(
"--include_player_clippings", is_flag=True, default=False, help="Include player clippings in tri generation."
)
def generate_tri(vphys_file: Path, *, outpath: Path | None = None, include_player_clippings: bool) -> None:
"""Parse a .vphys file into a .tri file."""
vphys_file = Path(vphys_file)
vphys_parser = VphysParser(vphys_file)
vphys_parser = VphysParser(vphys_file, including_player_clippings=include_player_clippings)
vphys_parser.to_tri(path=outpath)
logger.success(f"Tri file saved to {outpath}")
33 changes: 28 additions & 5 deletions awpy/visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,17 +248,19 @@ class VphysParser:
the .vphys file.
"""

def __init__(self, vphys_file: str | pathlib.Path) -> None:
def __init__(self, vphys_file: str | pathlib.Path, *, including_player_clippings: bool = False) -> None:
"""Initializes the parser with the path to a VPhys file.

Args:
vphys_file (str | pathlib.Path): Path to the VPhys file
to parse.
including_player_clippings (bool, optional): Whether to include
player clippings in the generated triangles. Defaults to False.
"""
self.vphys_file = pathlib.Path(vphys_file)
self.triangles = []
self.kv3_parser = KV3Parser()
self.parse()
self.parse(including_player_clippings=including_player_clippings)

@staticmethod
def bytes_to_vec(byte_str: str, element_size: int) -> list[int | float]:
Expand Down Expand Up @@ -288,7 +290,9 @@ def bytes_to_vec(byte_str: str, element_size: int) -> list[int | float]:

return result

def get_collision_attribute_indices_for_default_group(self) -> list[str]:
def get_collision_attribute_indices_for_default_group(
self, *, including_player_clippings: bool = False
) -> list[str]:
"""Get collision attribute indices for the default group.

Returns:
Expand All @@ -302,14 +306,31 @@ def get_collision_attribute_indices_for_default_group(self) -> list[str]:
break
if collision_group_string.lower() == '"default"':
collision_attribute_indices.append(str(idx))
elif including_player_clippings:
relevant_interactions = ['"playerclip"']
interacts_as: list[str] = []
interact_idx = 0
while True:
interaction = self.kv3_parser.get_value(
f"m_collisionAttributes[{idx}].m_InteractAsStrings[{interact_idx}]"
)
if not interaction:
break
interacts_as.append(interaction)
interact_idx += 1
if any(interaction.lower() in relevant_interactions for interaction in interacts_as):
collision_attribute_indices.append(str(idx))
idx += 1
return collision_attribute_indices

def parse(self) -> None:
def parse(self, *, including_player_clippings: bool = False) -> None: # noqa: PLR0912
"""Parses the VPhys file and extracts collision geometry.

Processes hulls and meshes in the VPhys file to generate a list of triangles.
"""
if including_player_clippings:
logger.debug("Including player clippings in tri generation.")

if len(self.triangles) > 0:
logger.debug(f"VPhys data already parsed, got {len(self.triangles)} triangles.")
return
Expand All @@ -323,7 +344,9 @@ def parse(self) -> None:
# Parse VPhys data
self.kv3_parser.parse(data)

collision_attribute_indices = self.get_collision_attribute_indices_for_default_group()
collision_attribute_indices = self.get_collision_attribute_indices_for_default_group(
including_player_clippings=including_player_clippings
)

logger.debug(f"Extracted collision attribute indices: {collision_attribute_indices}")

Expand Down
13 changes: 13 additions & 0 deletions scripts/generate-tris.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ Get-ChildItem -Path $inputPath -Filter "*.vpk" | Where-Object {
Write-Host "Error: .tri output not created for $fileNameWithoutExtension" -ForegroundColor Red
}

# Run the awpy tri command to generate a .tri file, outputting to a temporary file.
$triTempPath = Join-Path -Path $tempOutputDir -ChildPath "$fileNameWithoutExtension-clippings.tri"
Write-Host "Running awpy generate-tri on: $vphysFilePath" -ForegroundColor Yellow
uv run awpy tri $vphysFilePath --outpath $triTempPath --include_player_clippings

if (Test-Path $triTempPath) {
$finalTriPath = Join-Path -Path $outputDirectory -ChildPath "$fileNameWithoutExtension-clippings.tri"
Move-Item -Path $triTempPath -Destination $finalTriPath -Force
Write-Host "Output saved as: $finalTriPath" -ForegroundColor Cyan
} else {
Write-Host "Error: .tri output not created for $fileNameWithoutExtension" -ForegroundColor Red
}

# Clean up the temporary directory.
Remove-Item -Path $tempOutputDir -Recurse -Force
}
Expand Down
Loading