75 lines
4.4 KiB
PowerShell
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
|