# math.inl ## Overview
Math library for basic operations on vectors, matrices and quaternions.
## Index
Constants
`TM_PI`
`TM_PI_D`

Vec2
`tm_vec2_add()`
`tm_vec2_sub()`
`tm_vec2_dot()`
`tm_vec2_cross()`
`tm_vec2_mul()`
`tm_vec2_mul_add()`
`tm_vec2_element_mul()`
`tm_vec2_element_div()`
`tm_vec2_length()`
`tm_vec2_normalize()`
`tm_vec2_equal()`
`tm_vec2_lerp()`
`tm_vec2_min()`
`tm_vec2_max()`
`tm_vec2_dist_sqr()`

Vec3
`tm_vec3_add()`
`tm_vec3_sub()`
`tm_vec3_dot()`
`tm_vec3_cross()`
`tm_vec3_mul()`
`tm_vec3_mul_add()`
`tm_vec3_element_mul()`
`tm_vec3_element_div()`
`tm_vec3_length()`
`tm_vec3_normalize()`
`tm_vec3_equal()`
`tm_vec3_lerp()`
`tm_vec3_min()`
`tm_vec3_max()`
`tm_vec3_dist_sqr()`

Vec4
`tm_vec4_add()`
`tm_vec4_sub()`
`tm_vec4_dot()`
`tm_vec4_mul()`
`tm_vec4_mul_add()`
`tm_vec4_element_mul()`
`tm_vec4_element_div()`
`tm_vec4_length()`
`tm_vec4_normalize()`
`tm_vec4_equal()`
`tm_vec4_lerp()`
`tm_vec4_min()`
`tm_vec4_max()`
`tm_vec4_dist_sqr()`

Mat44
`tm_mat44_identity()`
`tm_mat44_from_translation()`
`tm_mat44_from_scale()`
`tm_mat44_from_quaternion()`
`tm_xyz_from_quaternion()`
`tm_mat44_from_translation_quaternion_scale()`
`tm_mat44_mul()`
`tm_mat44_inverse()`
`tm_mat44_transform()`
`tm_mat44_transform_no_translation()`
`tm_mat44_transform_vec4()`
`tm_matr44_determinant()`
`tm_mat44_determinant33()`
`tm_mat44_to_quaternion()`
`tm_mat44_to_translation_quaternion_scale()`
`tm_mat44_x()`
`tm_mat44_y()`
`tm_mat44_z()`
`tm_mat44_w()`
`tm_mat44_x_vec4()`
`tm_mat44_y_vec4()`
`tm_mat44_z_vec4()`
`tm_mat44_w_vec4()`

Quaternion
`tm_quaternion_from_rotation()`
`tm_quaternion_to_rotation()`
`tm_quaternion_mul()`
`tm_quaternion_inverse()`
`tm_quaternion_rotate_vec3()`
`tm_quaternion_nlerp()`
`tm_quaternion_to_euler()`
`tm_euler_to_quaternion()`

uint32_t
`tm_uint32_count_bits()`
`tm_uint32_count_trailing_zero_bits()`
`tm_uint32_count_leading_zero_bits()`
`tm_uint32_log()`
`tm_uint32_round_up_to_power_of_two()`
`tm_uint32_align_to_power_of_two()`
`tm_uint32_div_ceil()`

uint64_t
`tm_uint64_align_to_power_of_two()`
`tm_uint64_div_ceil()`

float
`tm_lerp()`
`tm_inv_lerp()`
`tm_remap()`
`tm_equal_abs_eps()`
## API

Constants

Mathematical constants. ### `TM_PI`
~~~c #define TM_PI 3.14159265f ~~~ Single precision pi.
### `TM_PI_D`
~~~c #define TM_PI_D 3.14159265358979323846 ~~~ Double precision pi.

Vec2

### `tm_vec2_add()`
~~~c static inline tm_vec2_t tm_vec2_add(tm_vec2_t lhs, tm_vec2_t rhs); ~~~
### `tm_vec2_sub()`
~~~c static inline tm_vec2_t tm_vec2_sub(tm_vec2_t lhs, tm_vec2_t rhs); ~~~
### `tm_vec2_dot()`
~~~c static inline float tm_vec2_dot(tm_vec2_t v1, tm_vec2_t v2); ~~~
### `tm_vec2_cross()`
~~~c static inline float tm_vec2_cross(tm_vec2_t v1, tm_vec2_t v2); ~~~
### `tm_vec2_mul()`
~~~c static inline tm_vec2_t tm_vec2_mul(tm_vec2_t lhs, float rhs); ~~~
### `tm_vec2_mul_add()`
~~~c static inline tm_vec2_t tm_vec2_mul_add(tm_vec2_t lhs, tm_vec2_t rhs, float mul); ~~~
### `tm_vec2_element_mul()`
~~~c static inline tm_vec2_t tm_vec2_element_mul(tm_vec2_t lhs, tm_vec2_t rhs); ~~~
### `tm_vec2_element_div()`
~~~c static inline tm_vec2_t tm_vec2_element_div(tm_vec2_t lhs, tm_vec2_t rhs); ~~~
### `tm_vec2_length()`
~~~c static inline float tm_vec2_length(tm_vec2_t v); ~~~
### `tm_vec2_normalize()`
~~~c static inline tm_vec2_t tm_vec2_normalize(tm_vec2_t); ~~~
### `tm_vec2_equal()`
~~~c static inline bool tm_vec2_equal(tm_vec2_t lhs, tm_vec2_t rhs); ~~~
### `tm_vec2_lerp()`
~~~c static inline tm_vec2_t tm_vec2_lerp(tm_vec2_t a, tm_vec2_t b, float t); ~~~
### `tm_vec2_min()`
~~~c static inline tm_vec2_t tm_vec2_min(tm_vec2_t a, tm_vec2_t b); ~~~
### `tm_vec2_max()`
~~~c static inline tm_vec2_t tm_vec2_max(tm_vec2_t a, tm_vec2_t b); ~~~
### `tm_vec2_dist_sqr()`
~~~c static inline float tm_vec2_dist_sqr(tm_vec2_t a, tm_vec2_t b); ~~~

Vec3

### `tm_vec3_add()`
~~~c static inline tm_vec3_t tm_vec3_add(tm_vec3_t lhs, tm_vec3_t rhs); ~~~
### `tm_vec3_sub()`
~~~c static inline tm_vec3_t tm_vec3_sub(tm_vec3_t lhs, tm_vec3_t rhs); ~~~
### `tm_vec3_dot()`
~~~c static inline float tm_vec3_dot(tm_vec3_t v1, tm_vec3_t v2); ~~~
### `tm_vec3_cross()`
~~~c static inline tm_vec3_t tm_vec3_cross(tm_vec3_t lhs, tm_vec3_t rhs); ~~~
### `tm_vec3_mul()`
~~~c static inline tm_vec3_t tm_vec3_mul(tm_vec3_t lhs, float rhs); ~~~
### `tm_vec3_mul_add()`
~~~c static inline tm_vec3_t tm_vec3_mul_add(tm_vec3_t lhs, tm_vec3_t rhs, float mul); ~~~
### `tm_vec3_element_mul()`
~~~c static inline tm_vec3_t tm_vec3_element_mul(tm_vec3_t lhs, tm_vec3_t rhs); ~~~
### `tm_vec3_element_div()`
~~~c static inline tm_vec3_t tm_vec3_element_div(tm_vec3_t lhs, tm_vec3_t rhs); ~~~
### `tm_vec3_length()`
~~~c static inline float tm_vec3_length(tm_vec3_t v); ~~~
### `tm_vec3_normalize()`
~~~c static inline tm_vec3_t tm_vec3_normalize(tm_vec3_t); ~~~
### `tm_vec3_equal()`
~~~c static inline bool tm_vec3_equal(tm_vec3_t lhs, tm_vec3_t rhs); ~~~
### `tm_vec3_lerp()`
~~~c static inline tm_vec3_t tm_vec3_lerp(tm_vec3_t a, tm_vec3_t b, float t); ~~~
### `tm_vec3_min()`
~~~c static inline tm_vec3_t tm_vec3_min(tm_vec3_t a, tm_vec3_t b); ~~~
### `tm_vec3_max()`
~~~c static inline tm_vec3_t tm_vec3_max(tm_vec3_t a, tm_vec3_t b); ~~~
### `tm_vec3_dist_sqr()`
~~~c static inline float tm_vec3_dist_sqr(tm_vec3_t a, tm_vec3_t b); ~~~

Vec4

### `tm_vec4_add()`
~~~c static inline tm_vec4_t tm_vec4_add(tm_vec4_t lhs, tm_vec4_t rhs); ~~~
### `tm_vec4_sub()`
~~~c static inline tm_vec4_t tm_vec4_sub(tm_vec4_t lhs, tm_vec4_t rhs); ~~~
### `tm_vec4_dot()`
~~~c static inline float tm_vec4_dot(tm_vec4_t v1, tm_vec4_t v2); ~~~
### `tm_vec4_mul()`
~~~c static inline tm_vec4_t tm_vec4_mul(tm_vec4_t lhs, float rhs); ~~~
### `tm_vec4_mul_add()`
~~~c static inline tm_vec4_t tm_vec4_mul_add(tm_vec4_t lhs, tm_vec4_t rhs, float mul); ~~~
### `tm_vec4_element_mul()`
~~~c static inline tm_vec4_t tm_vec4_element_mul(tm_vec4_t lhs, tm_vec4_t rhs); ~~~
### `tm_vec4_element_div()`
~~~c static inline tm_vec4_t tm_vec4_element_div(tm_vec4_t lhs, tm_vec4_t rhs); ~~~
### `tm_vec4_length()`
~~~c static inline float tm_vec4_length(tm_vec4_t v); ~~~
### `tm_vec4_normalize()`
~~~c static inline tm_vec4_t tm_vec4_normalize(tm_vec4_t); ~~~
### `tm_vec4_equal()`
~~~c static inline bool tm_vec4_equal(tm_vec4_t lhs, tm_vec4_t rhs); ~~~
### `tm_vec4_lerp()`
~~~c static inline tm_vec4_t tm_vec4_lerp(tm_vec4_t a, tm_vec4_t b, float t); ~~~
### `tm_vec4_min()`
~~~c static inline tm_vec4_t tm_vec4_min(tm_vec4_t a, tm_vec4_t b); ~~~
### `tm_vec4_max()`
~~~c static inline tm_vec4_t tm_vec4_max(tm_vec4_t a, tm_vec4_t b); ~~~
### `tm_vec4_dist_sqr()`
~~~c static inline float tm_vec4_dist_sqr(tm_vec4_t a, tm_vec4_t b); ~~~

Mat44

### `tm_mat44_identity()`
~~~c static inline const tm_mat44_t *tm_mat44_identity(); ~~~
### `tm_mat44_from_translation()`
~~~c static inline void tm_mat44_from_translation(tm_mat44_t *res, tm_vec3_t t); ~~~
### `tm_mat44_from_scale()`
~~~c static inline void tm_mat44_from_scale(tm_mat44_t *res, tm_vec3_t s); ~~~
### `tm_mat44_from_quaternion()`
~~~c static inline void tm_mat44_from_quaternion(tm_mat44_t *res, tm_vec4_t q); ~~~
### `tm_xyz_from_quaternion()`
~~~c static inline void tm_xyz_from_quaternion(tm_vec3_t *x, tm_vec3_t *y, tm_vec3_t *z, tm_vec4_t q); ~~~
### `tm_mat44_from_translation_quaternion_scale()`
~~~c static inline void tm_mat44_from_translation_quaternion_scale(tm_mat44_t *res, tm_vec3_t t, tm_vec4_t q, tm_vec3_t s); ~~~
### `tm_mat44_mul()`
~~~c static inline void tm_mat44_mul(tm_mat44_t *res, const tm_mat44_t *lhs, const tm_mat44_t *rhs); ~~~
### `tm_mat44_inverse()`
~~~c static inline void tm_mat44_inverse(tm_mat44_t *res, const tm_mat44_t *m); ~~~
### `tm_mat44_transform()`
~~~c static inline tm_vec3_t tm_mat44_transform(const tm_mat44_t *m, tm_vec3_t v); ~~~
### `tm_mat44_transform_no_translation()`
~~~c static inline tm_vec3_t tm_mat44_transform_no_translation(const tm_mat44_t *m, tm_vec3_t v); ~~~
### `tm_mat44_transform_vec4()`
~~~c static inline tm_vec4_t tm_mat44_transform_vec4(const tm_mat44_t *m, tm_vec4_t v); ~~~
### `tm_matr44_determinant()`
~~~c static inline float tm_matr44_determinant(const tm_mat44_t *m); ~~~
### `tm_mat44_determinant33()`
~~~c static inline float tm_mat44_determinant33(const tm_mat44_t *m); ~~~
### `tm_mat44_to_quaternion()`
~~~c static inline tm_vec4_t tm_mat44_to_quaternion(const tm_mat44_t *m); ~~~
### `tm_mat44_to_translation_quaternion_scale()`
~~~c static inline void tm_mat44_to_translation_quaternion_scale(tm_vec3_t *t, tm_vec4_t *r, tm_vec3_t *s, const tm_mat44_t *m); ~~~
### `tm_mat44_x()`
~~~c static inline tm_vec3_t *tm_mat44_x(tm_mat44_t *m); ~~~
### `tm_mat44_y()`
~~~c static inline tm_vec3_t *tm_mat44_y(tm_mat44_t *m); ~~~
### `tm_mat44_z()`
~~~c static inline tm_vec3_t *tm_mat44_z(tm_mat44_t *m); ~~~
### `tm_mat44_w()`
~~~c static inline tm_vec3_t *tm_mat44_w(tm_mat44_t *m); ~~~
### `tm_mat44_x_vec4()`
~~~c static inline tm_vec4_t *tm_mat44_x_vec4(tm_mat44_t *m); ~~~
### `tm_mat44_y_vec4()`
~~~c static inline tm_vec4_t *tm_mat44_y_vec4(tm_mat44_t *m); ~~~
### `tm_mat44_z_vec4()`
~~~c static inline tm_vec4_t *tm_mat44_z_vec4(tm_mat44_t *m); ~~~
### `tm_mat44_w_vec4()`
~~~c static inline tm_vec4_t *tm_mat44_w_vec4(tm_mat44_t *m); ~~~

Quaternion

### `tm_quaternion_from_rotation()`
~~~c static inline tm_vec4_t tm_quaternion_from_rotation(tm_vec3_t axis, float a); ~~~
### `tm_quaternion_to_rotation()`
~~~c static inline tm_vec3_t tm_quaternion_to_rotation(tm_vec4_t q, float *a); ~~~
### `tm_quaternion_mul()`
~~~c static inline tm_vec4_t tm_quaternion_mul(tm_vec4_t lhs, tm_vec4_t rhs); ~~~
### `tm_quaternion_inverse()`
~~~c static inline tm_vec4_t tm_quaternion_inverse(tm_vec4_t q); ~~~
### `tm_quaternion_rotate_vec3()`
~~~c static inline tm_vec3_t tm_quaternion_rotate_vec3(tm_vec4_t q, tm_vec3_t v); ~~~
### `tm_quaternion_nlerp()`
~~~c static inline tm_vec4_t tm_quaternion_nlerp(tm_vec4_t a, tm_vec4_t b, float t); ~~~
### `tm_quaternion_to_euler()`
~~~c static tm_vec3_t tm_quaternion_to_euler(tm_vec4_t q); ~~~
### `tm_euler_to_quaternion()`
~~~c static tm_vec4_t tm_euler_to_quaternion(tm_vec3_t xyz); ~~~

uint32_t

### `tm_uint32_count_bits()`
~~~c static inline uint32_t tm_uint32_count_bits(uint32_t v); ~~~ Returns the number of set bits in `v`.
### `tm_uint32_count_trailing_zero_bits()`
~~~c static inline uint32_t tm_uint32_count_trailing_zero_bits(uint32_t v); ~~~ Returns the number of trailing zero bits in `v`.
### `tm_uint32_count_leading_zero_bits()`
~~~c static inline uint32_t tm_uint32_count_leading_zero_bits(uint32_t v); ~~~ Returns the number of leading zero bits in `v`.
### `tm_uint32_log()`
~~~c static inline uint32_t tm_uint32_log(uint32_t v); ~~~ Returns the rounded down 2-logarithm of `v`. This is equal to the bit position of the highest non-zero bit in `v`. `tm_uint32_log(0)` returns `0`.
### `tm_uint32_round_up_to_power_of_two()`
~~~c static inline uint32_t tm_uint32_round_up_to_power_of_two(uint32_t v); ~~~ Rounds `v` up to the next power of 2.
### `tm_uint32_align_to_power_of_two()`
~~~c static inline uint32_t tm_uint32_align_to_power_of_two(uint32_t v, uint32_t p); ~~~ Rounds `v` up to the specified power of 2 `p`.
### `tm_uint32_div_ceil()`
~~~c static inline uint32_t tm_uint32_div_ceil(uint32_t v, uint32_t d); ~~~ Computes the division `v/d`, rounding up the result to the nearest integer value.

uint64_t

### `tm_uint64_align_to_power_of_two()`
~~~c static inline uint64_t tm_uint64_align_to_power_of_two(uint64_t v, uint64_t p); ~~~ Rounds `v` up to the specified power of 2 `p`.
### `tm_uint64_div_ceil()`
~~~c static inline uint64_t tm_uint64_div_ceil(uint64_t v, uint64_t d); ~~~ Computes the division `v/d`, rounding up the result to the nearest integer value.

float

### `tm_lerp()`
~~~c static inline float tm_lerp(float s, float e, float t); ~~~ Linearly interpolates from `s` to `e` a fraction `t` [0,1].
### `tm_inv_lerp()`
~~~c static inline float tm_inv_lerp(float s, float e, float v); ~~~ Computes the fraction `t` that produces the interpolates value `v` in range [`s`, `e`].
### `tm_remap()`
~~~c static inline float tm_remap(float s0, float e0, float s1, float e1, float v); ~~~ Linearly remaps `v` from range [`s0`, `e0`] to range [`s1`, `e1`].
### `tm_equal_abs_eps()`
~~~c static inline bool tm_equal_abs_eps(float a, float b, float eps); ~~~ Compare floats for equality using an absolute EPSILON test. (I.e. the magnitudes of `a` and `b` are not taken into account in the comparison.)