Shared halo + deterministic border-quad ownership + T-junction conformance: 625/625 same-LOD for all three. LOD 2:1 prototype (collar zipper) fails MC 5 / hybrid 38 / DC 40 cases (corners, overhangs). Hybrid is bit-identical to MC on a sampled native SurfaceWorld cliff; DC rougher. Standalone only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
119 lines
5.6 KiB
PowerShell
119 lines
5.6 KiB
PowerShell
[CmdletBinding()]
|
|
param()
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$WorkDir = [IO.Path]::GetFullPath($PSScriptRoot)
|
|
$Standalone = [IO.Path]::GetFullPath((Join-Path $WorkDir '..\..'))
|
|
$PluginRoot = [IO.Path]::GetFullPath((Join-Path $Standalone '..'))
|
|
$BuildDir = Join-Path $WorkDir 'build'
|
|
$OutDir = Join-Path $WorkDir 'bin'
|
|
[IO.Directory]::CreateDirectory($BuildDir) | Out-Null
|
|
[IO.Directory]::CreateDirectory($OutDir) | Out-Null
|
|
|
|
$Runner = Get-Process -Id $PID
|
|
$Runner.PriorityClass = 'BelowNormal'
|
|
$Runner.ProcessorAffinity = [IntPtr]0xFF00
|
|
$Affinity = [IntPtr]0xFF00
|
|
$VcVars = 'E:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat'
|
|
if (-not (Test-Path -LiteralPath $VcVars -PathType Leaf)) { throw "MSVC environment script missing: $VcVars" }
|
|
|
|
# Import the exact MSVC environment without running the compiler through an unrestricted shell.
|
|
$EnvironmentLines = & $env:ComSpec /d /s /c "call `"$VcVars`" >nul 2>nul && set"
|
|
if ($LASTEXITCODE -ne 0) { throw "vcvars64 environment setup failed: $LASTEXITCODE" }
|
|
foreach ($Line in $EnvironmentLines) {
|
|
$Equals = $Line.IndexOf('=')
|
|
if ($Equals -le 0) { continue }
|
|
$Name = $Line.Substring(0, $Equals)
|
|
if ($Name.StartsWith('=')) { continue }
|
|
[Environment]::SetEnvironmentVariable($Name, $Line.Substring($Equals + 1), 'Process')
|
|
}
|
|
|
|
$Compiler = Join-Path $env:VCToolsInstallDir 'bin\Hostx64\x64\cl.exe'
|
|
if (-not (Test-Path -LiteralPath $Compiler -PathType Leaf)) { throw "MSVC compiler missing: $Compiler" }
|
|
$Source = Join-Path $WorkDir 'SharpMesherSpike.cpp'
|
|
$CoreInclude = Join-Path $Standalone 'Core\include'
|
|
$CoreLibrary = Join-Path $Standalone 'Build\VoxelForgeCore\VoxelForgeCore.lib'
|
|
if (-not (Test-Path -LiteralPath $CoreLibrary -PathType Leaf)) { throw "Core library missing: $CoreLibrary" }
|
|
$Exe = Join-Path $OutDir 'SharpMesherSpike.exe'
|
|
$Obj = Join-Path $BuildDir 'SharpMesherSpike.obj'
|
|
$Stdout = Join-Path $WorkDir 'build.stdout.log'
|
|
$Stderr = Join-Path $WorkDir 'build.stderr.log'
|
|
$CompilerArguments = '/nologo /std:c++20 /O2 /fp:precise /EHsc /MP8 /D_CRT_SECURE_NO_WARNINGS ' +
|
|
('/I"{0}" /I"{1}" /I"{2}" /Fo"{3}" "{4}" /Fe:"{5}" /link "{6}"' -f `
|
|
(Join-Path $Standalone 'Compat'), `
|
|
(Join-Path $Standalone 'Source\VoxelForge\Public'), $CoreInclude, $Obj, $Source, $Exe, $CoreLibrary)
|
|
|
|
$Attempt = 0
|
|
do {
|
|
$Attempt++
|
|
Remove-Item -LiteralPath $Stdout, $Stderr -Force -ErrorAction SilentlyContinue
|
|
$Info = [Diagnostics.ProcessStartInfo]::new()
|
|
$Info.FileName = $Compiler
|
|
$Info.Arguments = $CompilerArguments
|
|
$Info.WorkingDirectory = $PluginRoot
|
|
$Info.UseShellExecute = $false
|
|
$Info.CreateNoWindow = $true
|
|
$Info.RedirectStandardOutput = $true
|
|
$Info.RedirectStandardError = $true
|
|
$Process = [Diagnostics.Process]::new()
|
|
$Process.StartInfo = $Info
|
|
if (-not $Process.Start()) { throw 'Could not start cl.exe.' }
|
|
$ProcessId = $Process.Id
|
|
$Process.PriorityClass = [Diagnostics.ProcessPriorityClass]::BelowNormal
|
|
$Process.ProcessorAffinity = $Affinity
|
|
$OwnedPids = [Collections.Generic.HashSet[int]]::new()
|
|
[void]$OwnedPids.Add($ProcessId)
|
|
$StartAt = [DateTime]::UtcNow
|
|
$OutputTask = $Process.StandardOutput.ReadToEndAsync()
|
|
$ErrorTask = $Process.StandardError.ReadToEndAsync()
|
|
$TimedOut = $false
|
|
$MemoryStop = $false
|
|
while (-not $Process.HasExited) {
|
|
$Process.Refresh()
|
|
$Processes = @(Get-CimInstance -ClassName Win32_Process -ErrorAction SilentlyContinue)
|
|
$FoundChild = $true
|
|
while ($FoundChild) {
|
|
$FoundChild = $false
|
|
foreach ($Candidate in $Processes) {
|
|
if ($OwnedPids.Contains([int]$Candidate.ParentProcessId) -and
|
|
$OwnedPids.Add([int]$Candidate.ProcessId)) { $FoundChild = $true }
|
|
}
|
|
}
|
|
foreach ($OwnedPid in $OwnedPids) {
|
|
try {
|
|
$Child = Get-Process -Id $OwnedPid -ErrorAction Stop
|
|
$Child.PriorityClass = 'BelowNormal'
|
|
$Child.ProcessorAffinity = $Affinity
|
|
if ($Child.PrivateMemorySize64 -ge 8GB) { $MemoryStop = $true; Stop-Process -Id $OwnedPid -Force }
|
|
} catch {}
|
|
}
|
|
if ($MemoryStop) { break }
|
|
if (([DateTime]::UtcNow - $StartAt).TotalSeconds -ge 900) { $TimedOut = $true; break }
|
|
Start-Sleep -Milliseconds 200
|
|
}
|
|
if ($TimedOut -or $MemoryStop) {
|
|
foreach ($OwnedPid in $OwnedPids) { try { Stop-Process -Id $OwnedPid -Force -ErrorAction Stop } catch {} }
|
|
try { $Process.Kill() } catch {}
|
|
}
|
|
$Process.WaitForExit()
|
|
$CompilerStdout = $OutputTask.GetAwaiter().GetResult()
|
|
$CompilerStderr = $ErrorTask.GetAwaiter().GetResult()
|
|
[IO.File]::WriteAllText($Stdout, $CompilerStdout)
|
|
[IO.File]::WriteAllText($Stderr, $CompilerStderr)
|
|
if ($TimedOut) { throw 'Build exceeded 15 minutes and was stopped.' }
|
|
if ($MemoryStop) { throw 'Build process reached the 8 GB private-memory cap and was stopped.' }
|
|
if ($Process.ExitCode -eq -1073741502 -and $Attempt -eq 1) {
|
|
Write-Output 'Build exited 0xC0000142; waiting 60 seconds before the one allowed retry.'
|
|
Start-Sleep -Seconds 60
|
|
continue
|
|
}
|
|
if ($Process.ExitCode -ne 0) {
|
|
Write-Output "Build failed exit_code=$($Process.ExitCode) stdout=$Stdout stderr=$Stderr"
|
|
if ($CompilerStdout) { Write-Output $CompilerStdout }
|
|
if ($CompilerStderr) { Write-Output $CompilerStderr }
|
|
throw 'Sharp mesher spike build failed.'
|
|
}
|
|
} while ($Process.ExitCode -eq -1073741502 -and $Attempt -lt 2)
|
|
|
|
Write-Output "Build passed exe=$Exe elapsed_seconds=$([Math]::Round(([DateTime]::UtcNow - $StartAt).TotalSeconds,2)) priority=BelowNormal affinity=0xFF00"
|