Documentation
    Preparing search index...

    Class Vector3

    Mutable three-component vector (§7b) — the primary vector type of the engine (§7 transforms, §11 motion, §20+ physics). The world is right-handed with +Y up in both 2D and 3D (§7a).

    Allocation policy (§7b, plan D7): instance methods that produce a "this-shaped" result mutate in place and return this; only Vector3.clone allocates. Scalar queries (dot, lengthSq, length) and equalsApprox never allocate and never mutate.

    Change notification (plan D3): every mutator invokes Vector3.onChanged after writing. Direct field writes (v.x = 1) bypass the hook by design.

    Index
    • Parameters

      • x: number = 0
      • y: number = 0
      • z: number = 0

      Returns Vector3

    onChanged?: () => void

    Optional change hook invoked at the end of every mutator. Engine-internal: owners install it, user code normally leaves it unset. It is intentionally not copied by Vector3.copy or Vector3.clone.

    x: number
    y: number
    z: number
    • Allocates a new vector with the same components. The clone has no change hook. This is the only allocating method on the type (§7b).

      Returns Vector3

    • Copies the components of v into this vector. The change hook is not copied.

      Parameters

      Returns this

    • Right-handed cross product, mutating this vector to this × v (this vector is the left operand). Reading the result requires the temporaries below because two components are overwritten before the third is read.

      Aliasing-safe: v may be this. Both operands are read into scalars first, not just the receiver — reading v live while writing this is the whole bug when the two are the same object, and a.cross(a) must be the zero vector.

      Parameters

      Returns this

    • Component-wise approximate equality: true when every component differs by at most epsilon (absolute tolerance).

      Parameters

      • v: Vector3
      • epsilon: number = DEFAULT_EPSILON

      Returns boolean

    • Euclidean length.

      Returns number

    • Moves this vector toward target by the factor t, mutating this vector. t = 0 leaves it unchanged, t = 1 makes it equal to target. Values outside [0, 1] extrapolate; no clamping is applied.

      Parameters

      Returns this

    • Scales this vector to unit length.

      Zero-length behaviour (defined here): normalizing a zero-length vector leaves it at (0, 0, 0) rather than producing NaN or throwing — there is no meaningful direction to pick, and poisoning a hot path with NaN is worse than a no-op. The change hook still fires.

      Range behaviour — the guard below tests the squared length, so three ranges leave this vector non-unit and none of them reports an error (measured from a consumer seat, dogfood cycle 10):

      • Underflow. A vector whose squared length rounds to 0 — every component below about 1.57e-162 — takes the zero-length branch and is left unchanged, non-unit. Just above that bound the square is denormal and has lost most of its mantissa, so the result can be as far off as 0.707 in length.
      • Overflow. A component at or above 1.3407807929942597e+154 squares to Infinity, so 1 / Math.sqrt(lengthSquared) is 0 and every component is written as 0: a large finite vector normalizes to the zero vector.
      • Non-finite input. An infinite component gives NaN in that slot and 0 in the others. A NaN component leaves the vector untouched, because NaN > 0 is false. The zero-length promise above covers a zero input, not a non-finite one — normalize() does produce NaN here.

      Nothing clamps and nothing throws (§85, §61): a hot path that can see such magnitudes scales into range before normalizing.

      Returns this

    • Multiplies every component by the scalar s.

      Parameters

      • s: number

      Returns this

    • Sets all three components.

      Parameters

      • x: number
      • y: number
      • z: number

      Returns this