aabb.h (2948B)
1 #pragma once 2 3 #include "intrinsics.h" 4 #include "log.h" 5 #include "linear_algebra.h" 6 #include "ggformat.h" 7 8 enum Quadrant { 9 QUADRANT_SW, 10 QUADRANT_SE, 11 QUADRANT_NW, 12 QUADRANT_NE, 13 }; 14 15 struct MinMaxu32 { 16 v3u32 mins, maxs; 17 18 MinMaxu32() { } 19 20 explicit MinMaxu32( v3u32 a, v3u32 b ) { 21 mins.x = min( a.x, b.x ); 22 mins.y = min( a.y, b.y ); 23 mins.z = min( a.z, b.z ); 24 maxs.x = max( a.x, b.x ); 25 maxs.y = max( a.y, b.y ); 26 maxs.z = max( a.z, b.z ); 27 } 28 29 MinMaxu32 quadrant( int q ) const; 30 MinMaxu32 clamp_z( u32 lo, u32 hi ); 31 }; 32 33 struct MinMax { 34 v3 mins, maxs; 35 36 MinMax() { } 37 38 explicit MinMax( v3 a, v3 b ) { 39 mins.x = min( a.x, b.x ); 40 mins.y = min( a.y, b.y ); 41 mins.y = min( a.z, b.z ); 42 maxs.y = max( a.x, b.x ); 43 maxs.y = max( a.y, b.y ); 44 maxs.y = max( a.z, b.z ); 45 } 46 47 explicit MinMax( const MinMaxu32 & aabb ) { 48 mins.x = checked_cast< float >( aabb.mins.x ); 49 mins.y = checked_cast< float >( aabb.mins.y ); 50 mins.z = checked_cast< float >( aabb.mins.z / 256.0f ); // TODO: huge hack 51 maxs.x = checked_cast< float >( aabb.maxs.x ); 52 maxs.y = checked_cast< float >( aabb.maxs.y ); 53 maxs.z = checked_cast< float >( aabb.maxs.z / 256.0f ); 54 } 55 56 bool contains( v3 p ) const { 57 return p.x >= mins.x && p.y >= mins.y && p.z >= mins.z && 58 p.x <= maxs.x && p.y <= maxs.y && p.z <= maxs.z; 59 } 60 }; 61 62 struct AABB { 63 v3 centre, extents; 64 65 AABB() { } 66 67 explicit AABB( v3 c, v3 e ) { 68 centre = c; 69 extents = e; 70 } 71 72 explicit AABB( const MinMax & aabb ) { 73 centre = ( aabb.maxs + aabb.mins ) * 0.5f; 74 extents = ( aabb.maxs - aabb.mins ) * 0.5f; 75 } 76 }; 77 78 forceinline MinMaxu32 MinMaxu32::quadrant( int q ) const { 79 switch( q ) { 80 case QUADRANT_SW: { 81 v3u32 mx = maxs; 82 mx.x = mean( mins.x, maxs.x ); 83 mx.y = mean( mins.y, maxs.y ); 84 return MinMaxu32( mins, mx ); 85 } 86 87 case QUADRANT_SE: { 88 v3u32 mn = mins; 89 v3u32 mx = maxs; 90 mn.x = mean( mins.x, maxs.x ); 91 mx.y = mean( mins.y, maxs.y ); 92 return MinMaxu32( mn, mx ); 93 } 94 95 case QUADRANT_NW: { 96 v3u32 mn = mins; 97 v3u32 mx = maxs; 98 mn.y = mean( mins.y, maxs.y ); 99 mx.x = mean( mins.x, maxs.x ); 100 return MinMaxu32( mn, mx ); 101 } 102 103 case QUADRANT_NE: { 104 v3u32 mn = mins; 105 mn.x = mean( mins.x, maxs.x ); 106 mn.y = mean( mins.y, maxs.y ); 107 return MinMaxu32( mn, maxs ); 108 } 109 } 110 111 FATAL( "bad quadrant" ); 112 return MinMaxu32(); 113 } 114 115 forceinline MinMaxu32 MinMaxu32::clamp_z( u32 lo, u32 hi ) { 116 v3u32 mn = mins; 117 v3u32 mx = maxs; 118 mn.z = max( mn.z, lo ); 119 mx.z = min( mx.z, hi ); 120 return MinMaxu32( mn, mx ); 121 } 122 123 inline void format( FormatBuffer * fb, const MinMax & aabb, const FormatOpts & opts ) { 124 format( fb, "MinMax(" ); 125 format( fb, aabb.mins, opts ); 126 format( fb, ", " ); 127 format( fb, aabb.maxs, opts ); 128 format( fb, ")" ); 129 } 130 131 inline void format( FormatBuffer * fb, const MinMaxu32 & aabb, const FormatOpts & opts ) { 132 format( fb, "MinMaxu32(" ); 133 format( fb, aabb.mins, opts ); 134 format( fb, ", " ); 135 format( fb, aabb.maxs, opts ); 136 format( fb, ")" ); 137 }