Skip to main content
The math utility module provides comprehensive mathematical operations for 3D vector and matrix calculations, including angle conversions, transformations, and geometric computations.

Vector Types

vec2

2D vector class for screen-space coordinates and 2D calculations.
math::vec2<float> screenPos(100.0f, 200.0f);
float length = screenPos.length();
float dot = screenPos.dot_product(otherVec);

Methods

valid()
bool
Returns true if both components are finite numbers
length()
float
Calculate the magnitude of the vector
length_sqr()
float
Calculate squared magnitude (faster, avoids sqrt)
dot_product(vec2)
float
Calculate dot product with another vector

vec3

3D vector class for positions, angles, and directions in 3D space.
math::vec3 position(100.0f, 200.0f, 64.0f);
math::vec3 angle(0.0f, 90.0f, 0.0f);

// Normalize the vector
position.normalize_in_place();

// Calculate distance
float distance = position.dist_to(targetPos);

Methods

valid()
bool
Check if all components are finite
is_zero()
bool
Check if the vector is a zero vector
length()
float
Calculate the 3D magnitude
length_2d()
float
Calculate 2D magnitude (ignoring z component)
dist_to(vec3)
float
Calculate distance to another point
normalize_in_place()
float
Normalize the vector and return original length
normalize()
vec3&
Normalize angles to valid range (x: ±360°, y: ±360°, z: ±50°)
clamp()
vec3
Clamp angles (pitch: ±89°, yaw: ±180°, roll: ±50°)
sanitize()
vec3&
Normalize and clamp the angles
dot_product(vec3)
float
Calculate dot product
cross_product(vec3)
vec3
Calculate cross product

Matrix Types

matrix_3x4

3x4 transformation matrix used for bone matrices and coordinate transformations.
math::matrix_3x4 boneMatrix;
math::vec3 position = math::matrix_position(boneMatrix);

Static Methods

copy(src, dst)
void
Copy matrix from source to destination
multiply(in1, in2, out)
void
Multiply two matrices and store result

matrix_4x4

4x4 matrix used for view-projection transformations.

Angle Operations

angle_vector

Convert an angle to a direction vector.
math::vec3 viewAngle(0.0f, 90.0f, 0.0f);
math::vec3 forward = math::angle_vector(viewAngle);
angle
const math::vec3&
Input angle (pitch, yaw, roll)
return
math::vec3
Forward direction vector

angle_vectors

Convert angles to forward, right, and up vectors.
math::vec3 forward, right, up;
math::angle_vectors(viewAngles, &forward, &right, &up);
angles
const math::vec3&
Input angle
fw
math::vec3*
Output forward vector (required)
rg
math::vec3*
Output right vector (optional)
up
math::vec3*
Output up vector (optional)

vector_angles

Convert a direction vector to angles.
math::vec3 direction(1.0f, 0.0f, 0.0f);
math::vec3 angles;
math::vector_angles(direction, angles);

calculate_angle

Calculate the angle from source position to destination position.
math::vec3 aimAngles = math::calculate_angle(localPos, enemyPos);
src
const math::vec3&
Source position
dst
const math::vec3&
Destination position
return
math::vec3
Normalized angle from src to dst

Transformations

world_to_screen

Project 3D world coordinates to 2D screen coordinates.
math::vec3 worldPos(100.0f, 200.0f, 64.0f);
math::vec3 screenPos;

if (math::world_to_screen(worldPos, screenPos)) {
    // screenPos now contains 2D screen coordinates
    g_render.render_text(screenPos.x, screenPos.y, AL_DEFAULT, FLAG_NONE, "Enemy", font, color::white());
}
Always check the return value - world_to_screen returns false if the position is behind the camera.

vector_transform

Transform a vector by a matrix.
math::vec3 localPos(0.0f, 0.0f, 0.0f);
math::matrix_3x4 boneMatrix = entity->bone_matrix(HITBOX_HEAD);
math::vec3 worldPos = math::vector_transform(localPos, boneMatrix);

matrix_position

Extract position from a transformation matrix.
math::matrix_3x4 matrix = player->bone_matrix(0);
math::vec3 position = math::matrix_position(matrix);

Angle Utilities

clamp_angle

Clamp angles to valid ranges for Source Engine.
math::vec3 angles(120.0f, 270.0f, 0.0f);
math::clamp_angle(angles);
// angles.x clamped to ±89°, angles.y wrapped to ±180°
Pitch is clamped to ±89° and yaw is wrapped to ±180°. Roll is always set to 0.

normalize_yaw

Normalize yaw angle to -180° to 180° range.
float yaw = 270.0f;
float normalized = math::normalize_yaw(yaw); // Returns -90.0f

approach_angle

Smoothly approach a target angle at a given speed.
float currentYaw = 0.0f;
float targetYaw = 90.0f;
float speed = 5.0f;

currentYaw = math::approach_angle(targetYaw, currentYaw, speed);

get_fov

Calculate field of view (FOV) between view angles and a target.
float fov = math::get_fov(viewAngles, localPos, enemyPos);
if (fov < 5.0f) {
    // Enemy is within FOV crosshair
}

Conversion Functions

deg2rad / rad2deg

Convert between degrees and radians.
float radians = math::deg2rad(90.0f);  // π/2
float degrees = math::rad2deg(3.14159f); // ~180°

Utility Functions

min / max

Find minimum or maximum value (supports variadic arguments).
float minimum = math::min(5.0f, 10.0f, 3.0f);  // Returns 3.0f
float maximum = math::max(5.0f, 10.0f, 3.0f);  // Returns 10.0f

random

Generate random number in range.
float spread = math::random(-5.0f, 5.0f);
int randomInt = math::random(1, 100);

Fast Math Functions

Optimized approximations for performance-critical code (in math::util namespace).

fast_sin / fast_cos

float s = math::util::fast_sin(angle);
float c = math::util::fast_cos(angle);
These functions use polynomial approximations and are faster than std::sin/cos but slightly less accurate.

fast_sqrt

SIMD-optimized square root.
float input = 16.0f;
float output;
math::util::fast_sqrt(&output, &input);

sin_cos

Compute both sine and cosine simultaneously.
float s, c;
math::sin_cos(angle, &s, &c);

Constants

math::util::pi   // long double π
math::util::pi_f // float π

Common Patterns

Calculating Aim Angles

math::vec3 localPos = g_ctx.local->get_abs_origin();
math::vec3 enemyHead = enemy->get_hitbox_position(HITBOX_HEAD);

math::vec3 aimAngles = math::calculate_angle(localPos, enemyHead);
aimAngles.sanitize(); // Normalize and clamp

Distance Checking

math::vec3 delta = enemyPos - localPos;
float distance = delta.length();
float distanceSqr = delta.length_sqr(); // Faster for comparisons

if (distanceSqr < (500.0f * 500.0f)) {
    // Enemy within 500 units
}

Converting Bone Positions

math::matrix_3x4 headMatrix = player->bone_matrix(HITBOX_HEAD);
math::vec3 headPos = math::matrix_position(headMatrix);

math::vec3 screenPos;
if (math::world_to_screen(headPos, screenPos)) {
    g_render.render_text(screenPos.x, screenPos.y, AL_DEFAULT, FLAG_NONE, 
                        "HEAD", font, color::red());
}

Build docs developers (and LLMs) love