mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-11 07:13:44 +00:00
feat(ugc): make models like LU Toolbox does, within CPU and memory budgets
Parity with LU Toolbox's Process Model, Bake Lighting and icon renderer, with its defaults as the settings' defaults: - Colors from its LU palette (UgcPalette: LU colors, LDD colors mapped to the nearest LU one, unknown ones black), transparent bricks at 58.82% opacity, a brick transparent only when all of its materials are. - Color variation: each brick's material gets its HSV value shifted in a 2.224 gamma by up to 5% (times the color's own amount), from a random number of the model, brick and material, so reprocessing gives the same colors in every LOD. Icons get none, and the icon renderer's color corrections. - LODs 0 and 2 with its distance logic, written as NiLODNode/NiRangeLODData like its exports and the game's own brick models, shapes divided at 65535 vertices along the longest side like divide_mesh. - Ambient occlusion like its AO-only bake: 64 rays per vertex, distance 5, after hidden surface removal, transparent bricks neither baked nor occluding, glow colors added. - Icons from its icon scene: 50 mm lens at 53.4/19.5 degrees, sun of 2.5 at 21/50.3 degrees with soft shadows, grey world light with occlusion; LOD 0's hidden surface removal and occlusion are reused for them. - Optional ground plane for hidden surface removal; stats.json per model and the previous version's previews kept for comparing. Budgets, applied live on config reload: max_cpu_percent (workers account their thread CPU time and sleep to stay under it, long renders included), worker_nice, max_memory_mb (jobs are estimated from their brick count and wait until they fit), max_model_bricks and pause_hours. /status and the traffic report show CPU, memory and throttling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,8 +10,13 @@ namespace {
|
||||
"model.nif", "model.nif.gz", "model.nif.checksum",
|
||||
"model.lxfml.gz", "model.lxfml.checksum",
|
||||
"icon.dds.gz", "icon.dds.checksum", "icon.png",
|
||||
"model.noao.nif", "stats.json",
|
||||
"previous.icon.png", "previous.model.nif", "previous.model.noao.nif", "previous.stats.json",
|
||||
};
|
||||
|
||||
// What of the files made before is kept when an item is made again, for comparing (as previous.<name>)
|
||||
constexpr std::array KEPT_FILES = { "icon.png", "model.nif", "model.noao.nif", "stats.json" };
|
||||
|
||||
const char* KindFolder(UgcStorage::Kind kind) {
|
||||
return kind == UgcStorage::Kind::MODEL ? "models" : "modular";
|
||||
}
|
||||
@@ -61,6 +66,14 @@ std::optional<uint64_t> UgcStorage::Write(Kind kind, LWOOBJID id, const Files& f
|
||||
}
|
||||
bytes += data.size();
|
||||
}
|
||||
// Keep the last version's previews to compare with
|
||||
for (const auto* name : KEPT_FILES) {
|
||||
if (files.contains(name)) {
|
||||
std::filesystem::copy_file(folder / name, temporary / (std::string("previous.") + name), std::filesystem::copy_options::overwrite_existing, code);
|
||||
if (!code) bytes += std::filesystem::file_size(temporary / (std::string("previous.") + name), code);
|
||||
code.clear();
|
||||
}
|
||||
}
|
||||
// Swap the old folder out and the new one in; the old one is deleted after
|
||||
const auto old = folder.parent_path() / (".old-" + folder.filename().string() + "-" + RandomSuffix());
|
||||
const bool hadOld = std::filesystem::exists(folder, code);
|
||||
|
||||
Reference in New Issue
Block a user