载入中...
搜索中...
未找到
PhysicsSerialization.cpp
浏览该文件的文档.
2
3#include <utility>
4
5namespace eve::physics_editing {
6namespace {
7
8const EditorValue* field(const EditorValue& value, const char* key) {
9 const auto* object = value.getIf<EditorValue::Object>();
10 if (!object) return nullptr;
11 const auto found = object->find(key);
12 return found == object->end() ? nullptr : &found->second;
13}
14
15} // namespace
16
19 for (const auto& [path, value] : values_) properties[path] = value;
21 root["schemaVersion"] = 1;
22 root["dimensions"] = dimensions_;
23 root["properties"] = EditorValue(std::move(properties));
24 return EditorValue(std::move(root));
25}
26
28 const EditorValue* versionValue = field(snapshot, "schemaVersion");
29 const EditorValue* dimensionsValue = field(snapshot, "dimensions");
30 const EditorValue* propertiesValue = field(snapshot, "properties");
31 const auto* version = versionValue ? versionValue->getIf<int64_t>() : nullptr;
32 const auto* dimensions = dimensionsValue ? dimensionsValue->getIf<int64_t>() : nullptr;
33 const auto* properties = propertiesValue ? propertiesValue->getIf<EditorValue::Object>() : nullptr;
34 if (!version || *version != 1 || !dimensions || *dimensions != dimensions_ || !properties)
35 return eve::editing::failed<void>(EditorStatus::Rejected, RuleId("editor.physics.snapshot-format"),
36 "Collider snapshot version or dimensionality is incompatible");
37 auto candidate = defaults();
38 const PropertySchema schemaValue = colliderSchema();
39 for (const auto& [path, value] : *properties) {
40 auto descriptor = schemaValue.find(PropertyPath(path));
41 if (!descriptor)
42 return eve::editing::failed<void>(EditorStatus::Unsupported, RuleId("editor.physics.snapshot-property"),
43 "Collider snapshot contains unknown property: " + path);
44 auto valid = validateAssignment(*descriptor, value);
45 if (!valid.ok()) return valid;
46 candidate[path] = value;
47 }
48 values_ = std::move(candidate);
51 return eve::editing::applied<void>();
52}
53
54std::vector<EditorDiagnostic> PhysicsColliderTarget::validate() const {
55 std::vector<EditorDiagnostic> diagnostics;
56 const auto text = [&](const char* path) -> std::string {
57 const auto found = values_.find(path);
58 const auto* value = found == values_.end() ? nullptr : found->second.getIf<std::string>();
59 return value ? *value : std::string{};
60 };
61 const auto number = [&](const char* path) -> double {
62 const auto found = values_.find(path);
63 const auto* value = found == values_.end() ? nullptr : found->second.getIf<double>();
64 return value ? *value : 0.0;
65 };
66 const std::string shape = text("shape.kind");
67 if ((shape == "convex-hull" || shape == "triangle-mesh" || shape == "height-field" || shape == "polygon" ||
68 shape == "chain") &&
69 text("shape.asset").empty())
70 diagnostics.push_back(eve::editing::ruleDiagnostic(
71 eve::DiagnosticCode::PreconditionViolation, RuleId("editor.physics.shape-asset-required"),
72 DiagnosticSeverity::Error, "Selected collider kind requires a shape asset"));
73 if ((shape == "sphere" || shape == "circle" || shape == "capsule") && number("shape.radius") <= 0.0)
74 diagnostics.push_back(eve::editing::ruleDiagnostic(
75 eve::DiagnosticCode::PreconditionViolation, RuleId("editor.physics.radius-required"),
76 DiagnosticSeverity::Error, "Round collider requires a positive radius"));
77 if (shape == "capsule" && number("shape.capsule-height") < 2.0 * number("shape.radius"))
78 diagnostics.push_back(eve::editing::ruleDiagnostic(
79 eve::DiagnosticCode::PreconditionViolation, RuleId("editor.physics.capsule-height"),
80 DiagnosticSeverity::Warning, "Capsule height is smaller than its diameter"));
81 if (text("body.type") == "dynamic" && number("material.density") == 0.0)
82 diagnostics.push_back(eve::editing::ruleDiagnostic(
83 eve::DiagnosticCode::PreconditionViolation, RuleId("editor.physics.dynamic-zero-density"),
84 DiagnosticSeverity::Warning, "Dynamic collider has zero density"));
85 if ((shape == "triangle-mesh" || shape == "height-field") && text("body.type") != "static")
86 diagnostics.push_back(eve::editing::ruleDiagnostic(
87 eve::DiagnosticCode::PreconditionViolation, RuleId("editor.physics.static-complex-shape"),
88 DiagnosticSeverity::Error, "Triangle-mesh and height-field colliders require a static body"));
89 return diagnostics;
90}
91
92} // namespace eve::physics_editing
double value
int root
Definition AnimSmr.cpp:119
std::string descriptor
std::uint32_t key
ShaderImageInput shape
std::string text
std::map< std::string, PropertyRule > properties
bool valid
std::string path
Definition PlayHost.cpp:110
double number
bool found
Move-only operation result carrying either a value or Status.
Definition Result.h:155
void bumpRevision()
Advance the revision without touching the dirty region.
virtual void clearDirtyRegion()=0
Clears dirty region.
Dotted property path (layout.size) compared and persisted as text.
Definition EditingIds.h:78
Deterministic owning value tree shared by authoring hosts.
std::map< std::string, Value > Object
const T * getIf() const
Return an immediately borrowed typed value.
EditorValue snapshotValue() const
Capture deterministic collider content for asset/scene persistence.
Result< void > loadSnapshot(const EditorValue &snapshot)
Atomically load a versioned collider snapshot.
std::vector< EditorDiagnostic > validate() const
Report cross-property shape/body problems for inspector overlays.
Diagnostic ruleDiagnostic(eve::DiagnosticCode code, RuleId rule, DiagnosticSeverity severity, std::string message)
Build a common diagnostic carrying an open editing rule identity.
editing::Value EditorValue
const EditorValue * field(const EditorValue &value, const char *name)
EVENGINE_API_PLATFORM public API.
PropertyDescriptorLookup find(const PropertyPath &path) const
Finds find.