File indexing completed on 2026-04-09 07:49:30
0001 #pragma once
0002
0003 #if defined(__CUDACC__) || defined(__CUDABE__)
0004 #else
0005 #include <sstream>
0006 #include <iostream>
0007 #include <iomanip>
0008 #include <vector>
0009 #include <string>
0010 #endif
0011
0012 #define AABB_METHOD inline
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 struct AABB
0027 {
0028 float3 mn ;
0029 float3 mx ;
0030
0031 static AABB Make(const float* v );
0032 const float* data() const ;
0033 float3 center() const ;
0034 float extent() const ;
0035 float4 center_extent() const ;
0036 void center_extent(float4& ce) const ;
0037
0038 bool empty() const ;
0039 void include_point(const float* point);
0040 void include_point(const float3& p);
0041
0042 static bool AllZero(const float* aabb);
0043 void include_aabb( const float* aabb);
0044
0045
0046 #if defined(__CUDACC__) || defined(__CUDABE__)
0047 #else
0048 std::string desc() const ;
0049 static std::string Desc(const float* data);
0050 static std::string Compare(unsigned& mismatch, const float* a, const float* b, int detail, float epsilon=1e-4);
0051 static void cube_corners(std::vector<float3>& corners, const float4& ce );
0052 #endif
0053
0054 };
0055
0056
0057 AABB_METHOD AABB AABB::Make( const float* v )
0058 {
0059 AABB bb = {} ;
0060 bb.mn.x = *(v+0);
0061 bb.mn.y = *(v+1);
0062 bb.mn.z = *(v+2);
0063 bb.mx.x = *(v+3);
0064 bb.mx.y = *(v+4);
0065 bb.mx.z = *(v+5);
0066 return bb ;
0067 }
0068
0069 AABB_METHOD const float* AABB::data() const
0070 {
0071 return (const float*)&mn ;
0072 }
0073 AABB_METHOD float3 AABB::center() const
0074 {
0075 return ( mx + mn )/2.f ;
0076 }
0077 AABB_METHOD float AABB::extent() const
0078 {
0079 float3 d = mx - mn ;
0080 return fmaxf(fmaxf(d.x, d.y), d.z) /2.f ;
0081 }
0082 AABB_METHOD float4 AABB::center_extent() const
0083 {
0084 return make_float4( center(), extent() );
0085 }
0086
0087 AABB_METHOD void AABB::center_extent(float4& ce) const
0088 {
0089 float3 c = center();
0090 ce.x = c.x ;
0091 ce.y = c.y ;
0092 ce.z = c.z ;
0093 ce.w = extent() ;
0094 }
0095
0096 AABB_METHOD bool AABB::empty() const
0097 {
0098 return mn.x == 0.f && mn.y == 0.f && mn.z == 0.f && mx.x == 0.f && mx.y == 0.f && mx.z == 0.f ;
0099 }
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 AABB_METHOD void AABB::include_point(const float* point)
0129 {
0130 const float3 p = make_float3( *(point+0), *(point+1), *(point+2) );
0131 include_point(p);
0132 }
0133
0134 AABB_METHOD void AABB::include_point(const float3& p)
0135 {
0136 if(empty())
0137 {
0138 mn = p ;
0139 mx = p ;
0140 }
0141 else
0142 {
0143 mn = fminf( mn, p );
0144 mx = fmaxf( mx, p );
0145 }
0146 }
0147
0148
0149 AABB_METHOD bool AABB::AllZero(const float* aabb)
0150 {
0151 int count = 0 ;
0152 for(int i=0 ; i < 6 ; i++) if(std::abs(aabb[i]) == 0.f) count += 1 ;
0153 return count == 6 ;
0154 }
0155
0156 AABB_METHOD void AABB::include_aabb(const float* aabb)
0157 {
0158 if(AllZero(aabb)) return ;
0159
0160 const float3 other_mn = make_float3( *(aabb+0), *(aabb+1), *(aabb+2) );
0161 const float3 other_mx = make_float3( *(aabb+3), *(aabb+4), *(aabb+5) );
0162
0163 if(empty())
0164 {
0165 mn = other_mn ;
0166 mx = other_mx ;
0167 }
0168 else
0169 {
0170 mn = fminf( mn, other_mn );
0171 mx = fmaxf( mx, other_mx );
0172 }
0173 }
0174
0175
0176
0177 #if defined(__CUDACC__) || defined(__CUDABE__)
0178 #else
0179
0180 inline std::ostream& operator<<(std::ostream& os, const AABB& bb)
0181 {
0182 os
0183 << " [ "
0184 << bb.mn
0185 << " : "
0186 << bb.mx
0187 << " | "
0188 << ( bb.mx - bb.mn )
0189 << " ] "
0190 ;
0191 return os;
0192 }
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 AABB_METHOD void AABB::cube_corners(std::vector<float3>& corners, const float4& ce )
0223 {
0224 for(int c=0 ; c < 8 ; c++)
0225 {
0226 float3 a = make_float3(
0227 ce.x + ( c & 1 ? ce.w : -ce.w ),
0228 ce.y + ( c & 2 ? ce.w : -ce.w ),
0229 ce.z + ( c & 4 ? ce.w : -ce.w )
0230 ) ;
0231 corners.push_back(a) ;
0232 }
0233 }
0234
0235
0236 AABB_METHOD std::string AABB::desc() const
0237 {
0238 std::stringstream ss ;
0239 ss
0240 << " mn " << mn
0241 << " mx " << mx
0242 ;
0243 std::string s = ss.str();
0244 return s ;
0245 }
0246
0247 AABB_METHOD std::string AABB::Desc(const float* data)
0248 {
0249 std::stringstream ss ;
0250 for(int j=0 ; j < 6 ; j++) ss << std::fixed << std::setw(10) << std::setprecision(2) << *(data + j) << " " ;
0251 std::string s = ss.str();
0252 return s ;
0253 }
0254
0255 AABB_METHOD std::string AABB::Compare(unsigned& mismatch, const float* a, const float* b, int detail, float epsilon)
0256 {
0257 mismatch = 0 ;
0258 std::stringstream ss ;
0259 for(int j=0 ; j < 6 ; j++)
0260 {
0261 float ab = a[j] - b[j] ;
0262
0263 if( detail == 3 )
0264 {
0265 ss
0266 << std::fixed << std::setw(10) << std::setprecision(2) << a[j] << " "
0267 << std::fixed << std::setw(10) << std::setprecision(2) << b[j] << " "
0268 << std::fixed << std::setw(10) << std::setprecision(2) << ab << " "
0269 ;
0270 }
0271 else if( detail == 1 )
0272 {
0273 ss
0274 << std::fixed << std::setw(10) << std::setprecision(2) << ab << " "
0275 ;
0276 }
0277
0278
0279 if(std::abs(ab) > epsilon) mismatch += 1 ;
0280 }
0281 ss << " mismatch " << mismatch ;
0282 std::string s = ss.str();
0283 return s ;
0284 }
0285
0286
0287 #endif
0288
0289