Skip to content

Latest commit

Β 

History

History
279 lines (227 loc) Β· 18.8 KB

File metadata and controls

279 lines (227 loc) Β· 18.8 KB

3D Structs

Page Map

Header Link
Purpose Purpose
Use Cases Use Cases
Struct Table Struct Table
Vector3 Vector3
UVector3 UVector3
IVector3 IVector3
Quaternion Quaternion
Transform3D Transform3D

Purpose

These are the value types 3D APIs use: positions and directions, rotations, and transforms. You compose them for placement, aiming, movement, and interpolation, then hand them to node transform, physics, and camera calls. Like the 2D structs they are cheap Copy values.

Use Cases

  • Place and move 3D nodes: Vector3 positions and velocities feeding set_global_pos_3d! / get_global_pos_3d!, and full Transform3D values.
  • Aim, orbit, and turn: Quaternion rotation, with look_at_3d! to face a target and interpolation for smooth turning.
  • Address a voxel grid or world chunk: UVector3 for unsigned coordinates, IVector3 when they can go negative.
  • Cast rays for line of sight and hitscan: a Vector3 origin and direction passed to physics_raycast_3d!.

Decision Guide

Use Vector3 for spatial values and Quaternion for composed rotation. Use Euler angles only at an authoring boundary that asks for them; repeated Euler composition introduces order and wrap problems. Use a full transform when position, rotation, and scale share ownership. Do not mirror a node's live transform in #[State] unless the stored value represents a distinct goal or snapshot.

Struct Table

Type Fields / Shape Return/use type Use when
Vector3 x: f32, y: f32, z: f32 value type 3D position, size, velocity, ray origin/direction.
UVector3 x: u32, y: u32, z: u32 value type voxel/grid coords, unsigned 3D extents.
IVector3 x: i32, y: i32, z: i32 value type signed voxel/chunk coords, grid offsets.
Quaternion x: f32, y: f32, z: f32, w: f32 value type 3D rotation, aiming, interpolation, vector rotation.
Transform3D position/rotation/scale transform value type local/global 3D node transforms.

Vector3

Signature:

pub struct Vector3 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}

Use when an API needs 3D coordinates, movement, direction, raycast data, physics values, or mesh query points.

Common methods:

Signature Returns Use when
pub const fn Vector3::new(x: f32, y: f32, z: f32) -> Self Vector3 Build a typed 3D value.
pub const fn to_array(self) -> [f32; 3] [f32; 3] Pass to array-based APIs or serialize compact coords.
pub const fn to_tuple(self) -> (f32, f32, f32) (f32, f32, f32) Destructure into normal Rust tuple flow.
pub fn length(&self) -> f32 / pub fn length_squared(&self) -> f32 f32 Measure magnitude; squared avoids sqrt for comparisons.
pub fn normalized(&self) -> Self Vector3 Get safe unit direction.
pub fn distance_to(self, other: Self) -> f32 f32 Measure distance between two 3D points.
pub fn direction_to(self, other: Self) -> Self Vector3 Get direction from one point to another.
pub fn angle_to(self, other: Self) -> f32 f32 Get angle in radians.
pub fn dot(self, rhs: Self) -> f32 f32 Alignment/projection checks.
pub fn cross(self, rhs: Self) -> Self Vector3 Perpendicular axis / normal direction.
pub fn min(self, rhs: Self) -> Self / pub fn max(self, rhs: Self) -> Self Vector3 Pick per-axis lower/upper values.
pub fn clamp(self, min: Self, max: Self) -> Self Vector3 Keep coords inside a per-axis range.
pub fn negated(self) -> Self Vector3 Get negated copy.
pub fn negate(&mut self) -> &mut Self &mut Vector3 Mutate to negated value.
pub fn project_on(self, onto: Self) -> Self Vector3 Project one vector onto another.
pub fn lerped(self, to: Self, t: f32) -> Self Vector3 Get interpolated copy.
pub fn lerp(&mut self, to: Self, t: f32) -> &mut Self &mut Vector3 Mutate toward target in place.
pub fn slerped(self, to: Self, t: f32) -> Self Vector3 Get spherical interpolation copy.
pub fn slerp(&mut self, to: Self, t: f32) -> &mut Self &mut Vector3 Mutate by spherical interpolation in place.

Example:

lifecycle!({
    fn on_update(&self, ctx: &mut ScriptContext<'_, API>) {
        let forward = Vector3::new(0.0, 0.0, -1.0);
        let start = get_global_pos_3d!(ctx.run, ctx.id).unwrap_or(Vector3::ZERO);
        let hit = physics_raycast_3d!(ctx.run, start, forward, 100.0);
        let _ = hit;
    }
});

UVector3

Signature:

pub struct UVector3 {
    pub x: u32,
    pub y: u32,
    pub z: u32,
}

Use when a value must be non-negative and integer-sized in 3 dimensions.

Common methods and conversions:

Signature Returns Use when
pub const fn UVector3::new(x: u32, y: u32, z: u32) -> Self UVector3 Build unsigned 3D coords.
pub const fn to_array(self) -> [u32; 3] [u32; 3] Pass voxel coords to array-based APIs.
pub const fn to_tuple(self) -> (u32, u32, u32) (u32, u32, u32) Destructure into normal Rust tuple flow.
pub fn as_vector3(self) -> Vector3 Vector3 Feed integer coords to float APIs.
pub fn dot(self, rhs: Self) -> u64 u64 Compare unsigned grid direction/alignment.
pub fn length_squared(self) -> u64 u64 Compare unsigned magnitude without sqrt.
pub fn min(self, rhs: Self) -> Self / pub fn max(self, rhs: Self) -> Self UVector3 Pick per-axis lower/upper unsigned values.
pub fn clamp(self, min: Self, max: Self) -> Self UVector3 Keep voxel coords inside a per-axis range.
pub fn negated(self) -> Self UVector3 Get wrapping-negated copy.
pub fn negate(&mut self) -> &mut Self &mut Self Mutate to wrapping-negated value.
pub fn stepped(self, to: Self, step: u32) -> Self UVector3 Get copy moved toward target by fixed step.
pub fn step(&mut self, to: Self, step: u32) -> &mut Self &mut Self Mutate unsigned coords toward target.
pub fn Vector3::as_uvector3_floor(self) -> UVector3 UVector3 Convert to lower grid/voxel cell.
pub fn Vector3::as_uvector3_round(self) -> UVector3 UVector3 Convert with nearest-cell rounding.
pub fn Vector3::as_uvector3_ceil(self) -> UVector3 UVector3 Convert to upper grid/voxel cell.
pub fn Vector3::as_uvector3_saturating(self) -> UVector3 UVector3 Clamp negative/non-finite input to zero.
pub fn UVector3::as_ivector3_saturating(self) -> IVector3 IVector3 Convert unsigned coords to signed coords.

Example:

let voxel = UVector3::new(12, 8, 2);
let world_cell = voxel.as_vector3();
let next_voxel = voxel.stepped(UVector3::new(12, 8, 8), 1);
let packed = next_voxel.to_tuple();
let travel_score = voxel.dot(next_voxel);

IVector3

Signature:

pub struct IVector3 {
    pub x: i32,
    pub y: i32,
    pub z: i32,
}

Use when integer coords may go below zero, such as chunk coords around world origin, signed voxel offsets, or grid cells relative to an actor.

Common methods and conversions:

Signature Returns Use when
pub const fn IVector3::new(x: i32, y: i32, z: i32) -> Self IVector3 Build signed 3D coords.
pub const ZERO: IVector3 / pub const ONE: IVector3 / pub const NEG_ONE IVector3 Common signed constants.
pub const fn to_array(self) -> [i32; 3] [i32; 3] Pass signed coords to array-based APIs.
pub const fn to_tuple(self) -> (i32, i32, i32) (i32, i32, i32) Destructure into normal Rust tuple flow.
pub fn as_vector3(self) -> Vector3 Vector3 Feed signed grid coords to float APIs.
pub fn as_uvector3_saturating(self) -> UVector3 UVector3 Clamp negative coords to zero for sizes.
pub fn dot(self, rhs: Self) -> i64 i64 Compare signed grid direction/alignment.
pub fn length_squared(self) -> i64 i64 Compare signed magnitude without sqrt.
pub fn min(self, rhs: Self) -> Self / pub fn max(self, rhs: Self) -> Self IVector3 Pick per-axis lower/upper signed values.
pub fn clamp(self, min: Self, max: Self) -> Self IVector3 Keep signed coords inside a per-axis range.
pub fn negated(self) -> Self IVector3 Get negated copy.
pub fn negate(&mut self) -> &mut Self &mut Self Mutate to negated value.
pub fn abs(self) -> Self IVector3 Get per-axis absolute values.
pub fn signum(self) -> Self IVector3 Get per-axis sign (-1, 0, or 1).
pub fn stepped(self, to: Self, step: u32) -> Self IVector3 Get copy moved toward target by fixed step.
pub fn step(&mut self, to: Self, step: u32) -> &mut Self &mut Self Mutate signed coords toward target.
pub fn Vector3::as_ivector3_floor(self) -> IVector3 IVector3 Convert to lower grid/voxel cell.
pub fn Vector3::as_ivector3_round(self) -> IVector3 IVector3 Convert with nearest-cell rounding.
pub fn Vector3::as_ivector3_ceil(self) -> IVector3 IVector3 Convert to upper grid/voxel cell.
pub fn Vector3::as_ivector3_saturating(self) -> IVector3 IVector3 Clamp non-finite/out-of-range input.

Example:

let chunk = IVector3::new(-2, 4, 0);
let neighbor = chunk + IVector3::new(0, 0, -1);
let world_cell = neighbor.as_vector3();
let voxel_index = neighbor.as_uvector3_saturating();
let packed = chunk.to_array();
let travel_score = chunk.dot(neighbor);

Quaternion

Signature:

pub struct Quaternion {
    pub x: f32,
    pub y: f32,
    pub z: f32,
    pub w: f32,
}

Use when an API needs 3D rotation. Prefer it over Euler angles for interpolation and stable orientation.

Common methods:

Signature Returns Use when
pub const IDENTITY: Quaternion Quaternion No rotation.
pub const fn Quaternion::new(x: f32, y: f32, z: f32, w: f32) -> Self Quaternion Build explicit quaternion.
pub fn from_euler_xyz(x: f32, y: f32, z: f32) -> Self Quaternion Convert Euler radians to rotation.
pub fn from_euler(euler: Vector3) -> Self Quaternion Convert Euler vector in radians.
pub fn looking_at(direction: Vector3, up: Vector3) -> Self Quaternion Aim local -Z toward direction.
pub fn rotate_vector3(self, v: Vector3) -> Vector3 Vector3 Rotate a vector by this rotation.
pub fn negated(self) -> Self Quaternion Get negated copy.
pub fn negate(&mut self) -> &mut Self &mut Quaternion Mutate to negated value.
pub fn slerped(self, to: Self, t: f32) -> Self Quaternion Smooth spherical interpolation.
pub fn nlerped(self, to: Self, t: f32) -> Self Quaternion Cheaper normalized linear interpolation.
pub fn slerp(&mut self, to: Self, t: f32) -> &mut Self &mut Quaternion Mutate by spherical interpolation.
pub fn nlerp(&mut self, to: Self, t: f32) -> &mut Self &mut Quaternion Mutate by normalized linear interpolation.
pub fn inverse(self) -> Self Quaternion Reverse rotation.
pub fn normalized(self) -> Self Quaternion Normalize after custom math.

Example:

lifecycle!({
    fn on_update(&self, ctx: &mut ScriptContext<'_, API>) {
        let forward = Vector3::new(0.0, 0.0, -1.0);
        let up = Vector3::new(0.0, 1.0, 0.0);
        let rot = Quaternion::looking_at(forward, up);

        set_local_rot_3d!(ctx.run, ctx.id, rot);
    }
});

Transform3D

Use when an API needs full 3D node transform state instead of separate position/rotation/scale calls.

Common APIs:

Signature Returns Use when
pub const IDENTITY: Transform3D Transform3D Reset transform.
pub const fn Transform3D::new(pos: Vector3, rot: Quaternion, scale: Vector3) -> Self Transform3D Build full transform.
pub fn to_mat4(&self) -> Mat4 Mat4 Convert to matrix for render/math transforms.
pub fn from_mat4(mat: Mat4) -> Self Transform3D Extract transform from matrix.
pub fn lerped(self, to: Self, t: f32) -> Self Transform3D Blend full transform with quaternion slerp.
pub fn lerp(&mut self, to: Self, t: f32) -> &mut Self &mut Self Blend full transform in place.
pub fn looking_at(eye: Vector3, target: Vector3, up: Vector3) -> Self Transform3D Build transform positioned at eye aimed at target.
pub fn forward(&self) -> Vector3 Vector3 Local forward axis in world space (rotation * -Z).
pub fn right(&self) -> Vector3 Vector3 Local right axis in world space (rotation * +X).
pub fn up(&self) -> Vector3 Vector3 Local up axis in world space (rotation * +Y).

Use forward()/right()/up() for camera-relative movement, for example a freecam that moves along where it faces:

let _ = with_node_mut!(ctx.run, Camera3D, ctx.id, |camera| {
    let fwd = camera.transform.forward();
    camera.transform.position += fwd * speed * dt;
});

Example:

lifecycle!({
    fn on_init(&self, ctx: &mut ScriptContext<'_, API>) {
        let transform = Transform3D::new(
            Vector3::new(0.0, 2.0, -4.0),
            Quaternion::IDENTITY,
            Vector3::ONE,
        );

        set_local_transform_3d!(ctx.run, ctx.id, transform);
    }
});