mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
feat(dashboard): pick processing options for Make again; compare them on the UGC page
The UGC page's Make again buttons (a model's, the failed ones, everything) use the ray tracer, hidden-face method and denoising picked next to them (the settings' when left alone). The List view's new Options column shows what made each model and what its next make will use; "Processing options compared" shows every combination the made models used with its makes, models and the average time, CPU time, hidden faces', occlusion's and icon's time and share of triangles removed per make. Check: the three selects next to Make again (models only); make a model again with embree fast and see its Options column and the comparison table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -125,10 +125,14 @@
|
||||
if (!i.processMs) return '';
|
||||
return 'took ' + duration(i.processMs) + (i.processCpuMs ? ', CPU ' + duration(i.processCpuMs) : '') + (i.processMemoryKb ? ', ~' + megabytes(i.processMemoryKb) + ' RAM (est.)' : '');
|
||||
}
|
||||
// When it was made and what that cost (the cost is only known for makes since it was recorded)
|
||||
// When it was made and what that cost (the cost is only known for makes since it was recorded), and with what
|
||||
function madeText(i) {
|
||||
if (!i.processedAt) return '';
|
||||
return fmt.unix(i.processedAt) + (costText(i) ? ' \u00b7 ' + costText(i) : '');
|
||||
return fmt.unix(i.processedAt) + (costText(i) ? ' \u00b7 ' + costText(i) : '') + (i.madeOptions ? ' \u00b7 with ' + i.madeOptions : '');
|
||||
}
|
||||
// The processing options picked for Make again (ray tracer, hidden faces, denoise), as /api/ugc/reprocess takes them
|
||||
function remakeOptions() {
|
||||
return ['optRays', 'optHsr', 'optDenoise'].map(function (x) { return $(x).value; }).filter(Boolean).join(' ');
|
||||
}
|
||||
// A model's file as the player named it: its name with the upload's extension (".lxfml"), else the upload's name
|
||||
function fileName(i) {
|
||||
@@ -178,6 +182,10 @@
|
||||
return badge(i.state) + (i.attempts ? ' <span class="small text-body-secondary">' + esc(i.attempts) + ' attempt' + (i.attempts === 1 ? '' : 's') + '</span>' : '') + waitBadge(i);
|
||||
})
|
||||
].concat(madeColumns(), [
|
||||
column('Options', function (i) {
|
||||
return '<span class="small">' + esc(i.madeOptions || '') + '</span>' +
|
||||
(i.processOptions ? '<div class="small text-body-secondary" title="Picked for its next make">next: ' + esc(i.processOptions) + '</div>' : '');
|
||||
}),
|
||||
column('Saved', function (i) {
|
||||
if (!i.trianglesBefore) return '';
|
||||
var removed = i.trianglesBefore - i.triangles, share = removed / i.trianglesBefore * 100;
|
||||
@@ -256,6 +264,7 @@
|
||||
b.textContent = (b.dataset.kind === 'modular' ? 'Cars and rockets' : 'Models') + (count === null || count === undefined ? '' : ' (' + Number(count).toLocaleString() + ')');
|
||||
});
|
||||
$('manageButtons').classList.toggle('d-none', !canManage);
|
||||
$('remakeOptions').classList.toggle('d-none', list.kind !== 'model');
|
||||
$('cacheCard').classList.toggle('d-none', !canManage);
|
||||
$('counts').innerHTML = countCard('Models', d.counts.model) + countCard('Cars and rockets (builds)', d.counts.modular) +
|
||||
(d.totals ? totalsCard('Models', d.totals.model) + totalsCard('Cars and rockets', d.totals.modular) : '');
|
||||
@@ -366,6 +375,7 @@
|
||||
function remake(body, question) {
|
||||
if (question && !confirm(question)) return;
|
||||
body.kind = list.kind;
|
||||
if (list.kind === 'model' && remakeOptions()) body.options = remakeOptions();
|
||||
api.post('/api/ugc/reprocess', body).then(function (d) {
|
||||
if (!d.success) { toast(d.error || 'Failed', 'danger'); return; }
|
||||
toast(d.message, 'success');
|
||||
@@ -715,6 +725,31 @@
|
||||
}
|
||||
loadPresets();
|
||||
|
||||
// ---- processing options: Make again's choices and the comparison of what made the models ----
|
||||
|
||||
var OPTION_LABELS = { builtin: 'Built in', embree: 'Embree (CPU)', hiprt: 'HIPRT (GPU)', toolbox: 'LU Toolbox (paths)', fast: 'Fast (renders)', off: 'Off', oidn: 'Open Image Denoise' };
|
||||
function loadOptions() {
|
||||
return api.get('/api/ugc/options').then(function (d) {
|
||||
if (!d.success) throw new Error(d.error || 'Failed');
|
||||
[['optRays', 'rays', 'Ray tracer'], ['optHsr', 'hsr', 'Hidden faces'], ['optDenoise', 'denoise', 'Denoise']].forEach(function (x) {
|
||||
var select = $(x[0]), chosen = select.value;
|
||||
select.innerHTML = '<option value="">' + esc(x[2]) + ': settings (' + esc(OPTION_LABELS[d.defaults[x[1]]] || d.defaults[x[1]]) + ')</option>' +
|
||||
d.choices[x[1]].map(function (name) { return '<option value="' + esc(name) + '">' + esc(x[2]) + ': ' + esc(OPTION_LABELS[name] || name) + '</option>'; }).join('');
|
||||
select.value = chosen;
|
||||
});
|
||||
var ms = function (v) { return v ? esc(duration(v)) : ''; };
|
||||
$('optionsTable').querySelector('tbody').innerHTML = d.combinations.length ? d.combinations.map(function (c) {
|
||||
return '<tr><td><code>' + esc(c.options) + '</code></td><td>' + esc(c.runs.toLocaleString()) + '</td><td>' + esc(c.models.toLocaleString()) + '</td><td>' + ms(c.ms) +
|
||||
'</td><td>' + ms(c.cpuMs) + '</td><td>' + ms(c.hsrMs) + '</td><td>' + ms(c.aoMs) + '</td><td>' + ms(c.iconMs) + '</td><td>' + esc(c.bricks) + '</td><td title="' +
|
||||
esc(c.trianglesBefore.toLocaleString()) + ' before, ' + esc(c.triangles.toLocaleString()) + ' after, on average">' + esc((c.removed * 100).toFixed(1)) + '%</td></tr>';
|
||||
}).join('') : '<tr><td colspan="10" class="text-body-secondary">No model made since the options were recorded.</td></tr>';
|
||||
}).catch(function (e) {
|
||||
$('optionsTable').querySelector('tbody').innerHTML = '<tr><td colspan="10" class="text-danger">Could not load the options: ' + esc(e.message) + '</td></tr>';
|
||||
});
|
||||
}
|
||||
loadOptions();
|
||||
$('optionsCard').addEventListener('toggle', function () { if (this.open) loadOptions(); });
|
||||
|
||||
if (window.Live) Live.on('ugc', load);
|
||||
|
||||
var linked = readUrl();
|
||||
|
||||
@@ -32,6 +32,19 @@
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="card mb-3" id="optionsCard">
|
||||
<summary class="card-header py-2 small fw-semibold">Processing options compared</summary>
|
||||
<div class="card-body py-2 small">
|
||||
<p class="text-body-secondary mb-2">The ways of making models to compare: the ray tracer (built in, Embree on the CPU, HIPRT on the GPU), how
|
||||
hidden faces are found (LU Toolbox's paths, or fast renders from around the model) and denoising of icons. The settings pick the
|
||||
defaults; <b>Make again</b> can use others for a make (the options next to it, or <code>/reprocessproperty embree fast</code> in game).
|
||||
Every make is counted under what made it: the averages per make below, each model's in the List view's Options column.</p>
|
||||
<div class="table-responsive"><table class="table table-sm align-middle mb-0" id="optionsTable">
|
||||
<thead><tr><th>Options</th><th>Makes</th><th>Models</th><th>Took</th><th>CPU</th><th>Hidden faces</th><th>Occlusion</th><th>Icon</th><th>Bricks</th><th>Triangles removed</th></tr></thead>
|
||||
<tbody><tr><td colspan="10" class="text-body-secondary">Loading…</td></tr></tbody></table></div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="card mb-3 d-none" id="cacheCard">
|
||||
<summary class="card-header py-2 small fw-semibold">Stored files: delete and purge</summary>
|
||||
<div class="card-body py-2 small">
|
||||
@@ -67,7 +80,12 @@
|
||||
<button type="button" class="btn btn-outline-secondary active" data-view="gallery">Icons</button>
|
||||
<button type="button" class="btn btn-outline-secondary" data-view="list">List</button>
|
||||
</div>
|
||||
<div class="ms-auto d-none" id="manageButtons">
|
||||
<div class="ms-auto d-none d-flex flex-wrap gap-1 align-items-center" id="manageButtons">
|
||||
<span class="d-flex gap-1" id="remakeOptions" title="How Make again makes models (the settings' way unless picked here)">
|
||||
<select class="form-select form-select-sm w-auto" id="optRays" aria-label="Ray tracer for Make again"><option value="">Ray tracer: settings</option></select>
|
||||
<select class="form-select form-select-sm w-auto" id="optHsr" aria-label="Hidden faces for Make again"><option value="">Hidden faces: settings</option></select>
|
||||
<select class="form-select form-select-sm w-auto" id="optDenoise" aria-label="Denoise for Make again"><option value="">Denoise: settings</option></select>
|
||||
</span>
|
||||
<button type="button" class="btn btn-sm btn-outline-warning" id="retryFailed">Try the failed ones again</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" id="remakeAll">Make everything again</button>
|
||||
</div>
|
||||
@@ -76,7 +94,7 @@
|
||||
<div id="gallery" class="ugc-gallery mb-2"></div>
|
||||
<div class="card d-none" id="listCard"><div class="card-body p-2">
|
||||
<div id="modelTableBox"><table class="table table-sm align-middle mb-0 w-100 table-stack" id="ugcModelTable">
|
||||
<thead><tr><th>Icon</th><th>ID</th><th>Owner</th><th>State</th><th>Made</th><th>Took</th><th>CPU</th><th>RAM (est.)</th><th>Saved</th><th>Size</th><th>File</th><th>Where</th><th></th></tr></thead></table></div>
|
||||
<thead><tr><th>Icon</th><th>ID</th><th>Owner</th><th>State</th><th>Made</th><th>Took</th><th>CPU</th><th>RAM (est.)</th><th>Options</th><th>Saved</th><th>Size</th><th>File</th><th>Where</th><th></th></tr></thead></table></div>
|
||||
<div id="assemblyTableBox" class="d-none"><table class="table table-sm align-middle mb-0 w-100 table-stack" id="ugcAssemblyTable">
|
||||
<thead><tr><th>Icon</th><th>ID</th><th>Owner</th><th>State</th><th>Made</th><th>Took</th><th>CPU</th><th>RAM (est.)</th><th>Size</th><th>File</th><th>Where</th><th></th></tr></thead></table></div>
|
||||
</div></div>
|
||||
|
||||
Reference in New Issue
Block a user