载入中...
搜索中...
未找到
SplinePath.cpp
浏览该文件的文档.
13 std::isfinite(p.inY) && std::isfinite(p.inZ) && std::isfinite(p.outX) && std::isfinite(p.outY) &&
15 std::isfinite(p.scaleY) && std::isfinite(p.pitchDegrees) && std::isfinite(p.yawDegrees) && p.scaleX > 0.f &&
27V3 cross(V3 a, V3 b) { return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; }
28float length(V3 value) { return std::sqrt(value.x * value.x + value.y * value.y + value.z * value.z); }
35 return add(add(mul(value, c), mul(cross(axis, value), s)), mul(axis, dot(axis, value) * (1.f - c)));
44 DiagnosticCode::InvalidArgument, "spline kind must be linear, catmullRom, quadraticBezier, or bezier",
65 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "spline point must be finite",
74 return Result<void>::failure(Diagnostic::error(DiagnosticCode::NotFound, "spline point index is out of range",
77 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "spline point must be finite",
84Result<void> SplinePath::setPointProfileResult(int index, float rollDegrees, float scaleX, float scaleY) {
86 return Result<void>::failure(Diagnostic::error(DiagnosticCode::NotFound, "spline point index is out of range",
102Result<void> SplinePath::setPointRotationResult(int index, float pitchDegrees, float yawDegrees, float rollDegrees) {
104 return Result<void>::failure(Diagnostic::error(DiagnosticCode::NotFound, "spline point index is out of range",
128 if (points_[static_cast<std::size_t>(index)].breakBefore == disconnected) return Result<void>::success();
136 return Result<void>::failure(Diagnostic::error(DiagnosticCode::NotFound, "spline point index is out of range",
168 DiagnosticCode::NotFound, "spline chunk index is out of range", "chunk.index", {}, "procgen.splinePath"));
209 const float u = segment == segments - 1 && t == 1.f ? 1.f : scaled - static_cast<float>(segment);
213SplineSample SplinePath::evaluateSegmentUnchecked(int segment, float u, float normalizedDistance) const {
239 add(add(mul(p0, v * v * v), mul(p1, 3.f * v * v * u)), add(mul(p2, 3.f * v * u * u), mul(p3, u * u * u)));
240 tangent = add(add(mul(sub(p1, p0), 3.f * v * v), mul(sub(p2, p1), 6.f * v * u)), mul(sub(p3, p2), 3.f * u * u));
261 add(sub(p2, p0), add(mul(add(add(mul(p0, 2.f), mul(p1, -5.f)), add(mul(p2, 4.f), mul(p3, -1.f))), 2.f * u),
290 DiagnosticCode::InvalidArgument, "spline parameter must be finite", "t", {}, "procgen.splinePath"));
301 if (arcSamplesPerSegment_ == samplesPerSegment && !arcTable_.empty()) return Result<void>::success();
307 const bool startsChunk = segment == 0 || endpoints[static_cast<std::size_t>(segment - 1)].second !=
310 evaluateSegmentUnchecked(segment, 0.f, static_cast<float>(segment) / static_cast<float>(segmentCount()));
331Result<SplineSample> SplinePath::evaluateDistanceResult(float distance, int samplesPerSegment) const {
334 DiagnosticCode::InvalidArgument, "spline distance must be finite", "distance", {}, "procgen.splinePath"));
361 evaluateSegmentUnchecked(segment, u, (static_cast<float>(segment) + u) / static_cast<float>(segmentCount()));
366Result<SplineSample> SplinePath::closestPointResult(float x, float y, float z, int samplesPerSegment) const {
369 DiagnosticCode::InvalidArgument, "closest point query must be finite", "point", {}, "procgen.splinePath"));
377 entry.segment, entry.u, (static_cast<float>(entry.segment) + entry.u) / static_cast<float>(segmentCount()));
391Result<std::vector<SplineFrameSample>> SplinePath::sampleFramesResult(int sampleCount, bool uniformByDistance,
395 Diagnostic::error(DiagnosticCode::InvalidArgument, "frame sampleCount must be in [1, 4096]", "sampleCount",
399 DiagnosticCode::InvalidArgument, "frame roll must be finite", "rollDegrees", {}, "procgen.splinePath"));
416 uniformByDistance ? evaluateDistanceResult(totalLength * ratio, samplesPerSegment) : evaluateResult(ratio);
439 frames.push_back({sample, side.x, side.y, side.z, up.x, up.y, up.z, tangent.x, tangent.y, tangent.z});
450 std::atan2(dot(tangent, cross(lastSide, firstSide)), std::clamp(dot(lastSide, firstSide), -1.f, 1.f));
455 V3 side = rotateAround({frame.sideX, frame.sideY, frame.sideZ}, currentTangent, correction * ratio);
526 return chunk < 0 || chunk >= chunkCount() ? 0 : static_cast<int>(chunks_[static_cast<std::size_t>(chunk)].size());
534 return Result<SplineSample>::success(chunks_[static_cast<std::size_t>(chunk)][static_cast<std::size_t>(index)]);
545 DiagnosticCode::NotFound, "spline polyline index is out of range", "polyline.index", {}, "procgen.splinePath"));
548Result<SplineSample> SplinePath::travelResult(float distance, std::string_view wrapMode, int samplesPerSegment) const {
555 DiagnosticCode::InvalidArgument, "spline travel wrap mode must be clamp, loop, or pingPong", "wrapMode", {},
573Result<SplineFrameSample> SplinePath::travelFrameResult(float distance, std::string_view wrapMode,
587 normalized({std::lerp(lower.forwardX, upper.forwardX, blend), std::lerp(lower.forwardY, upper.forwardY, blend),
620 DiagnosticCode::InvalidArgument, "spline polyline requires at least two samples per chunk", "sampleCount",
633 auto measured = uniformByDistance ? path.value().lengthResult(samplesPerSegment) : Result<float>::success(0.f);
651Result<void> SplinePath::applyShapePresetResult(std::string_view preset, int pointCount, float radius, float height,
653 if (preset != "line" && preset != "circle" && preset != "arc" && preset != "spiral" && preset != "wave")
661 if (!std::isfinite(radius) || !std::isfinite(height) || !std::isfinite(turns) || radius <= 0.f || turns <= 0.f)
669 const float t = pointCount > 1 ? static_cast<float>(index) / static_cast<float>(pointCount - 1) : 0.f;
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
Owning uniformly distributed spline samples for instancing.
Definition SplinePath.h:45
Result< SplineSample > sampleResult(int index) const
Return one sample value, or a structured out-of-range diagnostic.
Definition SplinePath.cpp:503
Result< SplineFrameSample > frameResult(int index) const
Return one sample with its transported orientation frame.
Definition SplinePath.cpp:511
Owning multi-segment 3D spline with deterministic bounded sampling.
Definition SplinePath.h:91
Result< void > setPointRotationResult(int index, float pitchDegrees, float yawDegrees, float rollDegrees)
Atomically replace point-local pitch, yaw, and roll orientation.
Definition SplinePath.cpp:102
Result< void > setPointResult(int index, const SplinePoint &point)
Replace a control point atomically.
Definition SplinePath.cpp:72
Result< void > applyShapePresetResult(std::string_view preset, int pointCount, float radius, float height, float turns=1.f)
Atomically replace this path with line, circle, arc, spiral, or wave preset points.
Definition SplinePath.cpp:651
Result< void > removePointResult(int index)
Remove a control point by stable current index.
Definition SplinePath.cpp:134
Result< SplineSample > evaluateResult(float t) const
Evaluate by normalized segment parameter, not arc length.
Definition SplinePath.cpp:285
void setClosed(bool closed)
Configure whether the final point connects back to the first.
Definition SplinePath.cpp:51
int chunkCount() const noexcept
Return the number of independently connected chunks.
Definition SplinePath.cpp:157
Result< std::vector< SplineFrameSample > > sampleFramesResult(int sampleCount, bool uniformByDistance, float rollDegrees=0.f, int samplesPerSegment=24) const
Sample stable parallel-transport frames for extrusion and placement.
Definition SplinePath.cpp:391
Result< void > setKindResult(std::string_view kind)
Select linear, catmullRom, quadraticBezier, or cubic bezier interpolation.
Definition SplinePath.cpp:41
Result< SplinePolyline > polylineResult(int sampleCount=64, bool uniformByDistance=true, int samplesPerSegment=24) const
Build an owning sampled polyline without depending on a graphics module.
Definition SplinePath.cpp:612
Result< void > setPointChunkBreakResult(int index, bool disconnected)
Start or reconnect an open-path chunk before one non-first point.
Definition SplinePath.cpp:119
Result< SplinePath > chunkPathResult(int chunk) const
Copy one independently connected chunk as an owning path.
Definition SplinePath.cpp:165
Result< SplineSample > evaluateDistanceResult(float distance, int samplesPerSegment=24) const
Evaluate by world-space distance using a bounded arc-length table.
Definition SplinePath.cpp:331
Result< void > addPointResult(const SplinePoint &point)
Append an owning control point after validating finite coordinates.
Definition SplinePath.cpp:63
Result< void > setPointProfileResult(int index, float rollDegrees, float scaleX, float scaleY)
Atomically replace per-point roll and cross-section scale after finite positive validation.
Definition SplinePath.cpp:84
Result< SplineSample > travelResult(float distance, std::string_view wrapMode="clamp", int samplesPerSegment=24) const
Evaluate distance-driven travel using clamp, loop, or pingPong wrapping without reading wall time.
Definition SplinePath.cpp:548
Result< SplineDistribution > distributeResult(int instanceCount, bool includeEnd=true, int samplesPerSegment=24) const
Produce owning arc-length-uniform samples for instance distribution.
Definition SplinePath.cpp:598
Result< SplineSample > closestPointResult(float x, float y, float z, int samplesPerSegment=32) const
Return the sampled closest path location to a point.
Definition SplinePath.cpp:366
Result< float > lengthResult(int samplesPerSegment=24) const
Return approximate total world-space length.
Definition SplinePath.cpp:325
Result< SplineFrameSample > travelFrameResult(float distance, std::string_view wrapMode="clamp", int samplesPerSegment=24) const
Evaluate distance-driven travel with a transported orientation frame.
Definition SplinePath.cpp:573
Owning sampled polyline for renderer-neutral runtime visualization adapters.
Definition SplinePath.h:61
Result< SplineSample > chunkPointResult(int chunk, int index) const
Return one point inside one disconnected chunk.
Definition SplinePath.cpp:529
Result< SplineSample > pointResult(int index) const
Return one point sample or a structured range error.
Definition SplinePath.cpp:537
int chunkPointCount(int chunk) const noexcept
Return point count for one chunk, or zero for an invalid index.
Definition SplinePath.cpp:525
constexpr HexDirection next(HexDirection d) noexcept
The next direction clockwise (NW wraps to NE).
Definition HexMetrics.h:76
Definition EvpackPointGraphLoader.h:12
@ InvalidArgument
@ NotFound
@ PreconditionViolation
One spline anchor with incoming and outgoing handle offsets.
Definition SplinePath.h:15
Evaluated spline position and normalized tangent.
Definition SplinePath.h:26