Curve3D
Local 3D Bezier curve with control handles and a CPU length/orientation cache.
Add points and relative in/out handles, then choose sampling units: Sample(idx,t) is one segment parameter; Samplef uses index plus fraction; SampleBaked(offset) uses local distance on an approximation. For motion in local units per second, accumulate distance instead of treating t as time or a fraction of the whole length.
Baked data rebuild lazily after edits. BakeInterval controls density, but length remains approximate. SampleBaked clamps distance and does not loop even when Closed. Closed Samplef(PointCount) has special boundary behavior; use the explicit final-segment endpoint or GetBakedLength for the loop endpoint.
Tilt is in radians and applies by flag. Frame forward is −Basis.Z. All results are local: Path3D transform/scale are not automatically applied. _Data is an internal container requiring matching lengths, not a user-input format.
Small nondegenerate curves, cache/handles, closure, orientation and valid data roundtrips were tested in Windows headless. Degenerate geometry, malformed data, exact analytic length, all tessellation tolerances and graphics were not established.
Declarations checked against C# SDK 1.0.0. Expand a name to see declarations and documentation.
Constructors1
Curve3DConstructor
public Curve3D();Creates an owned empty curve resource: Closed=false, BakeInterval=0.2, UpVectorEnabled=true. Add control points before sampling. Stores local data rather than moving Entities or building collisions. Dispose the resource after use.
Properties5
BakeIntervalProperty
public float BakeInterval { get; set; }Positive finite CPU-cache density scale, default 0.2 in local units. Smaller usually produces more samples and memory/CPU work. Not a promise of perfectly equal spacing or exact analytic length: subdivision depth is bounded. The setter does not validate positivity/finiteness for you.
ClosedProperty
public bool Closed { get; set; }Adds a last-to-first segment without duplicating a control point in PointCount. Requires at least two meaningful points. Does not enable automatic SampleBaked looping: distance still clamps to endpoints. RemovePoint clears Closed below two points, while PointCount/ClearPoints can retain it.
PointCountProperty
public int PointCount { get; set; }Control-point count, not baked-sample count. Growth appends zero positions/handles/tilts; shrinking truncates the end. Changed can occur per appended point rather than one atomic path replacement. Shrinking through PointCount does not automatically clear Closed; validate configuration yourself.
UpVectorEnabledProperty
public bool UpVectorEnabled { get; set; }Enables baked up-vector computation, default true. Used for an up direction along the path and SampleBakedUpVector. Disabling reduces cache data; frame sampling falls back to Vector3.Up, which does not guarantee stability for vertical/degenerate curves. Does not control gravity.
_DataProperty
public Reckfell.Collections.Dictionary _Data { get; set; }Internal data container: points is Vector3[] triplets of in/out/position; tilts is float[] with one value per point. Getter creates a Dictionary snapshot; setter requires matching lengths. An undersized tilts array is not safely validated input. Use point methods for ordinary code and resources for persistence; this is not a stable external format. Dispose the owned Dictionary wrapper after reading.
Methods32
AddPointvoid
public void AddPoint(Vector3 position, Vector3? @in = default, Vector3? @out = default, int index = -1);Adds a control point with local position and relative in/out handles. Default nullable handles become Vector3.Zero. index in [0,PointCount) inserts before that point; negative/out-of-range appends. Shifts subsequent indices, invalidates the cache and emits Changed.
| Name | Type | Default |
|---|---|---|
position | Vector3 | — |
in | Vector3? | default |
out | Vector3? | default |
index | int | -1 |
positionFinite local position; SetPointIn/Out take a relative handle rather than an endpoint.
inRelative incoming handle; null/default means Vector3.Zero.
outRelative outgoing handle; null/default means Vector3.Zero.
indexInsert-before index; out-of-range appends.
ClearPointsvoid
public void ClearPoints();Removes all control points; the next baked query rebuilds an empty cache. Retains settings including Closed. Do not sample positions/orientation on an empty curve; GetBakedLength returns 0.
GetBakeIntervalfloat
public float GetBakeInterval();Reads BakeInterval. Positive finite CPU-cache density scale, default 0.2 in local units. Smaller usually produces more samples and memory/CPU work. Not a promise of perfectly equal spacing or exact analytic length: subdivision depth is bounded. The setter does not validate positivity/finiteness for you.
floatStored setting; see the description for units.
GetBakedLengthfloat
public float GetBakedLength();Lazily updates the CPU cache and returns approximate baked-polyline length in local units. Empty/single-point curves yield 0; Closed includes the closing segment. Path3D scale is not automatically included.
floatApproximate local CPU-cache length, 0 for empty/single-point curves.
GetBakedPointsVector3[]
public Vector3[] GetBakedPoints();Returns an independent C# array of local cached positions, rebuilding first if needed. Array indices are not control-point indices. Samples an approximation rather than original handles.
Vector3[]New independent C# array of the specified baked/polyline data.
GetBakedTiltsfloat[]
public float[] GetBakedTilts();Returns tilt radians aligned with baked positions. Not a list of control-point tilts alone or automatic Entity roll application.
float[]New independent C# array of the specified baked/polyline data.
GetBakedUpVectorsVector3[]
public Vector3[] GetBakedUpVectors();Returns baked up vectors; empty when UpVectorEnabled=false. Orientation data rather than terrain surface normals. Array edits do not modify the curve.
Vector3[]New independent C# array of the specified baked/polyline data.
GetClosestOffsetfloat
public float GetClosestOffset(Vector3 toPoint);Returns local distance along the baked polyline to the closest toPoint projection. Neither perpendicular distance to the curve nor segment t. Can require scanning the entire cache.
| Name | Type | Default |
|---|---|---|
toPoint | Vector3 | — |
toPointFinite point in the curve local coordinate system.
floatDistance along the baked path to the closest projection.
GetClosestPointVector3
public Vector3 GetClosestPoint(Vector3 toPoint);Projects local toPoint onto the baked polyline by scanning its segments. An approximation, not a physics raycast or guaranteed solution for degenerate segments. Convert world input through Path3D.ToLocal first and the result through ToGlobal if needed.
| Name | Type | Default |
|---|---|---|
toPoint | Vector3 | — |
toPointFinite point in the curve local coordinate system.
Vector3Local vector/position for the specified query; do not ignore failure diagnostics.
GetPointCountint
public int GetPointCount();Reads the number of control points, including both endpoints of an open curve. Not the segment or baked-sample count.
intControl-point count, not baked samples.
GetPointInVector3
public Vector3 GetPointIn(int idx);Reads the incoming handle relative to this point position. Absolute Bezier control position = GetPointPosition(idx)+GetPointIn(idx).
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxExisting control-point index; for Sample, a segment index.
Vector3Local vector/position for the specified query; do not ignore failure diagnostics.
GetPointOutVector3
public Vector3 GetPointOut(int idx);Reads the outgoing handle relative to the point position. Neither the next endpoint nor a world coordinate.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxExisting control-point index; for Sample, a segment index.
Vector3Local vector/position for the specified query; do not ignore failure diagnostics.
GetPointPositionVector3
public Vector3 GetPointPosition(int idx);Reads an existing control point local position. Returns neither its world position nor the nearest baked sample.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxExisting control-point index; for Sample, a segment index.
Vector3Local vector/position for the specified query; do not ignore failure diagnostics.
GetPointTiltfloat
public float GetPointTilt(int idx);Reads the control-point tilt in radians. A roll around path direction, not Entity Euler degrees.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxExisting control-point index; for Sample, a segment index.
floatStored tilt in radians.
IsClosedbool
public bool IsClosed();Reads Closed. Adds a last-to-first segment without duplicating a control point in PointCount. Requires at least two meaningful points. Does not enable automatic SampleBaked looping: distance still clamps to endpoints. RemovePoint clears Closed below two points, while PointCount/ClearPoints can retain it.
boolCurrent flag value rather than a geometry-validity guarantee.
IsUpVectorEnabledbool
public bool IsUpVectorEnabled();Reads UpVectorEnabled. Enables baked up-vector computation, default true. Used for an up direction along the path and SampleBakedUpVector. Disabling reduces cache data; frame sampling falls back to Vector3.Up, which does not guarantee stability for vertical/degenerate curves. Does not control gravity.
boolCurrent flag value rather than a geometry-validity guarantee.
RemovePointvoid
public void RemovePoint(int idx);Removes an existing index and shifts subsequent ones. If Closed and fewer than two points remain, opens the curve. Unlike shrinking PointCount; invalidates the cache and emits Changed.
| Name | Type | Default |
|---|---|---|
idx | int | — |
idxExisting control-point index; for Sample, a segment index.
SampleVector3
public Vector3 Sample(int idx, float t);Evaluates a segment Bezier position at parameter t, normally 0..1. Not distance or constant speed: even zero handles do not make t=0.25 a quarter of the length. Open segments are 0..PointCount−2; Closed adds last→first. Out-of-segment endpoint indices can return an endpoint, but use a valid index; do not assume t is clamped.
| Name | Type | Default |
|---|---|---|
idx | int | — |
t | float | — |
idxExisting control-point index; for Sample, a segment index.
tBezier segment parameter, normally 0..1; neither distance nor elapsed time.
Vector3Local vector/position for the specified query; do not ignore failure diagnostics.
SampleBakedVector3
public Vector3 SampleBaked(float offset = 0f, bool cubic = false);Samples position at finite distance offset along the baked cache. Clamps to 0..GetBakedLength() without looping even when Closed. cubic=true uses cubic cache interpolation, not exact original Bezier sampling, and can differ from linear. Add points first.
| Name | Type | Default |
|---|---|---|
offset | float | 0f |
cubic | bool | false |
offsetFinite local-unit distance along the baked cache, not a normalized ratio.
cubictrue enables cubic cache interpolation, default false; not exact reconstruction of the original Bezier.
Vector3Local vector/position for the specified query; do not ignore failure diagnostics.
SampleBakedUpVectorVector3
public Vector3 SampleBakedUpVector(float offset, bool applyTilt = false);Samples a local up vector at distance offset; requires UpVectorEnabled and a usable cache. applyTilt defaults to false. Do not use on empty/degenerate curves or treat a diagnosed Vector3.Up fallback as successful sampling.
| Name | Type | Default |
|---|---|---|
offset | float | — |
applyTilt | bool | false |
offsetFinite local-unit distance along the baked cache, not a normalized ratio.
applyTilttrue applies tilt radians to frame/up-vector; false by default.
Vector3Local vector/position for the specified query; do not ignore failure diagnostics.
SampleBakedWithRotationTransform3D
public Transform3D SampleBakedWithRotation(float offset = 0f, bool cubic = false, bool applyTilt = false);Returns a local Transform3D: Origin is the baked position and Basis the orientation frame; forward is −Basis.Z. applyTilt includes tilt roll in radians. Meaningful orientation needs at least two nondegenerate points; one point produces diagnostics. Does not automatically assign an Entity transform.
| Name | Type | Default |
|---|---|---|
offset | float | 0f |
cubic | bool | false |
applyTilt | bool | false |
offsetFinite local-unit distance along the baked cache, not a normalized ratio.
cubictrue enables cubic cache interpolation, default false; not exact reconstruction of the original Bezier.
applyTilttrue applies tilt radians to frame/up-vector; false by default.
Transform3DLocal Transform3D with forward=−Basis.Z, not a world transform.
SamplefVector3
public Vector3 Samplef(float fofs);Uses the integer part of fofs as segment index and the fraction as t. Not a normalized whole-curve distance. In 1.0.0 Closed Samplef(PointCount) returns the last-segment start rather than the loop endpoint. Use Sample(PointCount−1,1) or SampleBaked(GetBakedLength()) for the closing endpoint.
| Name | Type | Default |
|---|---|---|
fofs | float | — |
fofsSegment index plus fractional t; avoid integer upper bound PointCount for Closed.
Vector3Local vector/position for the specified query; do not ignore failure diagnostics.
SetBakeIntervalvoid
public void SetBakeInterval(float distance);Sets BakeInterval. Positive finite CPU-cache density scale, default 0.2 in local units. Smaller usually produces more samples and memory/CPU work. Not a promise of perfectly equal spacing or exact analytic length: subdivision depth is bounded. The setter does not validate positivity/finiteness for you.
| Name | Type | Default |
|---|---|---|
distance | float | — |
distancePositive finite BakeInterval; the setter does not validate it for you.
SetClosedvoid
public void SetClosed(bool closed);Sets Closed. Adds a last-to-first segment without duplicating a control point in PointCount. Requires at least two meaningful points. Does not enable automatic SampleBaked looping: distance still clamps to endpoints. RemovePoint clears Closed below two points, while PointCount/ClearPoints can retain it.
| Name | Type | Default |
|---|---|---|
closed | bool | — |
closedtrue adds last→first; does not enable distance wrapping.
SetPointCountvoid
public void SetPointCount(int count);Sets PointCount. Control-point count, not baked-sample count. Growth appends zero positions/handles/tilts; shrinking truncates the end. Changed can occur per appended point rather than one atomic path replacement. Shrinking through PointCount does not automatically clear Closed; validate configuration yourself.
| Name | Type | Default |
|---|---|---|
count | int | — |
countNonnegative control-point count; growth appends zero data.
SetPointInvoid
public void SetPointIn(int idx, Vector3 position);Sets an existing point relative incoming handle. It forms no preceding segment at an open curve first point; Closed uses it for the closing segment. Invalidates the cache.
| Name | Type | Default |
|---|---|---|
idx | int | — |
position | Vector3 | — |
idxExisting control-point index; for Sample, a segment index.
positionFinite local position; SetPointIn/Out take a relative handle rather than an endpoint.
SetPointOutvoid
public void SetPointOut(int idx, Vector3 position);Sets an existing point relative outgoing handle. It creates no extra segment at an open curve last point; Closed uses it to return to the first. Invalidates the cache.
| Name | Type | Default |
|---|---|---|
idx | int | — |
position | Vector3 | — |
idxExisting control-point index; for Sample, a segment index.
positionFinite local position; SetPointIn/Out take a relative handle rather than an endpoint.
SetPointPositionvoid
public void SetPointPosition(int idx, Vector3 position);Changes an existing point local position while retaining relative handles/tilt. Invalidates the CPU cache and emits Changed. Every owner of a shared resource sees the edit.
| Name | Type | Default |
|---|---|---|
idx | int | — |
position | Vector3 | — |
idxExisting control-point index; for Sample, a segment index.
positionFinite local position; SetPointIn/Out take a relative handle rather than an endpoint.
SetPointTiltvoid
public void SetPointTilt(int idx, float tilt);Sets finite tilt in radians and invalidates the cache. Orientation sampling applies it only with applyTilt=true; position itself does not change.
| Name | Type | Default |
|---|---|---|
idx | int | — |
tilt | float | — |
idxExisting control-point index; for Sample, a segment index.
tiltFinite roll in radians rather than degrees.
SetUpVectorEnabledvoid
public void SetUpVectorEnabled(bool enable);Sets UpVectorEnabled. Enables baked up-vector computation, default true. Used for an up direction along the path and SampleBakedUpVector. Disabling reduces cache data; frame sampling falls back to Vector3.Up, which does not guarantee stability for vertical/degenerate curves. Does not control gravity.
| Name | Type | Default |
|---|---|---|
enable | bool | — |
enableEnables baked up vectors, not world-up or gravity.
TessellateVector3[]
public Vector3[] Tessellate(int maxStages = 5, float toleranceDegrees = 4f);Returns a local polyline from adaptive subdivision using toleranceDegrees as an angular criterion. maxStages limits depth rather than exact point count. Changes no control points and promises neither equal intervals nor exact length. Closed output returns to the first point.
| Name | Type | Default |
|---|---|---|
maxStages | int | 5 |
toleranceDegrees | float | 4f |
maxStagesSensible nonnegative subdivision depth; larger costs more work/memory.
toleranceDegreesPositive finite angular tolerance in degrees, bounded by maxStages.
Vector3[]New independent C# array of the specified baked/polyline data.
TessellateEvenLengthVector3[]
public Vector3[] TessellateEvenLength(int maxStages = 5, float toleranceLength = 0.2f);Returns a local polyline from length-based toleranceLength subdivision bounded by maxStages. “Even” guarantees neither perfectly identical spacing nor tolerance after reaching the depth limit. Requires at least two points and changes no source data.
| Name | Type | Default |
|---|---|---|
maxStages | int | 5 |
toleranceLength | float | 0.2f |
maxStagesSensible nonnegative subdivision depth; larger costs more work/memory.
toleranceLengthPositive finite length criterion in local units, bounded by maxStages.
Vector3[]New independent C# array of the specified baked/polyline data.