Files
NODEDC_MISSION_CORE/simulation/ai-polygon/navigation/Prepare-Terrain.ps1
T

75 lines
4.4 KiB
PowerShell

param(
[Parameter(Mandatory=$true)][string]$WorldFile,
[string]$Root = 'D:\NDC_MISSIONCORE\runtime\simulation',
[string]$Python = 'D:\NDC_MISSIONCORE\runtime\simulation\isaac-sim-6.1.0\kit\python\python.exe'
)
$ErrorActionPreference = 'Stop'
[Threading.Thread]::CurrentThread.CurrentCulture = [Globalization.CultureInfo]::InvariantCulture
$world = Get-Content -Raw $WorldFile | ConvertFrom-Json
if ($world.sha256 -notmatch '^[a-f0-9]{64}$') { throw 'Invalid source hash' }
$source = Join-Path $Root ('state\worlds\' + $world.sha256 + '.ply')
if ((Get-FileHash $source -Algorithm SHA256).Hash.ToLower() -ne $world.sha256) { throw 'World source changed' }
$tool = Join-Path $Root 'tools\splat-transform-3.4.0\node_modules\@playcanvas\splat-transform'
$package = Get-Content -Raw (Join-Path $tool 'package.json') | ConvertFrom-Json
if ($package.version -ne '3.4.0') { throw 'SplatTransform version changed' }
$settings = $world.settings
$json = ($settings | ConvertTo-Json -Compress) + (Get-FileHash $PSCommandPath -Algorithm SHA256).Hash
$sha = [Security.Cryptography.SHA256]::Create()
$digest = [BitConverter]::ToString($sha.ComputeHash([Text.Encoding]::UTF8.GetBytes($json))).Replace('-','').ToLower()
$out = Join-Path $Root ('assets\terrain-v1\' + $world.sha256 + '-' + $digest.Substring(0,16))
New-Item -ItemType Directory -Force $out | Out-Null
$mesh = Join-Path $out 'terrain.collision.glb'
$migrator = Join-Path $PSScriptRoot 'migrate_terrain_coordinates.py'
if ((Get-FileHash $migrator -Algorithm SHA256).Hash.ToLower() -ne 'ff08de8b97b9f2b0040b379840c402f5c7c327e3bc1915548d99b6372ff5ca37') { throw 'Coordinate migrator identity changed' }
if (-not (Test-Path $mesh)) {
# Exact rigid correction of the admitted historical cache avoids rerunning
# a faulty third-party BVH build. Never mutates or reclassifies that mesh.
$ErrorActionPreference = 'Continue'
& $Python $migrator --root $Root --world $WorldFile --output $mesh
if ($LASTEXITCODE -notin @(0,2)) { throw 'Collision coordinate migration failed' }
$ErrorActionPreference = 'Stop'
}
if (-not (Test-Path $mesh)) {
# SplatTransform 3.4 assigns PLY an implicit Rz(180) before CLI actions.
# Cancel it FIRST, then apply the same XYZ rotation as the USD visual.
# World Z-up -> glTF Y-up is Rx(-90): (x,y,z) -> (x,z,-y).
# Runtime's (x,y,z) -> (x,-z,y) is exactly its inverse. Do not use Rx(+90).
$x = [double]$settings.spawn_xy[0]; $y = [double]$settings.spawn_xy[1]; $z = [double]$settings.ground_z
$box = @(($x-15),($z-4),(-$y-15),($x+15),($z+8),(-$y+15)) -join ','
$args = @('--max-old-space-size=12288', (Join-Path $tool 'bin\cli.mjs'), $source,
'--filter-nan', '--rotate', '0,0,180',
'--rotate', ($settings.rotation_degrees -join ','),
'--scale', [string]$settings.meters_per_unit,
'--rotate', '-90,0,0', '--filter-box', $box,
'--voxel-size', '0.06', '--voxel-opacity', '0.25',
'--voxel-floor-fill', '0.3', '--collision-mesh', 'smooth',
(Join-Path $out 'terrain.voxel.json'))
$ErrorActionPreference = 'Continue'
& node @args
if ($LASTEXITCODE -ne 0) { throw 'SplatTransform collision generation failed' }
$ErrorActionPreference = 'Stop'
}
if (-not (Test-Path $mesh)) { throw 'Collision mesh was not produced' }
$correctionPath = Join-Path $out 'coordinate-correction.json'
$correction = if (Test-Path $correctionPath) { Get-Content -Raw $correctionPath | ConvertFrom-Json } else { $null }
if ($correction) {
if ((Get-FileHash $mesh -Algorithm SHA256).Hash.ToLower() -ne $correction.collider_sha256) { throw 'Corrected collision changed' }
$settings = $correction.settings
}
$manifest = @{
schema_version = 'missioncore.ai-polygon-terrain/v1'
source_sha256 = $world.sha256
settings = $settings
generator = '@playcanvas/splat-transform@3.4.0'
generator_sha256 = (Get-FileHash $PSCommandPath -Algorithm SHA256).Hash.ToLower()
voxel_size_m = 0.06
collider = $mesh
collider_sha256 = (Get-FileHash $mesh -Algorithm SHA256).Hash.ToLower()
coordinate_system = 'gltf-y-up-from-metric-world'
coordinate_revision = 'ply-rz180-cancelled-usd-xyz-gltf-rx-minus90-v2'
coordinate_correction = $correction
qualification = 'reconstructed-proxy-requires-contact-validation'
}
[IO.File]::WriteAllText((Join-Path $out 'terrain.json'), ($manifest | ConvertTo-Json -Depth 6), [Text.UTF8Encoding]::new($false))
$manifest | ConvertTo-Json -Depth 6 -Compress