载入中...
搜索中...
未找到
RoadNetworkEditApply.cpp
浏览该文件的文档.
2#include "procgen/editing/RoadNetworkEditTargetInternal.inc"
3
4#include <algorithm>
5#include <cmath>
6#include <utility>
7
8namespace eve::procgen_editing {
9using namespace detail;
10
12 if (operation.target != targetId())
13 return reject<void>("editor.road.target", "Road operation targets another network");
14 if (operation.type == kMoveNode) {
15 std::uint32_t nodeId = 0;
16 float x = 0.f, y = 0.f, z = 0.f;
17 if (!readId(operation.payload, "id", nodeId) || !readNumber(operation.payload, "x", x) ||
18 !readNumber(operation.payload, "y", y) || !readNumber(operation.payload, "z", z))
19 return reject<void>("editor.road.node-payload", "Road node payload is invalid");
20 auto moved = network_->setNodePosition(nodeId, x, y, z);
21 if (!moved.ok()) return roadFailure<void>(moved.status());
22 } else if (operation.type == kSetNodeRadius) {
23 std::uint32_t nodeId = 0;
24 float junctionRadius = 0.f;
25 if (!decodeNodeRadius(operation.payload, nodeId, junctionRadius))
26 return reject<void>("editor.road.node-radius-payload", "Road node radius payload is invalid");
27 auto changed = network_->setNodeJunctionRadius(nodeId, junctionRadius);
28 if (!changed.ok()) return roadFailure<void>(changed.status());
29 } else if (operation.type == kSetNodeControl) {
30 std::uint32_t nodeId = 0;
32 if (!decodeNodeControl(operation.payload, nodeId, control))
33 return reject<void>("editor.road.node-control-payload", "Road node control payload is invalid");
34 auto changed = network_->setNodeJunctionControl(nodeId, control);
35 if (!changed.ok()) return roadFailure<void>(changed.status());
36 } else if (operation.type == kMergeNodes || operation.type == kMergeNodesAndConnect) {
37 std::uint32_t keepNodeId = 0, removeNodeId = 0;
38 float maxDistance = 0.f;
39 if (!decodeMergeNodes(operation.payload, keepNodeId, removeNodeId, maxDistance))
40 return reject<void>("editor.road.merge-payload", "Road node merge payload is invalid");
41 auto candidate = *network_;
42 auto merged = candidate.mergeNodes(keepNodeId, removeNodeId, maxDistance);
43 if (!merged.ok()) return roadFailure<void>(merged.status());
44 if (operation.type == kMergeNodesAndConnect) {
45 auto connected = candidate.connectAllTurns(keepNodeId);
46 if (!connected.ok()) return roadFailure<void>(connected.status());
47 }
48 auto valid = candidate.validate();
49 if (!valid.ok()) return roadFailure<void>(valid.status());
50 *network_ = std::move(candidate);
51 } else if (operation.type == kUnmergeNodes) {
52 procgen::road::RoadNode removedNode;
53 std::vector<procgen::road::RoadEdge> affectedEdges;
54 std::vector<procgen::road::RoadLaneConnection> affectedLinks;
55 std::vector<procgen::road::RoadLaneConnection> affectedBlockedLinks;
56 if (!decodeUnmergeNodes(operation.payload, removedNode, affectedEdges, affectedLinks,
57 affectedBlockedLinks))
58 return reject<void>("editor.road.unmerge-payload", "Road node unmerge payload is invalid");
59 auto candidate = *network_;
60 auto restoredNode = candidate.restoreNode(removedNode);
61 if (!restoredNode.ok()) return roadFailure<void>(restoredNode.status());
62 for (const auto& edge : affectedEdges) {
63 auto removedEdge = candidate.removeEdge(edge.id);
64 if (!removedEdge.ok()) return roadFailure<void>(removedEdge.status());
65 auto restoredEdge = candidate.restoreEdge(edge);
66 if (!restoredEdge.ok()) return roadFailure<void>(restoredEdge.status());
67 }
68 for (const auto& link : affectedLinks) {
69 auto restoredLink = candidate.addLaneLink(link);
70 if (!restoredLink.ok()) return roadFailure<void>(restoredLink.status());
71 }
72 for (const auto& link : affectedBlockedLinks) {
73 auto blocked = candidate.blockLaneLink(link);
74 if (!blocked.ok()) return roadFailure<void>(blocked.status());
75 }
76 auto valid = candidate.validate();
77 if (!valid.ok()) return roadFailure<void>(valid.status());
78 *network_ = std::move(candidate);
79 } else if (operation.type == kSetEdgePoints) {
80 std::uint32_t edgeId = 0;
81 std::vector<procgen::road::RoadControlPoint> points;
82 if (!decodeEdge(operation.payload, edgeId, points))
83 return reject<void>("editor.road.edge-payload", "Road edge payload is invalid");
84 auto changed = network_->setEdgeControlPoints(edgeId, std::move(points));
85 if (!changed.ok()) return roadFailure<void>(changed.status());
86 } else if (operation.type == kSetEdgeStyle) {
87 std::uint32_t edgeId = 0;
89 if (!decodeStyle(operation.payload, edgeId, style))
90 return reject<void>("editor.road.style-payload", "Road style payload is invalid");
91 auto changed = network_->setEdgeStyle(edgeId, style);
92 if (!changed.ok()) return roadFailure<void>(changed.status());
93 } else if (operation.type == kSetEdgeLanes) {
94 std::uint32_t edgeId = 0;
95 int lanesForward = 0, lanesBackward = 0;
96 std::vector<procgen::road::RoadLaneConnection> restoreLinks;
97 std::vector<procgen::road::RoadLaneConnection> restoreBlockedLinks;
98 if (!decodeLaneCounts(operation.payload, edgeId, lanesForward, lanesBackward, restoreLinks,
99 restoreBlockedLinks))
100 return reject<void>("editor.road.lanes-payload", "Road lane-count payload is invalid");
101 auto candidate = *network_;
102 auto changed = candidate.setEdgeLaneCounts(edgeId, lanesForward, lanesBackward);
103 if (!changed.ok()) return roadFailure<void>(changed.status());
104 for (const auto& link : restoreLinks) {
105 auto restored = candidate.addLaneLink(link);
106 if (!restored.ok()) return roadFailure<void>(restored.status());
107 }
108 for (const auto& link : restoreBlockedLinks) {
109 auto blocked = candidate.blockLaneLink(link);
110 if (!blocked.ok()) return roadFailure<void>(blocked.status());
111 }
112 *network_ = std::move(candidate);
113 } else if (operation.type == kReverseEdge) {
114 std::uint32_t edgeId = 0;
115 if (!readId(operation.payload, "id", edgeId))
116 return reject<void>("editor.road.reverse-payload", "Road edge reverse payload is invalid");
117 auto reversed = network_->reverseEdge(edgeId);
118 if (!reversed.ok()) return roadFailure<void>(reversed.status());
119 } else if (operation.type == kReconnectEdgeEndpoint) {
120 std::uint32_t edgeId = 0, nodeId = 0;
121 bool fromEndpoint = false;
122 std::vector<procgen::road::RoadLaneConnection> restoreLinks;
123 std::vector<procgen::road::RoadLaneConnection> restoreBlockedLinks;
124 if (!decodeReconnectEndpoint(operation.payload, edgeId, fromEndpoint, nodeId, restoreLinks,
125 restoreBlockedLinks))
126 return reject<void>("editor.road.reconnect-payload", "Road endpoint reconnect payload is invalid");
127 auto candidate = *network_;
128 auto changed = candidate.reconnectEdgeEndpoint(edgeId, fromEndpoint, nodeId);
129 if (!changed.ok()) return roadFailure<void>(changed.status());
130 for (const auto& link : restoreLinks) {
131 auto restored = candidate.addLaneLink(link);
132 if (!restored.ok()) return roadFailure<void>(restored.status());
133 }
134 for (const auto& link : restoreBlockedLinks) {
135 auto restored = candidate.blockLaneLink(link);
136 if (!restored.ok()) return roadFailure<void>(restored.status());
137 }
138 auto valid = candidate.validate();
139 if (!valid.ok()) return roadFailure<void>(valid.status());
140 *network_ = std::move(candidate);
141 } else if (operation.type == kDetachEdgeEndpoint) {
142 std::uint32_t edgeId = 0, nodeId = 0;
143 bool fromEndpoint = false;
144 if (!decodeDetachEndpoint(operation.payload, edgeId, fromEndpoint, nodeId))
145 return reject<void>("editor.road.detach-payload", "Road endpoint detach payload is invalid");
146 auto candidate = *network_;
147 auto detached = candidate.detachEdgeEndpoint(edgeId, fromEndpoint, nodeId);
148 if (!detached.ok()) return roadFailure<void>(detached.status());
149 *network_ = std::move(candidate);
150 } else if (operation.type == kReattachEdgeEndpoint) {
151 std::uint32_t edgeId = 0, oldNodeId = 0, detachedNodeId = 0;
152 bool fromEndpoint = false;
153 std::vector<procgen::road::RoadLaneConnection> restoreLinks;
154 std::vector<procgen::road::RoadLaneConnection> restoreBlockedLinks;
155 if (!decodeReattachEndpoint(operation.payload, edgeId, fromEndpoint, oldNodeId, detachedNodeId,
156 restoreLinks, restoreBlockedLinks))
157 return reject<void>("editor.road.reattach-payload", "Road endpoint reattach payload is invalid");
158 auto candidate = *network_;
159 auto changed = candidate.reconnectEdgeEndpoint(edgeId, fromEndpoint, oldNodeId);
160 if (!changed.ok()) return roadFailure<void>(changed.status());
161 for (const auto& link : restoreLinks) {
162 auto restored = candidate.addLaneLink(link);
163 if (!restored.ok()) return roadFailure<void>(restored.status());
164 }
165 for (const auto& link : restoreBlockedLinks) {
166 auto restored = candidate.blockLaneLink(link);
167 if (!restored.ok()) return roadFailure<void>(restored.status());
168 }
169 auto removed = candidate.removeNode(detachedNodeId);
170 if (!removed.ok()) return roadFailure<void>(removed.status());
171 auto valid = candidate.validate();
172 if (!valid.ok()) return roadFailure<void>(valid.status());
173 *network_ = std::move(candidate);
174 } else if (operation.type == kSplitEdge) {
175 std::uint32_t edgeId = 0, nodeId = 0, secondEdgeId = 0;
176 std::size_t controlPointIndex = 0;
177 float junctionRadius = 0.f;
178 if (!decodeSplit(operation.payload, edgeId, controlPointIndex, junctionRadius, nodeId, secondEdgeId))
179 return reject<void>("editor.road.split-payload", "Road split payload is invalid");
180 auto candidate = *network_;
181 auto split = candidate.splitEdge(edgeId, controlPointIndex, junctionRadius, nodeId, secondEdgeId);
182 if (!split.ok()) return roadFailure<void>(split.status());
183 if (split.value().nodeId != nodeId || split.value().secondEdgeId != secondEdgeId)
184 return reject<void>("editor.road.split-identity", "Road split reserved identities no longer match",
185 EditorStatus::Conflict);
186 *network_ = std::move(candidate);
187 } else if (operation.type == kSplitEdgeAtPosition) {
188 std::uint32_t edgeId = 0, nodeId = 0, secondEdgeId = 0;
190 float maxDistance = 0.f, junctionRadius = 0.f;
191 if (!decodePositionSplit(operation.payload, edgeId, position, maxDistance, junctionRadius, nodeId,
192 secondEdgeId))
193 return reject<void>("editor.road.split-position-payload", "Road position split payload is invalid");
194 auto candidate = *network_;
195 auto split = candidate.splitEdgeAtPosition(edgeId, position, maxDistance, junctionRadius, nodeId,
196 secondEdgeId);
197 if (!split.ok()) return roadFailure<void>(split.status());
198 if (split.value().nodeId != nodeId || split.value().secondEdgeId != secondEdgeId)
199 return reject<void>("editor.road.split-position-identity",
200 "Road position split reserved identities no longer match", EditorStatus::Conflict);
201 *network_ = std::move(candidate);
202 } else if (operation.type == kConnectNodeAtPosition) {
203 std::uint32_t edgeId = 0, nodeId = 0, secondEdgeId = 0;
206 float maxDistance = 0.f, junctionRadius = 0.f;
207 if (!decodeConnectAtPosition(operation.payload, edgeId, position, maxDistance, junctionRadius, nodeId,
208 secondEdgeId, branch))
209 return reject<void>("editor.road.connect-position-payload",
210 "Road branch connection payload is invalid");
211 auto candidate = *network_;
212 auto split = candidate.splitEdgeAtPosition(edgeId, position, maxDistance, junctionRadius, nodeId,
213 secondEdgeId);
214 if (!split.ok()) return roadFailure<void>(split.status());
215 auto restoredBranch = candidate.restoreEdge(branch);
216 if (!restoredBranch.ok()) return roadFailure<void>(restoredBranch.status());
217 auto connected = candidate.connectAllTurns(nodeId);
218 if (!connected.ok()) return roadFailure<void>(connected.status());
219 auto valid = candidate.validate();
220 if (!valid.ok()) return roadFailure<void>(valid.status());
221 *network_ = std::move(candidate);
222 } else if (operation.type == kDisconnectNodeAtPosition) {
224 std::vector<procgen::road::RoadLaneConnection> originalLinks;
225 std::vector<procgen::road::RoadLaneConnection> originalBlockedLinks;
226 std::uint32_t nodeId = 0, secondEdgeId = 0, branchEdgeId = 0;
227 if (!decodeDisconnectAtPosition(operation.payload, original, originalLinks, originalBlockedLinks, nodeId,
228 secondEdgeId, branchEdgeId))
229 return reject<void>("editor.road.disconnect-position-payload",
230 "Road branch disconnection payload is invalid");
231 auto candidate = *network_;
232 auto removedBranch = candidate.removeEdge(branchEdgeId);
233 if (!removedBranch.ok()) return roadFailure<void>(removedBranch.status());
234 auto removedSecond = candidate.removeEdge(secondEdgeId);
235 if (!removedSecond.ok()) return roadFailure<void>(removedSecond.status());
236 auto removedFirst = candidate.removeEdge(original.id);
237 if (!removedFirst.ok()) return roadFailure<void>(removedFirst.status());
238 auto removedNode = candidate.removeNode(nodeId);
239 if (!removedNode.ok()) return roadFailure<void>(removedNode.status());
240 auto restoredOriginal = candidate.restoreEdge(original);
241 if (!restoredOriginal.ok()) return roadFailure<void>(restoredOriginal.status());
242 for (const auto& link : originalLinks) {
243 auto restoredLink = candidate.addLaneLink(link);
244 if (!restoredLink.ok()) return roadFailure<void>(restoredLink.status());
245 }
246 for (const auto& link : originalBlockedLinks) {
247 auto blocked = candidate.blockLaneLink(link);
248 if (!blocked.ok()) return roadFailure<void>(blocked.status());
249 }
250 auto valid = candidate.validate();
251 if (!valid.ok()) return roadFailure<void>(valid.status());
252 *network_ = std::move(candidate);
253 } else if (operation.type == kConnectEdgeIntersection) {
254 std::uint32_t firstEdgeId = 0, secondEdgeId = 0, firstNodeId = 0, firstSecondEdgeId = 0;
255 std::uint32_t secondNodeId = 0, secondSecondEdgeId = 0;
257 float firstParameter = 0.f, secondParameter = 0.f;
258 float maximumHeightDelta = 0.f, junctionRadius = 0.f;
259 if (!decodeIntersectionConnect(operation.payload, firstEdgeId, secondEdgeId, firstParameter,
260 secondParameter, mergedPoint, maximumHeightDelta, junctionRadius, firstNodeId,
261 firstSecondEdgeId, secondNodeId, secondSecondEdgeId))
262 return reject<void>("editor.road.intersection-payload", "Road intersection payload is invalid");
263 auto candidate = *network_;
264 auto firstSplit = candidate.splitEdgeAtSplineParameter(firstEdgeId, firstParameter, junctionRadius,
265 firstNodeId, firstSecondEdgeId);
266 if (!firstSplit.ok()) return roadFailure<void>(firstSplit.status());
267 auto secondSplit = candidate.splitEdgeAtSplineParameter(secondEdgeId, secondParameter, junctionRadius,
268 secondNodeId, secondSecondEdgeId);
269 if (!secondSplit.ok()) return roadFailure<void>(secondSplit.status());
270 auto moved = candidate.setNodePosition(firstNodeId, mergedPoint.x, mergedPoint.y, mergedPoint.z);
271 if (!moved.ok()) return roadFailure<void>(moved.status());
272 moved = candidate.setNodePosition(secondNodeId, mergedPoint.x, mergedPoint.y, mergedPoint.z);
273 if (!moved.ok()) return roadFailure<void>(moved.status());
274 auto merged = candidate.mergeNodes(firstNodeId, secondNodeId, 1e-3f);
275 if (!merged.ok()) return roadFailure<void>(merged.status());
276 auto connected = candidate.connectAllTurns(firstNodeId);
277 if (!connected.ok()) return roadFailure<void>(connected.status());
278 auto valid = candidate.validate();
279 if (!valid.ok()) return roadFailure<void>(valid.status());
280 *network_ = std::move(candidate);
281 } else if (operation.type == kDisconnectEdgeIntersection) {
283 std::vector<procgen::road::RoadLaneConnection> originalLinks;
284 std::vector<procgen::road::RoadLaneConnection> originalBlockedLinks;
285 std::uint32_t sharedNodeId = 0, firstSecondEdgeId = 0, secondSecondEdgeId = 0;
286 if (!decodeIntersectionDisconnect(operation.payload, first, second, originalLinks, originalBlockedLinks,
287 sharedNodeId,
288 firstSecondEdgeId, secondSecondEdgeId))
289 return reject<void>("editor.road.intersection-inverse",
290 "Road intersection inverse payload is invalid");
291 auto candidate = *network_;
292 for (const auto edgeId : {firstSecondEdgeId, secondSecondEdgeId, first.id, second.id}) {
293 auto removed = candidate.removeEdge(edgeId);
294 if (!removed.ok()) return roadFailure<void>(removed.status());
295 }
296 auto removedNode = candidate.removeNode(sharedNodeId);
297 if (!removedNode.ok()) return roadFailure<void>(removedNode.status());
298 auto restoredFirst = candidate.restoreEdge(first);
299 if (!restoredFirst.ok()) return roadFailure<void>(restoredFirst.status());
300 auto restoredSecond = candidate.restoreEdge(second);
301 if (!restoredSecond.ok()) return roadFailure<void>(restoredSecond.status());
302 for (const auto& link : originalLinks) {
303 auto restored = candidate.addLaneLink(link);
304 if (!restored.ok()) return roadFailure<void>(restored.status());
305 }
306 for (const auto& link : originalBlockedLinks) {
307 auto blocked = candidate.blockLaneLink(link);
308 if (!blocked.ok()) return roadFailure<void>(blocked.status());
309 }
310 auto valid = candidate.validate();
311 if (!valid.ok()) return roadFailure<void>(valid.status());
312 *network_ = std::move(candidate);
313 } else if (operation.type == kUnsplitEdge) {
315 std::vector<procgen::road::RoadLaneConnection> links;
316 std::vector<procgen::road::RoadLaneConnection> blockedLinks;
317 std::uint32_t nodeId = 0, secondEdgeId = 0;
318 if (!decodeUnsplit(operation.payload, edge, links, blockedLinks, nodeId, secondEdgeId))
319 return reject<void>("editor.road.unsplit-payload", "Road unsplit payload is invalid");
320 auto candidate = *network_;
321 auto removedSecond = candidate.removeEdge(secondEdgeId);
322 if (!removedSecond.ok()) return roadFailure<void>(removedSecond.status());
323 auto removedFirst = candidate.removeEdge(edge.id);
324 if (!removedFirst.ok()) return roadFailure<void>(removedFirst.status());
325 auto removedNode = candidate.removeNode(nodeId);
326 if (!removedNode.ok()) return roadFailure<void>(removedNode.status());
327 auto restoredEdge = candidate.restoreEdge(edge);
328 if (!restoredEdge.ok()) return roadFailure<void>(restoredEdge.status());
329 for (const auto& link : links) {
330 auto restoredLink = candidate.addLaneLink(link);
331 if (!restoredLink.ok()) return roadFailure<void>(restoredLink.status());
332 }
333 for (const auto& link : blockedLinks) {
334 auto blocked = candidate.blockLaneLink(link);
335 if (!blocked.ok()) return roadFailure<void>(blocked.status());
336 }
337 auto valid = candidate.validate();
338 if (!valid.ok()) return roadFailure<void>(valid.status());
339 *network_ = std::move(candidate);
340 } else if (operation.type == kRestoreNode) {
342 if (!decodeNodeRecord(operation.payload, node))
343 return reject<void>("editor.road.node-payload", "Road node restore payload is invalid");
344 auto candidate = *network_;
345 auto restored = candidate.restoreNode(node);
346 if (!restored.ok()) return roadFailure<void>(restored.status());
347 *network_ = std::move(candidate);
348 } else if (operation.type == kRemoveNode) {
349 std::uint32_t nodeId = 0;
350 if (!readId(operation.payload, "id", nodeId))
351 return reject<void>("editor.road.node-payload", "Road node removal payload is invalid");
352 auto candidate = *network_;
353 auto removed = candidate.removeNode(nodeId);
354 if (!removed.ok()) return roadFailure<void>(removed.status());
355 *network_ = std::move(candidate);
356 } else if (operation.type == kRestoreEdge) {
358 std::vector<procgen::road::RoadLaneConnection> links;
359 std::vector<procgen::road::RoadLaneConnection> blockedLinks;
360 if (!decodeEdgeRecord(operation.payload, edge, links, &blockedLinks))
361 return reject<void>("editor.road.edge-payload", "Road edge restore payload is invalid");
362 auto candidate = *network_;
363 auto restored = candidate.restoreEdge(std::move(edge));
364 if (!restored.ok()) return roadFailure<void>(restored.status());
365 for (const auto& link : links) {
366 auto linked = candidate.addLaneLink(link);
367 if (!linked.ok()) return roadFailure<void>(linked.status());
368 }
369 for (const auto& link : blockedLinks) {
370 auto blocked = candidate.blockLaneLink(link);
371 if (!blocked.ok()) return roadFailure<void>(blocked.status());
372 }
373 *network_ = std::move(candidate);
374 } else if (operation.type == kRemoveEdge) {
375 std::uint32_t edgeId = 0;
376 if (!readId(operation.payload, "id", edgeId))
377 return reject<void>("editor.road.edge-payload", "Road edge removal payload is invalid");
378 auto candidate = *network_;
379 auto removed = candidate.removeEdge(edgeId);
380 if (!removed.ok()) return roadFailure<void>(removed.status());
381 *network_ = std::move(candidate);
382 } else if (operation.type == kRestoreLaneLink || operation.type == kRemoveLaneLink) {
384 if (!decodeLink(operation.payload, link))
385 return reject<void>("editor.road.lane-link-payload", "Road lane-link payload is invalid");
386 auto candidate = *network_;
387 auto changed = operation.type == kRestoreLaneLink ? candidate.addLaneLink(link)
388 : candidate.removeLaneLink(link);
389 if (!changed.ok()) return roadFailure<void>(changed.status());
390 *network_ = std::move(candidate);
391 } else if (operation.type == kBlockLaneLink || operation.type == kUnblockLaneLink) {
393 bool restoreActive = false;
394 if (!decodeBlockedLink(operation.payload, link, restoreActive))
395 return reject<void>("editor.road.lane-link-block-payload",
396 "Road lane-link block payload is invalid");
397 auto candidate = *network_;
398 if (operation.type == kBlockLaneLink) {
399 auto changed = candidate.blockLaneLink(link);
400 if (!changed.ok()) return roadFailure<void>(changed.status());
401 } else {
402 auto changed = candidate.unblockLaneLink(link);
403 if (!changed.ok()) return roadFailure<void>(changed.status());
404 if (restoreActive) {
405 auto restored = candidate.addLaneLink(link);
406 if (!restored.ok()) return roadFailure<void>(restored.status());
407 }
408 }
409 *network_ = std::move(candidate);
410 } else if (operation.type == kRestoreLaneLinks || operation.type == kRemoveLaneLinks) {
411 std::vector<procgen::road::RoadLaneConnection> links;
412 if (!decodeLinks(operation.payload, links))
413 return reject<void>("editor.road.lane-links-payload", "Road lane-link batch payload is invalid");
414 auto candidate = *network_;
415 for (const auto& link : links) {
416 auto changed = operation.type == kRestoreLaneLinks ? candidate.addLaneLink(link)
417 : candidate.removeLaneLink(link);
418 if (!changed.ok()) return roadFailure<void>(changed.status());
419 }
420 *network_ = std::move(candidate);
421 } else {
422 return reject<void>("editor.road.type", "Unsupported road operation type", EditorStatus::Unsupported);
423 }
424 dirty_.include(0, 0);
425 return editing::applied();
426}
427
428} // namespace eve::procgen_editing
ActionParameterOperation operation
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
bool split
Definition CaveMesh.cpp:123
std::string nodeId
std::int32_t second
std::int32_t first
std::array< float, 3 > position
bool valid
std::shared_ptr< const std::vector< glm::vec2 > > points
int detail
const RoadNode * node
const RoadEdge * edge
int removed
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Result< int > reconnectEdgeEndpoint(std::uint32_t edgeId, bool fromEndpoint, std::uint32_t nodeId)
Reconnect one edge endpoint to an existing node and prune connections left at the old junction.
Result< void > removeNode(std::uint32_t nodeId)
Remove an isolated node.
Result< void > setEdgeStyle(std::uint32_t edgeId, RoadStyle style)
Replace edge style atomically.
Result< void > addLaneLink(RoadLaneConnection link)
Register one legal turn inside a shared junction node.
Result< RoadEdgeSplitResult > splitEdgeAtSplineParameter(std::uint32_t edgeId, float parameter, float junctionRadius=6.f, std::uint32_t nodeId=0, std::uint32_t secondEdgeId=0)
Split at a normalized parameter on the same Catmull-Rom centerline used by road baking.
Result< std::uint32_t > detachEdgeEndpoint(std::uint32_t edgeId, bool fromEndpoint)
Detach one edge endpoint onto a new coincident stable node.
Result< void > restoreNode(RoadNode node)
Restore a node with an explicit stable id for undo/import paths.
Result< void > reverseEdge(std::uint32_t edgeId)
Atomically reverse one edge while preserving its physical lanes, links, and side-object intervals.
Result< RoadEdgeSplitResult > splitEdgeAtPosition(std::uint32_t edgeId, RoadControlPoint position, float maxDistance, float junctionRadius=6.f)
Project a world position onto the baked Catmull-Rom centerline and split at the nearest point.
Result< void > setNodeJunctionRadius(std::uint32_t nodeId, float junctionRadius)
Replace one node's positive junction trim radius.
Result< void > setNodeJunctionControl(std::uint32_t nodeId, RoadJunctionControl control)
Replace one node's authoritative traffic-control policy.
Result< void > setNodePosition(std::uint32_t nodeId, float x, float y, float z)
Move a node and atomically re-anchor every incident edge endpoint.
Result< bool > blockLaneLink(RoadLaneConnection link)
Persistently forbid one exact legal lane connection and remove it if currently active.
Result< RoadEdgeSplitResult > splitEdge(std::uint32_t edgeId, std::size_t controlPointIndex, float junctionRadius=6.f)
Split an edge at one authored interior control point as a single topology mutation.
Result< void > setEdgeControlPoints(std::uint32_t edgeId, std::vector< RoadControlPoint > controlPoints)
Replace one edge spline while preserving its node-owned endpoint positions.
Result< void > removeEdge(std::uint32_t edgeId)
Remove an edge and every lane link that references it.
Result< void > restoreEdge(RoadEdge edge)
Restore an edge with an explicit stable id for undo/import paths.
Result< int > setEdgeLaneCounts(std::uint32_t edgeId, int lanesForward, int lanesBackward)
Atomically replace directional lane counts and remove links that become out of range.
Result< int > mergeNodes(std::uint32_t keepNodeId, std::uint32_t removeNodeId, float maxDistance)
Atomically merge one nearby endpoint node into another stable node.
static constexpr const char * kConnectNodeAtPosition
static constexpr const char * kSplitEdgeAtPosition
static constexpr const char * kDetachEdgeEndpoint
static constexpr const char * kDisconnectEdgeIntersection
static constexpr const char * kConnectEdgeIntersection
static constexpr const char * kReconnectEdgeEndpoint
EVENGINE_API_ORCHESTRATION EditorResult< void > applyDomainOperation(const editing::DomainOperation &operation) override
Apply one validated domain operation.
static constexpr const char * kDisconnectNodeAtPosition
static constexpr const char * kReattachEdgeEndpoint
static constexpr const char * kMergeNodesAndConnect
editing::TargetId targetId() const override
Target id.
Result< T > applied(T value, std::vector< Diagnostic > diagnostics={})
Construct an Applied result with an owning payload and optional diagnostics.
RoadJunctionControl
Authoritative traffic-control policy applied to every approach of one junction node.
Definition RoadTypes.h:43
@ Uncontrolled
Edge trafficPriority resolves right-of-way without a mandatory stop.
bool decodeEdge(const EditorValue &value, std::uint32_t &id, std::vector< procgen::road::RoadControlPoint > &points)
bool decodeReattachEndpoint(const EditorValue &value, std::uint32_t &edgeId, bool &fromEndpoint, std::uint32_t &oldNodeId, std::uint32_t &detachedNodeId, std::vector< procgen::road::RoadLaneConnection > &restoreLinks, std::vector< procgen::road::RoadLaneConnection > &restoreBlockedLinks)
bool decodeDisconnectAtPosition(const EditorValue &value, procgen::road::RoadEdge &original, std::vector< procgen::road::RoadLaneConnection > &originalLinks, std::vector< procgen::road::RoadLaneConnection > &originalBlockedLinks, std::uint32_t &nodeId, std::uint32_t &secondEdgeId, std::uint32_t &branchEdgeId)
bool decodeDetachEndpoint(const EditorValue &value, std::uint32_t &edgeId, bool &fromEndpoint, std::uint32_t &nodeId)
bool decodeMergeNodes(const EditorValue &value, std::uint32_t &keepNodeId, std::uint32_t &removeNodeId, float &maxDistance)
bool decodeNodeRecord(const EditorValue &value, procgen::road::RoadNode &node)
bool decodeLink(const EditorValue &value, procgen::road::RoadLaneConnection &link)
bool decodeStyle(const EditorValue &value, std::uint32_t &id, procgen::road::RoadStyle &style)
bool readId(const EditorValue &value, const char *name, std::uint32_t &output)
bool decodeLinks(const EditorValue &value, std::vector< procgen::road::RoadLaneConnection > &links)
bool decodePositionSplit(const EditorValue &value, std::uint32_t &edgeId, procgen::road::RoadControlPoint &position, float &maxDistance, float &junctionRadius, std::uint32_t &nodeId, std::uint32_t &secondEdgeId)
bool decodeUnmergeNodes(const EditorValue &value, procgen::road::RoadNode &removedNode, std::vector< procgen::road::RoadEdge > &affectedEdges, std::vector< procgen::road::RoadLaneConnection > &affectedLinks, std::vector< procgen::road::RoadLaneConnection > &affectedBlockedLinks)
bool decodeNodeRadius(const EditorValue &value, std::uint32_t &id, float &junctionRadius)
bool decodeLaneCounts(const EditorValue &value, std::uint32_t &edgeId, int &lanesForward, int &lanesBackward, std::vector< procgen::road::RoadLaneConnection > &restoreLinks, std::vector< procgen::road::RoadLaneConnection > &restoreBlockedLinks)
bool decodeUnsplit(const EditorValue &value, procgen::road::RoadEdge &edge, std::vector< procgen::road::RoadLaneConnection > &links, std::vector< procgen::road::RoadLaneConnection > &blockedLinks, std::uint32_t &nodeId, std::uint32_t &secondEdgeId)
bool readNumber(const EditorValue &value, const char *name, float &output)
bool decodeIntersectionDisconnect(const EditorValue &value, procgen::road::RoadEdge &first, procgen::road::RoadEdge &second, std::vector< procgen::road::RoadLaneConnection > &links, std::vector< procgen::road::RoadLaneConnection > &blockedLinks, std::uint32_t &sharedNodeId, std::uint32_t &firstSecondEdgeId, std::uint32_t &secondSecondEdgeId)
bool decodeIntersectionConnect(const EditorValue &value, std::uint32_t &firstEdgeId, std::uint32_t &secondEdgeId, float &firstParameter, float &secondParameter, procgen::road::RoadControlPoint &mergedPoint, float &maximumHeightDelta, float &junctionRadius, std::uint32_t &firstNodeId, std::uint32_t &firstSecondEdgeId, std::uint32_t &secondNodeId, std::uint32_t &secondSecondEdgeId)
bool decodeConnectAtPosition(const EditorValue &value, std::uint32_t &edgeId, procgen::road::RoadControlPoint &position, float &maxDistance, float &junctionRadius, std::uint32_t &nodeId, std::uint32_t &secondEdgeId, procgen::road::RoadEdge &branch)
bool decodeBlockedLink(const EditorValue &value, procgen::road::RoadLaneConnection &link, bool &restoreActive)
bool decodeReconnectEndpoint(EditorValue const &value, std::uint32_t &edgeId, bool &fromEndpoint, std::uint32_t &nodeId, std::vector< procgen::road::RoadLaneConnection > &restoreLinks, std::vector< procgen::road::RoadLaneConnection > &restoreBlockedLinks)
bool decodeSplit(const EditorValue &value, std::uint32_t &edgeId, std::size_t &controlPointIndex, float &junctionRadius, std::uint32_t &nodeId, std::uint32_t &secondEdgeId)
bool decodeEdgeRecord(const EditorValue &value, procgen::road::RoadEdge &edge, std::vector< procgen::road::RoadLaneConnection > &links, std::vector< procgen::road::RoadLaneConnection > *blockedLinks)
bool decodeNodeControl(const EditorValue &value, std::uint32_t &id, procgen::road::RoadJunctionControl &control)
DomainOperation public API.
void include(int x, int y)
Include.
One authored control point on a road centerline (world space, Y-up).
Definition RoadTypes.h:12
Directed centerline edge with optional reverse lanes.
Definition RoadTypes.h:61
One legal lane-to-lane connection inside a junction.
Definition RoadTypes.h:90
Junction node owned by a road network.
Definition RoadTypes.h:51
Cross-section and structural style for one road edge.
Definition RoadTypes.h:19