#pragma once #include #include "pxl8_types.h" #if defined(__x86_64__) || defined(_M_X64) #include #elif defined(__aarch64__) || defined(_M_ARM64) #include #endif #define PXL8_PI 3.14159265358979323846f #define PXL8_TAU (PXL8_PI * 2.0f) static inline f32 pxl8_fast_inv_sqrt(f32 x) { #if defined(__x86_64__) || defined(_M_X64) __m128 v = _mm_set_ss(x); v = _mm_rsqrt_ss(v); return _mm_cvtss_f32(v); #elif defined(__aarch64__) || defined(_M_ARM64) float32x2_t v = vdup_n_f32(x); float32x2_t est = vrsqrte_f32(v); est = vmul_f32(est, vrsqrts_f32(vmul_f32(v, est), est)); return vget_lane_f32(est, 0); #else f32 half = 0.5f * x; i32 i = *(i32*)&x; i = 0x5f3759df - (i >> 1); x = *(f32*)&i; x = x * (1.5f - half * x * x); return x; #endif } static inline f32 pxl8_fast_rcp(f32 x) { #if defined(__x86_64__) || defined(_M_X64) __m128 v = _mm_set_ss(x); __m128 rcp = _mm_rcp_ss(v); rcp = _mm_add_ss(rcp, _mm_mul_ss(rcp, _mm_sub_ss(_mm_set_ss(1.0f), _mm_mul_ss(v, rcp)))); return _mm_cvtss_f32(rcp); #elif defined(__aarch64__) || defined(_M_ARM64) float32x2_t v = vdup_n_f32(x); float32x2_t est = vrecpe_f32(v); est = vmul_f32(est, vrecps_f32(v, est)); return vget_lane_f32(est, 0); #else return 1.0f / x; #endif } typedef struct pxl8_vec2 { f32 x, y; } pxl8_vec2; typedef struct pxl8_vec3 { f32 x, y, z; } pxl8_vec3; typedef struct pxl8_vec4 { f32 x, y, z, w; } pxl8_vec4; typedef struct pxl8_mat4 { f32 m[16]; } pxl8_mat4; typedef struct pxl8_plane { f32 distance; pxl8_vec3 normal; } pxl8_plane; typedef struct pxl8_frustum { pxl8_plane planes[6]; } pxl8_frustum; typedef struct pxl8_projected_point { f32 depth; i32 x; i32 y; bool visible; } pxl8_projected_point; #ifdef __cplusplus extern "C" { #endif u32 pxl8_hash32(u32 x); pxl8_vec2 pxl8_vec2_add(pxl8_vec2 a, pxl8_vec2 b); f32 pxl8_vec2_dot(pxl8_vec2 a, pxl8_vec2 b); f32 pxl8_vec2_length(pxl8_vec2 v); pxl8_vec2 pxl8_vec2_normalize(pxl8_vec2 v); pxl8_vec2 pxl8_vec2_scale(pxl8_vec2 v, f32 s); pxl8_vec2 pxl8_vec2_sub(pxl8_vec2 a, pxl8_vec2 b); pxl8_vec3 pxl8_vec3_add(pxl8_vec3 a, pxl8_vec3 b); pxl8_vec3 pxl8_vec3_cross(pxl8_vec3 a, pxl8_vec3 b); f32 pxl8_vec3_dot(pxl8_vec3 a, pxl8_vec3 b); f32 pxl8_vec3_length(pxl8_vec3 v); pxl8_vec3 pxl8_vec3_lerp(pxl8_vec3 a, pxl8_vec3 b, f32 t); pxl8_vec3 pxl8_vec3_normalize(pxl8_vec3 v); pxl8_vec3 pxl8_vec3_scale(pxl8_vec3 v, f32 s); pxl8_vec3 pxl8_vec3_sub(pxl8_vec3 a, pxl8_vec3 b); pxl8_mat4 pxl8_mat4_identity(void); pxl8_mat4 pxl8_mat4_lookat(pxl8_vec3 eye, pxl8_vec3 center, pxl8_vec3 up); pxl8_mat4 pxl8_mat4_multiply(pxl8_mat4 a, pxl8_mat4 b); pxl8_vec3 pxl8_mat4_multiply_vec3(pxl8_mat4 m, pxl8_vec3 v); pxl8_vec4 pxl8_mat4_multiply_vec4(pxl8_mat4 m, pxl8_vec4 v); pxl8_mat4 pxl8_mat4_orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far); pxl8_mat4 pxl8_mat4_perspective(f32 fov, f32 aspect, f32 near, f32 far); pxl8_mat4 pxl8_mat4_rotate_x(f32 angle); pxl8_mat4 pxl8_mat4_rotate_y(f32 angle); pxl8_mat4 pxl8_mat4_rotate_z(f32 angle); pxl8_mat4 pxl8_mat4_scale(f32 x, f32 y, f32 z); pxl8_mat4 pxl8_mat4_translate(f32 x, f32 y, f32 z); pxl8_frustum pxl8_frustum_from_matrix(pxl8_mat4 vp); bool pxl8_frustum_test_aabb(const pxl8_frustum* frustum, pxl8_vec3 min, pxl8_vec3 max); #ifdef __cplusplus } #endif