载入中...
搜索中...
未找到
RuntimeGenerationAsset.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <iomanip>
6#include <limits>
7#include <sstream>
8
9namespace eve::procgen {
10
11std::string RuntimeGeneration::serializeCell(int level, int x, int z) const {
12 const auto found = cells_.find({level, x, z});
13 if (found == cells_.end() || found->second.state != State::Active) return {};
14 std::ostringstream out;
15 out << std::setprecision(std::numeric_limits<float>::max_digits10);
16 out << "EVPCG_CELL 3 " << worldSeed_ << ' ' << level << ' ' << x << ' ' << z << ' ' << found->second.revision << ' '
17 << levels_[size_t(level)].cellSize << '\n';
18 out << "POINTS " << found->second.output.getCount() << '\n';
19 const auto& points = found->second.output.points();
20 for (size_t index = 0; index < points.size(); ++index) {
21 const auto& point = points[index];
22 out << "POINT " << point.x << ' ' << point.y << ' ' << point.z << ' ' << point.normalX << ' ' << point.normalY
23 << ' ' << point.normalZ << ' ' << point.pitch << ' ' << point.yaw << ' ' << point.roll << ' '
24 << point.scaleX << ' ' << point.scaleY << ' ' << point.scaleZ << ' ' << point.density << ' ' << point.seed
25 << ' ' << point.id
26 << ' ' << point.boundsMinX << ' ' << point.boundsMinY << ' ' << point.boundsMinZ << ' ' << point.boundsMaxX
27 << ' ' << point.boundsMaxY << ' ' << point.boundsMaxZ << ' ' << point.colorR << ' ' << point.colorG << ' '
28 << point.colorB << ' ' << point.colorA << ' ' << point.steepness << '\n';
29 std::vector<std::string> names;
30 names.reserve(found->second.output.attributes().columnCount());
31 for (size_t column = 0; column < found->second.output.attributes().columnCount(); ++column) {
32 const std::string name(found->second.output.attributes().columnName(column));
33 if (found->second.output.attributes().has(index, name)) names.push_back(name);
34 }
35 std::sort(names.begin(), names.end());
36 for (const auto& name : names) {
37 switch (*found->second.output.attributes().typeOf(name)) {
39 out << "FLOAT " << index << ' ' << std::quoted(name) << ' '
40 << *found->second.output.attributes().getFloat(index, name) << '\n';
41 break;
43 out << "INT " << index << ' ' << std::quoted(name) << ' '
44 << *found->second.output.attributes().getInt(index, name) << '\n';
45 break;
47 out << "BOOL " << index << ' ' << std::quoted(name) << ' '
48 << (*found->second.output.attributes().getBool(index, name) ? 1 : 0) << '\n';
49 break;
51 const auto value = *found->second.output.attributes().getVector(index, name);
52 out << "VECTOR " << index << ' ' << std::quoted(name) << ' ' << value.x << ' ' << value.y << ' '
53 << value.z << '\n';
54 break;
55 }
57 out << "STRING " << index << ' ' << std::quoted(name) << ' '
58 << std::quoted(*found->second.output.attributes().getString(index, name)) << '\n';
59 break;
60 }
61 }
62 }
63 out << "END\n";
64 return out.str();
65}
66
67bool RuntimeGeneration::deserializeCell(const std::string& definition) {
68 constexpr int maxPersistedPoints = 10000000;
69 std::istringstream input(definition);
70 std::string magic;
71 int version = 0;
72 uint32_t seed = 0;
73 CellKey key;
74 uint64_t revision = 0;
75 float cellSize = 0.f;
76 if (!(input >> magic >> version >> seed >> key.level >> key.x >> key.z >> revision >> cellSize) ||
77 magic != "EVPCG_CELL" || (version != 1 && version != 2 && version != 3) || seed != worldSeed_ || revision == 0 ||
78 key.level < 0 || key.level >= int(levels_.size()) || !std::isfinite(cellSize) ||
79 cellSize != levels_[size_t(key.level)].cellSize)
80 return false;
81 std::string record;
82 int pointCount = 0;
83 if (!(input >> record >> pointCount) || record != "POINTS" || pointCount < 0 || pointCount > maxPersistedPoints)
84 return false;
85
86 PointSet restored;
87 for (int index = 0; index < pointCount; ++index) {
89 if (!(input >> record) || record != "POINT") return false;
90 if (version == 1) {
91 if (!(input >> point.x >> point.y >> point.z >> point.normalX >> point.normalY >> point.normalZ >>
92 point.yaw >> point.scaleX >> point.scaleY >> point.scaleZ >> point.density >> point.seed))
93 return false;
94 } else {
95 if (!(input >> point.x >> point.y >> point.z >> point.normalX >> point.normalY >> point.normalZ >>
96 point.pitch >> point.yaw >> point.roll >> point.scaleX >> point.scaleY >> point.scaleZ >>
97 point.density >> point.seed))
98 return false;
99 if (version == 3 && !(input >> point.id)) return false;
100 if (!(input >> point.boundsMinX >> point.boundsMinY >> point.boundsMinZ >> point.boundsMaxX >>
101 point.boundsMaxY >> point.boundsMaxZ >> point.colorR >> point.colorG >> point.colorB >>
102 point.colorA >> point.steepness))
103 return false;
104 }
105 if (!std::isfinite(point.x) || !std::isfinite(point.y) || !std::isfinite(point.z) ||
106 !std::isfinite(point.normalX) || !std::isfinite(point.normalY) || !std::isfinite(point.normalZ) ||
107 !std::isfinite(point.pitch) || !std::isfinite(point.yaw) || !std::isfinite(point.roll) ||
108 !std::isfinite(point.scaleX) || !std::isfinite(point.scaleY) || !std::isfinite(point.scaleZ) ||
109 !std::isfinite(point.density) || !std::isfinite(point.boundsMinX) || !std::isfinite(point.boundsMinY) ||
110 !std::isfinite(point.boundsMinZ) || !std::isfinite(point.boundsMaxX) || !std::isfinite(point.boundsMaxY) ||
111 !std::isfinite(point.boundsMaxZ) || !std::isfinite(point.colorR) || !std::isfinite(point.colorG) ||
112 !std::isfinite(point.colorB) || !std::isfinite(point.colorA) || !std::isfinite(point.steepness))
113 return false;
114 const int restoredIndex = restored.appendPoint(std::move(point));
115 while (true) {
116 const std::streampos position = input.tellg();
117 if (!(input >> record)) return false;
118 if (record == "FLOAT") {
119 int target = -1;
120 std::string name;
121 float value = 0.f;
122 if (!(input >> target >> std::quoted(name) >> value) || target != index || name.empty() ||
123 !std::isfinite(value))
124 return false;
125 if (!restored.trySetFloatAttribute(restoredIndex, name, value).ok()) return false;
126 } else if (record == "INT") {
127 int target = -1;
128 std::string name;
129 std::int64_t value = 0;
130 if (!(input >> target >> std::quoted(name) >> value) || target != index || name.empty()) return false;
131 if (!restored.trySetIntAttribute(restoredIndex, name, value).ok()) return false;
132 } else if (record == "BOOL") {
133 int target = -1;
134 std::string name;
135 int value = -1;
136 if (!(input >> target >> std::quoted(name) >> value) || target != index || name.empty() ||
137 (value != 0 && value != 1))
138 return false;
139 if (!restored.trySetBoolAttribute(restoredIndex, name, value != 0).ok()) return false;
140 } else if (record == "VECTOR") {
141 int target = -1;
142 std::string name;
144 if (!(input >> target >> std::quoted(name) >> value.x >> value.y >> value.z) || target != index ||
145 name.empty() || !std::isfinite(value.x) || !std::isfinite(value.y) || !std::isfinite(value.z))
146 return false;
147 if (!restored.trySetVectorAttribute(restoredIndex, name, value.x, value.y, value.z).ok()) return false;
148 } else if (record == "STRING") {
149 int target = -1;
150 std::string name;
151 std::string value;
152 if (!(input >> target >> std::quoted(name) >> std::quoted(value)) || target != index || name.empty())
153 return false;
154 if (!restored.trySetStringAttribute(restoredIndex, name, value).ok()) return false;
155 } else {
156 input.seekg(position);
157 break;
158 }
159 }
160 }
161 if (!(input >> record) || record != "END") return false;
162 std::string trailing;
163 if (input >> trailing) return false;
164
165 const auto existing = cells_.find(key);
166 const bool alreadyResident = existing != cells_.end() && (existing->second.state == State::Active ||
167 existing->second.state == State::Generating);
168 if (!alreadyResident && maxActiveCells_ > 0 && getActiveCellCount() + getGeneratingCount() >= maxActiveCells_)
169 return false;
170 const int restoredPoints = restored.getCount();
171 const int replacedPoints = existing != cells_.end() ? existing->second.output.getCount() : 0;
172 if ((maxPointsPerCell_ > 0 && restoredPoints > maxPointsPerCell_) ||
173 (maxResidentPoints_ > 0 && getResidentPointCount() - replacedPoints > maxResidentPoints_ - restoredPoints)) {
174 ++rejectedOutputCount_;
175 return false;
176 }
177 generateQueue_.erase(std::remove(generateQueue_.begin(), generateQueue_.end(), key), generateQueue_.end());
178 cleanupQueue_.erase(std::remove(cleanupQueue_.begin(), cleanupQueue_.end(), key), cleanupQueue_.end());
179 Cell& cell = cells_[key];
180 transitionCellState(cell, State::Active);
181 cell.revision = revision;
182 cell.ticket = ++nextTicket_;
183 cell.failures = 0;
184 cell.trimmed = false;
185 cell.output = std::move(restored);
186 return true;
187}
188
189} // namespace eve::procgen
LogicalId target
double value
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
int column
EvpackChunkInput input
Definition Evpack.cpp:170
std::uint32_t key
std::array< float, 3 > position
std::string name
int level
std::uint64_t revision
std::uint32_t seed
Definition PointSet.cpp:807
std::shared_ptr< const std::vector< glm::vec2 > > points
bool found
Cell cell
uint32_t index
glm::vec3 point
bool ok() const noexcept
Whether this result represents a non-failure outcome.
Definition Result.h:480
Script-friendly collection of attributed 3D samples.
Definition PointSet.h:59
Result< void > trySetStringAttribute(int index, const std::string &name, const std::string &value)
Canonical checked string metadata write.
Definition PointSet.cpp:421
Result< void > trySetBoolAttribute(int index, const std::string &name, bool value)
Canonical checked Boolean metadata write.
Definition PointSet.cpp:371
Result< void > trySetVectorAttribute(int index, const std::string &name, float x, float y, float z)
Canonical checked vector metadata write.
Definition PointSet.cpp:391
int appendPoint(ProcgenPoint point)
Append a point with an empty attribute row and return its row index.
Definition PointSet.cpp:62
Result< void > trySetIntAttribute(int index, const std::string &name, std::int64_t value)
Canonical checked signed integer metadata write.
Definition PointSet.cpp:351
int getCount() const
Returns the count.
Definition PointSet.cpp:48
Result< void > trySetFloatAttribute(int index, const std::string &name, float value)
Canonical checked float metadata write.
Definition PointSet.cpp:331
bool deserializeCell(const std::string &definition)
Atomically restore one cell produced by serializeCell for this world seed.
int getActiveCellCount() const
Returns the active cell count.
int getGeneratingCount() const
Returns the generating count.
std::string serializeCell(int level, int x, int z) const
Serialize one active cell cache entry in a deterministic versioned format.
int getResidentPointCount() const
Return points retained by active or not-yet-acknowledged cleanup cells.
Compact three-component value used by typed procedural metadata.
One deterministic sample used by script-first procedural pipelines.
Definition PointSet.h:17