载入中...
搜索中...
未找到
EditorMaterialPreview.cpp
浏览该文件的文档.
2
3#include <iterator>
4#include <set>
5#include <utility>
6
7namespace eve::editor {
8namespace {
9
10std::vector<EditorDiagnostic> validateSettings(const MaterialPreviewSettings& settings) {
11 std::vector<EditorDiagnostic> diagnostics;
12 const auto error = [&](const char* rule, std::string message) {
13 diagnostics.push_back(eve::editing::ruleDiagnostic(
14 DiagnosticCode::PreconditionViolation, RuleId(rule), DiagnosticSeverity::Error,
15 std::move(message)));
16 };
17 static const std::set<std::string> geometries{"sphere", "cube", "plane", "custom"};
18 if (!geometries.contains(settings.geometry))
19 error("editor.material.preview-geometry",
20 "Material preview geometry is unsupported: " + settings.geometry);
21 if (settings.geometry == "custom" && settings.customMeshAsset.empty())
22 error("editor.material.preview-mesh-required", "Custom material preview requires a mesh asset");
23 if (settings.width < 16 || settings.height < 16 || settings.width > 4096 || settings.height > 4096)
24 error("editor.material.preview-resolution",
25 "Material preview resolution must be between 16 and 4096");
26 if (settings.distance <= 0.0)
27 error("editor.material.preview-distance", "Material preview camera distance must be positive");
28 return diagnostics;
29}
30
31} // namespace
32
36 IMaterialPreviewRenderer& renderer) {
37 if (document.empty())
38 return eve::editing::failed<TaskId>(EditorStatus::Rejected, RuleId("editor.material.preview-document"),
39 "Material preview document id is required");
40 auto diagnostics = material.validate();
41 auto settingsDiagnostics = validateSettings(settings);
42 diagnostics.insert(diagnostics.end(), std::make_move_iterator(settingsDiagnostics.begin()),
43 std::make_move_iterator(settingsDiagnostics.end()));
44 for (const EditorDiagnostic& diagnostic : diagnostics)
45 if (diagnostic.severity() == DiagnosticSeverity::Error)
47 Status(EditorStatus::Rejected, std::move(diagnostics)));
48 const TaskId task("material-preview-" + std::to_string(++sequence_));
50 request.sceneId = StableId(task.value() + ":isolated-scene");
51 request.document = document;
52 request.documentRevision = material.revision();
53 request.material = material.snapshotValue();
54 request.settings = std::move(settings);
55 MaterialPreviewRenderResult rendered = renderer.render(request);
56 rendered.diagnostics.insert(rendered.diagnostics.begin(), diagnostics.begin(), diagnostics.end());
57 if (rendered.status == EditorStatus::Applied && rendered.artifact.empty()) {
58 rendered.status = EditorStatus::Failed;
60 DiagnosticCode::Failed, RuleId("editor.material.preview-artifact-required"),
61 DiagnosticSeverity::Error, "Preview renderer succeeded without an artifact"));
62 }
63 tasks_.emplace(task, Task{document, request.documentRevision, std::move(rendered)});
64 return eve::editing::applied<TaskId>(task);
65}
66
68 const auto found = tasks_.find(task);
69 if (found == tasks_.end())
70 return eve::editing::failed<MaterialPreviewRenderResult>(EditorStatus::NotFound,
71 RuleId("editor.material.preview-task-not-found"),
72 "Material preview task was not found");
73 return eve::editing::applied<MaterialPreviewRenderResult>(found->second.result);
74}
75
77 const TaskId& task) {
78 const auto found = tasks_.find(task);
79 if (found == tasks_.end())
80 return eve::editing::failed<void>(EditorStatus::NotFound, RuleId("editor.material.preview-task-not-found"),
81 "Material preview task was not found");
82 if (found->second.document != document)
83 return eve::editing::failed<void>(EditorStatus::Rejected, RuleId("editor.material.preview-document-mismatch"),
84 "Material preview belongs to another document");
85 if (found->second.revision != currentRevision)
86 return eve::editing::failed<void>(EditorStatus::Conflict, RuleId("editor.material.preview-stale"),
87 "Material changed after the preview was rendered");
88 if (found->second.result.status != EditorStatus::Applied || found->second.result.artifact.empty()) {
89 const EditorStatus status = found->second.result.status == EditorStatus::Applied
90 ? EditorStatus::Failed
91 : found->second.result.status;
92 return Result<void>::failure(Status(status, found->second.result.diagnostics));
93 }
94 published_[document] = found->second.result.artifact;
95 return eve::editing::applied<void>();
96}
97
98std::string MaterialPreviewService::publishedArtifact(const DocumentId& document) const {
99 const auto found = published_.find(document);
100 return found == published_.end() ? std::string{} : found->second;
101}
102
103} // namespace eve::editor
std::string message
const GltfImportRequest & request
wgpu::PopErrorScopeStatus status
std::string error
Definition Package.cpp:60
Material * material
bool found
TerrainThermalSettings settings
A structured explanation of a failed, degraded, or noteworthy result.
Definition Diagnostic.h:94
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Structured status and zero or more diagnostics for an operation.
Definition Status.h:68
UUID-backed identifier adapter for legacy textual boundaries.
Definition Identity.h:314
const std::string & value() const noexcept
Returns the exact legacy or canonical compatibility spelling.
Definition Identity.h:362
bool empty() const noexcept
True when no compatibility spelling has been assigned.
Definition Identity.h:374
Host boundary that owns creation and teardown of an isolated preview scene.
virtual MaterialPreviewRenderResult render(const MaterialPreviewRenderRequest &request)=0
Render one immutable request without reading or mutating the live game scene.
std::string publishedArtifact(const DocumentId &document) const
Return the most recently published artifact for a document.
Result< MaterialPreviewRenderResult > result(const TaskId &task) const
Return one immutable render result.
Result< TaskId > render(const DocumentId &document, const MaterialDocumentTarget &material, MaterialPreviewSettings settings, IMaterialPreviewRenderer &renderer)
Validate and render a material snapshot in a unique isolated scene.
Result< void > publish(const DocumentId &document, Revision currentRevision, const TaskId &task)
Publish only a successful result matching the current document revision.
UI-neutral, serializable material authoring target.
Diagnostic ruleDiagnostic(eve::DiagnosticCode code, RuleId rule, DiagnosticSeverity severity, std::string message)
Build a common diagnostic carrying an open editing rule identity.
eve::editing::StableId StableId
Definition EditorIds.h:36
eve::editing::RuleId RuleId
Definition EditorIds.h:32
eve::editing::Revision Revision
StatusCode
Stable outcome category for an operation.
Definition Status.h:27
Immutable request passed to a renderer-owned isolated preview scene.
Renderer output referenced by a stable artifact rather than GPU pointers.
std::vector< EditorDiagnostic > diagnostics
Camera, mesh and environment settings for an isolated material preview.