#pragma once #include #include "vector.h" inline F32 m_deg2rad( F32 deg ) { return deg * PIRAD; } inline F32 m_rad2deg( F32 rad ) { return rad * RADPI; } inline VEC2 m_radial_offset( F32 degrees, F32 distance ) { F32 rad = m_deg2rad( degrees ); F32 x = cos( rad ); F32 y = sin( rad ); VEC2 ret = { x * distance, y * distance }; return ret; } inline F32 m_dist_line_to_point( VEC2 p1, VEC2 p2, VEC2 p ) { if( vec_dist( p1, p2 ) < 0.001f ) return vec_dist( p1, p ); F32 a = p2.y - p1.y; F32 b = p1.x - p2.x; F32 c = p2.x * p1.y - p1.x * p2.y; F32 d = a * p.x + b * p.y + c; F32 n = sqrtf( a * a + b * b ); F32 dot1 = (p.x - p1.x) * (p2.x - p1.x) + (p.y - p1.y) * (p2.y - p1.y); F32 dot2 = (p.x - p2.x) * (p1.x - p2.x) + (p.y - p2.y) * (p1.y - p2.y); if( dot1 < 0 ) return vec_dist( p, p1 ); if( dot2 < 0 ) return vec_dist( p, p2 ); return fabsf( d ) / n; } inline U8 m_point_in_polygon( VEC2 p, VEC2* points, U32 pointc, U32 point_stride = sizeof(VEC2) ) { U8 in = 0; for( U32 i = 0, j = pointc - 1; i < pointc; j = i++ ) { U8* pointarr = (U8*)points; VEC2* pi = (VEC2*)( pointarr + i * point_stride ); VEC2* pj = (VEC2*)( pointarr + j * point_stride ); if( ( pi->y > p.y ) != ( pj->y > p.y ) ) { if( ( p.x < ( pj->x - pi->x ) * ( p.y - pi->y ) / ( pj->y - pi->y ) + pi->x ) ) in = !in; } } return in; } inline F32 m_snap_to_grid( F32 x, F32 grid ) { return x - copysignf( fmodf( fabsf( x ), grid ), x ); } template T min( T a, T b ) { return a < b? a : b; } template T max( T a, T b ) { return a > b? a : b; } template inline T m_clamp( T x, T a, T b ) { return min( max( x, a ), b ); } extern VEC2 m_screen_transform( const VEC3& world );