Skip to content

Math API

GodotECS.Math — pure static helpers, zero allocations, no LINQ/boxing. Source: addons/godotecs/src/math/.

Aabb

csharp
public struct Aabb
{
    public Godot.Vector3 Min;
    public Godot.Vector3 Max;
    public Aabb(Godot.Vector3 min, Godot.Vector3 max) { Min = min; Max = max; }
    public static Aabb FromCenterRadius(in Godot.Vector3 c, float r);
    public static Aabb Merge(in Aabb a, in Aabb b);
    public bool Overlaps(in Aabb o);
    public bool Contains(in Godot.Vector3 p);
}

FromCenterRadius builds {c - r, c + r}. Overlaps / Contains are inclusive on borders (touching counts). No constructor validation — a Min > Max box is simply empty under these tests.

EcsMath

csharp
public static class EcsMath
{
    public static float Dot(in Godot.Vector3 a, in Godot.Vector3 b);
    public static Godot.Vector3 Cross(in Godot.Vector3 a, in Godot.Vector3 b);
    public static float LengthSq(in Godot.Vector3 v);
    public static Godot.Vector3 NormalizeSafe(in Godot.Vector3 v);  // Zero when |v|^2 <= 1e-12
    public static Godot.Vector3 Lerp(in Godot.Vector3 a, in Godot.Vector3 b, float t);
    public static bool SphereVsSphere(in Godot.Vector3 a, float ra, in Godot.Vector3 b, float rb,
        out Godot.Vector3 normal, out float depth);
    public static Godot.Vector3 ClosestPointBox(in Godot.Vector3 p,
        in Godot.Vector3 boxMin, in Godot.Vector3 boxMax);
    public static bool SphereVsBox(in Godot.Vector3 c, float r,
        in Godot.Vector3 boxMin, in Godot.Vector3 boxMax,
        out Godot.Vector3 normal, out float depth);
    public static void IntegrateSoA(float[] px, float[] py, float[] pz,
        float[] vx, float[] vy, float[] vz, int n, float dt);
    public static void IntegrateSimd(float[] px, float[] py, float[] pz,
        float[] vx, float[] vy, float[] vz, int n, float dt);
}

Contact semantics: touching counts (dist <= ra + rb / dist <= r, depth ~ 0). Outputs on a miss are normal = Vector3.Zero, depth = 0. Degenerate cases pick an arbitrary axis rather than NaN: coincident sphere centers report normal +X with depth = ra + rb; a sphere center inside a box reports the minimum-penetration axis with depth = r + distance-to-nearest-face. IntegrateSoA is the scalar p += v * dt reference kernel; IntegrateSimd is the same kernel via System.Numerics.Vector<float> with a scalar tail for non-multiple counts.

Frustum

csharp
public struct Frustum
{
    // 6 planes as Vector4 (inward normal + W). A point is inside when N.p + W >= 0.
    public Godot.Vector4 P0, P1, P2, P3, P4, P5;
    public static Frustum FromCamera(Godot.Camera3D cam);       // throws on null
    public static Frustum FromCamera2D(Godot.Camera2D cam, Godot.Vector2 viewport);
    public bool Intersects(in Aabb box);                        // p-vertex test
}

FromCamera normalizes each plane from Camera3D.GetFrustum() and flips normals inward against the frustum center, so Intersects holds regardless of the engine's plane convention. FromCamera2D derives 4 side planes from screen-center position, zoom, and viewport size, plus two generous Z planes (-1000..1000) so 3D AABBs still test sensibly; near-zero zoom axes fall back to 1. Intersects tests only the furthest (p-)vertex per plane — exact for boxes.

GodotECS docs — version 0.1.0. All rights reserved until a license is added.