载入中...
搜索中...
未找到
MeshDeformationSession.cpp
浏览该文件的文档.
15 if (mesh.empty() || mesh.positions().size() % 3u != 0u || mesh.normals().size() != mesh.positions().size() ||
27 const std::array<std::size_t, 3> v{std::size_t(mesh.indices()[i]) * 3u, std::size_t(mesh.indices()[i + 1]) * 3u,
29 const std::array<float, 3> ab{positions[v[1]] - positions[v[0]], positions[v[1] + 1] - positions[v[0] + 1],
31 const std::array<float, 3> ac{positions[v[2]] - positions[v[0]], positions[v[2] + 1] - positions[v[0] + 1],
37 normals[base + static_cast<std::size_t>(component)] += cross[static_cast<std::size_t>(component)];
41 std::sqrt(normals[i] * normals[i] + normals[i + 1] * normals[i + 1] + normals[i + 2] * normals[i + 2]);
55 Diagnostic::error(DiagnosticCode::InvalidArgument, "sculpting source mesh is empty or invalid", "mesh", {}, "procgen.meshDeformationSession"));
82 Diagnostic::error(DiagnosticCode::PreconditionViolation, "damage session is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
85 Diagnostic::error(DiagnosticCode::InvalidArgument, "impact block divisions must be in [1, 128]", "divisionsPerAxis", {}, "procgen.meshDeformationSession"));
98 const std::size_t blockCount = static_cast<std::size_t>(divisionsPerAxis) * divisionsPerAxis * divisionsPerAxis;
102 return std::clamp(static_cast<int>((value - minimum) / (maximum - minimum) * divisionsPerAxis), 0,
124std::vector<std::uint32_t> MeshDeformationSession::impactCandidates(float x, float y, float z, float radius) const {
132 return std::clamp(static_cast<int>((value - minimum) / (maximum - minimum) * impactBlockDivisions_), 0,
152Result<void> MeshDeformationSession::applyBrushResult(std::string_view mode, float x, float y, float z, float radius,
157 Diagnostic::error(DiagnosticCode::PreconditionViolation, "sculpting session is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
158 if ((mode != "inflate" && mode != "dent" && mode != "flatten" && mode != "smooth" && mode != "directional") ||
162 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid sculpting brush parameters", "brush", {}, "procgen.meshDeformationSession"));
167 std::vector<std::unordered_set<std::uint32_t>> neighbors(static_cast<std::size_t>(candidate.getVertexCount()));
178 float directionLength = std::sqrt(directionX * directionX + directionY * directionY + directionZ * directionZ);
181 Diagnostic::error(DiagnosticCode::InvalidArgument, "directional brush requires a direction", "direction", {}, "procgen.meshDeformationSession"));
204 positions[base + 1] = std::lerp(sourcePositions[base + 1], y, std::clamp(std::abs(weight), 0.f, 1.f));
208 const float vy = mode == "directional" ? directionY / directionLength : sourceNormals[base + 1];
209 const float vz = mode == "directional" ? directionZ / directionLength : sourceNormals[base + 2];
224Result<void> MeshDeformationSession::applyBrushGpuResult(std::string_view mode, float x, float y, float z, float radius,
229 Diagnostic::error(DiagnosticCode::PreconditionViolation, "sculpting session is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
230 if ((mode != "inflate" && mode != "dent" && mode != "flatten" && mode != "smooth" && mode != "directional") ||
234 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid GPU sculpting brush parameters", "brush", {}, "procgen.meshDeformationSession"));
235 const float directionLength = std::sqrt(directionX * directionX + directionY * directionY + directionZ * directionZ);
238 Diagnostic::error(DiagnosticCode::InvalidArgument, "directional brush requires a direction", "direction", {}, "procgen.meshDeformationSession"));
242 Diagnostic::error(DiagnosticCode::Unsupported, "GPU mesh deformation provider is not installed", "backend", {}, "procgen.meshDeformationSession"));
249 request.directionX = directionX; request.directionY = directionY; request.directionZ = directionZ;
253 else if (mode == "directional") request.operation = MeshDeformationComputeOperation::Directional;
257 std::vector<std::unordered_set<std::uint32_t>> neighbors(static_cast<std::size_t>(current_.getVertexCount()));
259 const std::array<std::uint32_t, 3> triangle{current_.indices()[i], current_.indices()[i + 1], current_.indices()[i + 2]};
279 !std::all_of(deformed.value().begin(), deformed.value().end(), [](float value) { return std::isfinite(value); }))
281 Diagnostic::error(DiagnosticCode::Failed, "GPU returned an invalid mesh deformation", "backend", {}, "procgen.meshDeformationSession"));
293Result<void> MeshDeformationSession::applyImpactResult(float x, float y, float z, float impulseX, float impulseY,
298 Diagnostic::error(DiagnosticCode::PreconditionViolation, "damage session is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
299 const float impulseLength = std::sqrt(impulseX * impulseX + impulseY * impulseY + impulseZ * impulseZ);
300 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z) || !std::isfinite(impulseLength) ||
302 !std::isfinite(maxDisplacement) || impulseLength <= 1e-7f || radius <= 0.f || plasticity < 0.f ||
305 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid mesh impact parameters", "impact", {}, "procgen.meshDeformationSession"));
346Result<void> MeshDeformationSession::applyImpactGpuResult(float x, float y, float z, float impulseX, float impulseY,
351 Diagnostic::error(DiagnosticCode::PreconditionViolation, "damage session is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
352 const float impulseLength = std::sqrt(impulseX * impulseX + impulseY * impulseY + impulseZ * impulseZ);
353 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z) || !std::isfinite(impulseLength) ||
355 !std::isfinite(maxDisplacement) || impulseLength <= 1e-7f || radius <= 0.f || plasticity < 0.f ||
358 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid GPU mesh impact parameters", "impact", {}, "procgen.meshDeformationSession"));
362 Diagnostic::error(DiagnosticCode::Unsupported, "GPU mesh deformation provider is not installed", "backend", {}, "procgen.meshDeformationSession"));
365 request.positions = current_.positions(); request.normals = current_.normals(); request.baseline = original_.positions();
373 !std::all_of(deformed.value().begin(), deformed.value().end(), [](float value) { return std::isfinite(value); }))
375 Diagnostic::error(DiagnosticCode::Failed, "GPU returned invalid impact positions", "backend", {}, "procgen.meshDeformationSession"));
384Result<void> MeshDeformationSession::applySurfaceContactResult(float x, float y, float z, float normalX, float normalY,
390 Diagnostic::error(DiagnosticCode::PreconditionViolation, "interactive surface is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
391 const float normalLength = std::sqrt(normalX * normalX + normalY * normalY + normalZ * normalZ);
392 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z) || !std::isfinite(normalLength) ||
393 !std::isfinite(velocityX) || !std::isfinite(velocityY) || !std::isfinite(velocityZ) || !std::isfinite(radius) ||
394 !std::isfinite(depth) || !std::isfinite(drag) || !std::isfinite(falloff) || !std::isfinite(plasticity) ||
395 normalLength <= 1e-7f || radius <= 0.f || depth < 0.f || drag < 0.f || falloff <= 0.f || plasticity < 0.f ||
398 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid interactive surface contact", "contact", {}, "procgen.meshDeformationSession"));
438 Diagnostic::error(DiagnosticCode::PreconditionViolation, "interactive surface is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
441 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid interactive surface recovery step", "recovery", {}, "procgen.meshDeformationSession"));
460Result<void> MeshDeformationSession::applySlimeImpulseResult(float x, float y, float z, float impulseX, float impulseY,
464 Diagnostic::error(DiagnosticCode::PreconditionViolation, "mesh slime is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
466 !std::isfinite(impulseY) || !std::isfinite(impulseZ) || !std::isfinite(radius) || !std::isfinite(falloff) ||
469 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid mesh slime impulse", "slime.impulse", {}, "procgen.meshDeformationSession"));
488Result<void> MeshDeformationSession::stepSlimeResult(float dt, float stiffness, float damping, float maxSpeed) {
491 Diagnostic::error(DiagnosticCode::PreconditionViolation, "mesh slime is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
492 if (!std::isfinite(dt) || !std::isfinite(stiffness) || !std::isfinite(damping) || !std::isfinite(maxSpeed) ||
495 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid mesh slime simulation step", "slime.step", {}, "procgen.meshDeformationSession"));
527Result<void> MeshDeformationSession::configureColliderRefreshResult(std::string_view mode, float intervalSeconds,
531 Diagnostic::error(DiagnosticCode::PreconditionViolation, "collider refresh session is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
534 !std::isfinite(offsetZ) || (mode == "interval" && intervalSeconds <= 0.f) || intervalSeconds < 0.f)
536 Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid collider refresh configuration", "colliderRefresh", {}, "procgen.meshDeformationSession"));
552 Diagnostic::error(DiagnosticCode::PreconditionViolation, "collider refresh is not configured", "colliderRefresh", {}, "procgen.meshDeformationSession"));
570 if (colliderRefreshAccumulator_ + tolerance < colliderRefreshInterval_) return Result<bool>::success(false);
597Result<int> MeshDeformationSession::selectVerticesSphereResult(float x, float y, float z, float radius, bool replace) {
602 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z) || !std::isfinite(radius) || radius <= 0.f)
606 auto candidate = replace ? std::vector<std::uint8_t>(selectedVertices_.size(), 0u) : selectedVertices_;
611 const float dx = positions[base] - x, dy = positions[base + 1] - y, dz = positions[base + 2] - z;
618Result<int> MeshDeformationSession::selectVerticesBoxResult(float minX, float minY, float minZ, float maxX, float maxY,
624 if (!std::isfinite(minX) || !std::isfinite(minY) || !std::isfinite(minZ) || !std::isfinite(maxX) ||
626 return Result<int>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "invalid box vertex selection",
628 auto candidate = replace ? std::vector<std::uint8_t>(selectedVertices_.size(), 0u) : selectedVertices_;
651 Diagnostic::error(DiagnosticCode::PreconditionViolation, "vertex center requires a selection", "selection",
673 Diagnostic::error(DiagnosticCode::PreconditionViolation, "vertex editor is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
676 Diagnostic::error(DiagnosticCode::InvalidArgument, "vertex move delta must be finite", "move", {}, "procgen.meshDeformationSession"));
679 Diagnostic::error(DiagnosticCode::PreconditionViolation, "vertex move requires a selection", "selection", {}, "procgen.meshDeformationSession"));
698Result<void> MeshDeformationSession::manipulateSelectedVerticesResult(std::string_view mode, float originX,
704 Diagnostic::error(DiagnosticCode::InvalidArgument, "vertex manipulation mode must be pull, push, or grab", "mode", {}, "procgen.meshDeformationSession"));
705 if (!std::isfinite(originX) || !std::isfinite(originY) || !std::isfinite(originZ) || !std::isfinite(directionX) ||
708 Diagnostic::error(DiagnosticCode::InvalidArgument, "vertex manipulation values must be finite", "input", {}, "procgen.meshDeformationSession"));
710 return moveSelectedVerticesResult(directionX * distance, directionY * distance, directionZ * distance);
713 Diagnostic::error(DiagnosticCode::PreconditionViolation, "vertex manipulation requires a selection", "selection", {}, "procgen.meshDeformationSession"));
739 Diagnostic::error(DiagnosticCode::PreconditionViolation, "sculpting session is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
752 Diagnostic::error(DiagnosticCode::PreconditionViolation, "sculpting session is not initialized", "mesh", {}, "procgen.meshDeformationSession"));
764 Diagnostic::error(DiagnosticCode::NotFound, "sculpting undo history is empty", "undo", {}, "procgen.meshDeformationSession"));
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
CPU triangle mesh from procedural mesh recipes (e.g. marching cubes). Positions/normals are xyz-packe...
Definition MeshBuild.h:19
void setMeta(const std::string &key, const std::string &value)
Sets the meta.
Definition MeshBuild.cpp:244
int selectedVertexCount() const noexcept
Return selected vertex count.
Definition MeshDeformationSession.cpp:644
Result< void > initializeResult(const MeshBuild &mesh)
Replace the session with an owning copy of a valid source mesh.
Definition MeshDeformationSession.cpp:52
Result< int > selectVerticesSphereResult(float x, float y, float z, float radius, bool replace=true)
Replace or extend vertex selection using a world/local-space sphere.
Definition MeshDeformationSession.cpp:597
Result< void > applyImpactGpuResult(float x, float y, float z, float impulseX, float impulseY, float impulseZ, float radius, float plasticity, float hardness, float maxDisplacement)
Apply plastic damage through the registered GPU provider; absence returns Unsupported.
Definition MeshDeformationSession.cpp:346
Result< void > moveSelectedVerticesResult(float x, float y, float z)
Translate selected vertices by a finite axis-gizmo delta as one undoable edit.
Definition MeshDeformationSession.cpp:670
Result< void > undoResult()
Restore the most recent pre-edit snapshot.
Definition MeshDeformationSession.cpp:762
void clearVertexSelection() noexcept
Clear runtime vertex selection.
Definition MeshDeformationSession.cpp:640
Result< void > prepareImpactVertexBlocksResult(int divisionsPerAxis)
Build a bounded uniform vertex-block index for repeated high-density impact queries.
Definition MeshDeformationSession.cpp:79
Result< void > stepSlimeResult(float dt, float stiffness, float damping, float maxSpeed)
Advance deterministic spring-damper Mesh Slime dynamics using injected time.
Definition MeshDeformationSession.cpp:488
Result< bool > updateColliderRefreshResult(float dt)
Advance the refresh scheduler and consume at most one pending refresh.
Definition MeshDeformationSession.cpp:557
Result< int > selectVerticesBoxResult(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, bool replace=true)
Replace or extend vertex selection using an axis-aligned world/local-space box.
Definition MeshDeformationSession.cpp:618
Result< void > applyBrushGpuResult(std::string_view mode, float x, float y, float z, float radius, float strength, float falloff, float directionX=0.f, float directionY=1.f, float directionZ=0.f)
Apply a sculpt brush through the registered GPU provider; absence returns Unsupported.
Definition MeshDeformationSession.cpp:224
Result< void > applyImpactResult(float x, float y, float z, float impulseX, float impulseY, float impulseZ, float radius, float plasticity, float hardness, float maxDisplacement)
Apply one collision-neutral plastic impact to the current mesh.
Definition MeshDeformationSession.cpp:293
Result< void > bakeResult()
Make the current mesh the new restore point and clear undo history.
Definition MeshDeformationSession.cpp:749
Result< void > manipulateSelectedVerticesResult(std::string_view mode, float originX, float originY, float originZ, float directionX, float directionY, float directionZ, float distance)
Apply pull, push, or grab to selected vertices as one undoable edit.
Definition MeshDeformationSession.cpp:698
Result< void > requestColliderRefreshResult()
Mark a manual or once collider refresh as pending.
Definition MeshDeformationSession.cpp:549
Result< MeshVertexSelectionCenter > selectedVertexCenterResult() const
Return the arithmetic center of selected vertices for gizmo adapters.
Definition MeshDeformationSession.cpp:648
Result< void > applySurfaceContactResult(float x, float y, float z, float normalX, float normalY, float normalZ, float velocityX, float velocityY, float velocityZ, float radius, float depth, float drag, float falloff, float plasticity=0.f)
Apply one Interactive Surface contact using caller-supplied local-space values.
Definition MeshDeformationSession.cpp:384
Result< void > configureColliderRefreshResult(std::string_view mode, float intervalSeconds, float offsetX=0.f, float offsetY=0.f, float offsetZ=0.f)
Configure collider refresh scheduling and local position offset.
Definition MeshDeformationSession.cpp:527
Result< void > restoreResult()
Restore the initial mesh and clear undo history.
Definition MeshDeformationSession.cpp:736
Result< MeshBuild > currentMeshResult() const
Return an independent owning snapshot of the current mesh.
Definition MeshDeformationSession.cpp:774
Result< void > applySlimeImpulseResult(float x, float y, float z, float impulseX, float impulseY, float impulseZ, float radius, float falloff)
Inject one localized velocity impulse into the Mesh Slime simulation state.
Definition MeshDeformationSession.cpp:460
Result< void > applyBrushResult(std::string_view mode, float x, float y, float z, float radius, float strength, float falloff, float directionX=0.f, float directionY=1.f, float directionZ=0.f)
Apply a localized brush to the current mesh.
Definition MeshDeformationSession.cpp:152
Result< MeshBuild > colliderMeshResult() const
Return an owning current triangle-mesh collider snapshot with configured offset applied.
Definition MeshDeformationSession.cpp:580
int impactVertexBlockCount() const noexcept
Return the number of non-empty prepared impact blocks.
Definition MeshDeformationSession.cpp:119
Result< void > recoverSurfaceResult(float dt, float recoveryRate)
Advance elastic recovery using explicit simulation time.
Definition MeshDeformationSession.cpp:435
Definition EvpackPointGraphLoader.h:12
@ InvalidArgument
@ NotFound
@ PreconditionViolation
@ Unsupported
@ Failed
@ Directional
Owning, backend-neutral input for one synchronous GPU mesh deformation.
Definition MeshDeformationCompute.h:19
std::vector< float > positions
Definition MeshDeformationCompute.h:21
MeshDeformationComputeOperation operation
Definition MeshDeformationCompute.h:20
Value-only center of the current runtime vertex selection.
Definition MeshDeformationSession.h:15