File indexing completed on 2026-04-09 07:48:52
0001
0002 #include "NPFold.h"
0003
0004 #include "scuda.h"
0005 #include "squad.h"
0006 #include "sqat4.h"
0007 #include "ssys.h"
0008
0009 #include "CSGNode.h"
0010
0011 #include "csg_intersect_leaf.h"
0012 #include "csg_intersect_node.h"
0013 #include "csg_intersect_tree.h"
0014
0015 struct Params
0016 {
0017 CSGNode* node ;
0018 float4* plan ;
0019 qat4* tran ;
0020 qat4* itra ;
0021 float t_min ;
0022 bool dumpxyz ;
0023 };
0024
0025
0026 struct csg_intersect_prim_test
0027 {
0028 static int Main();
0029 static int Intersect(bool& valid_isect, float4& isect, CSGNode* nd, float t_min, const float3 o, const float3 d);
0030 static bool Simtrace( CSGNode* nd, quad4& q );
0031 static NP* XY(CSGNode* nd, int nx, int ny, float x0, float x1, float y0, float y1, float z, float _t_min, float3 d);
0032
0033 static int One(CSGNode* nd, float t_min, const float3 o, const float3 d);
0034 static int SphereOne();
0035 static int CylinderOne();
0036 static int HalfSpaceOne();
0037 static int HalfCylinderOne();
0038 static int HalfCylinderXY();
0039 };
0040
0041 inline int csg_intersect_prim_test::Main()
0042 {
0043 const char* TEST = ssys::getenvvar("TEST", "SphereOne");
0044 bool ALL = strcmp(TEST, "ALL") == 0 ;
0045 int rc = 0 ;
0046 if(ALL||0==strcmp(TEST,"SphereOne")) rc += SphereOne();
0047 if(ALL||0==strcmp(TEST,"CylinderOne")) rc += CylinderOne();
0048 if(ALL||0==strcmp(TEST,"HalfSpaceOne")) rc += HalfSpaceOne();
0049 if(ALL||0==strcmp(TEST,"HalfCylinderOne")) rc += HalfCylinderOne();
0050 if(ALL||0==strcmp(TEST,"HalfCylinderXY")) rc += HalfCylinderXY();
0051 return rc ;
0052 }
0053
0054
0055 inline int csg_intersect_prim_test::Intersect(bool& valid_isect, float4& isect, CSGNode* nd, float t_min, const float3 o, const float3 d)
0056 {
0057 Params params = {} ;
0058 isect.x = 0.f ;
0059 isect.y = 0.f ;
0060 isect.z = 0.f ;
0061 isect.w = 0.f ;
0062 valid_isect = intersect_prim(isect, nd, params.plan, params.itra, t_min , o, d, params.dumpxyz );
0063 return 0 ;
0064 }
0065
0066
0067 inline int csg_intersect_prim_test::One(CSGNode* nd, float t_min, const float3 o, const float3 d)
0068 {
0069 float4 isect ;
0070 bool valid_isect ;
0071 Intersect(valid_isect, isect, nd, t_min, o, d );
0072 printf("// o = np.array([%10.5f,%10.5f,%10.5f]) ; d = np.array([%10.5f,%10.5f,%10.5f]) ; is = %d ; isect = np.array([%10.5f,%10.5f,%10.5f,%10.5f]) \n",
0073 o.x, o.y, o.z,
0074 d.x, d.y, d.z,
0075 valid_isect,
0076 isect.x, isect.y, isect.z, isect.w ) ;
0077 return 0 ;
0078 }
0079 inline int csg_intersect_prim_test::SphereOne()
0080 {
0081 CSGNode nd = CSGNode::Sphere(100.f);
0082 return One(&nd, 0.f, {0.f, 0.f, 0.f}, {0.f, 0.f, 1.f} );
0083 }
0084 inline int csg_intersect_prim_test::CylinderOne()
0085 {
0086 CSGNode nd = CSGNode::Cylinder(100.f, -50.f, 50.f);
0087 return One(&nd, 0.f, {0.f, 0.f, 0.f}, {0.f, 0.f, 1.f} );
0088 }
0089 inline int csg_intersect_prim_test::HalfSpaceOne()
0090 {
0091 float v = 1.f/sqrtf(2.f);
0092 CSGNode nd = CSGNode::HalfSpace(v,v,0.f,0.f);
0093 int rc = 0 ;
0094 rc += One(&nd, 0.f, { 1.f, 1.f, 100.f}, {0.f, 0.f, -1.f} );
0095 rc += One(&nd, 0.f, {-1.f, -1.f, 100.f}, {0.f, 0.f, -1.f} );
0096 return rc ;
0097 }
0098
0099 inline int csg_intersect_prim_test::HalfCylinderOne()
0100 {
0101 CSGNode* nd = CSGNode::HalfCylinder();
0102 int rc = 0 ;
0103 rc += One(nd, 0.f, { 1.f, 1.f, 100.f}, {0.f, 0.f, -1.f} );
0104 rc += One(nd, 0.f, {-1.f, -1.f, 100.f}, {0.f, 0.f, -1.f} );
0105 return rc ;
0106 }
0107
0108
0109
0110 inline NP* csg_intersect_prim_test::XY(CSGNode* nd, int nx, int ny, float x0, float x1, float y0, float y1, float z, float _t_min, float3 ray_direction )
0111 {
0112 const int N = nx*ny ;
0113 NP* xy = NP::Make<float>(N,4,4);
0114 quad4* aa = xy->values<quad4>() ;
0115
0116 for(int iy=0 ; iy < ny ; iy++)
0117 for(int ix=0 ; ix < nx ; ix++)
0118 {
0119 int idx = iy*nx + ix ;
0120 assert( idx < N );
0121
0122 float fx = float(ix)/float(nx-1) ;
0123 float fy = float(iy)/float(ny-1) ;
0124 float x = x0 + (x1-x0)*fx ;
0125 float y = y0 + (y1-y0)*fy ;
0126
0127 quad4& q = aa[idx] ;
0128
0129 float& t_min = q.q1.f.w ;
0130 float3* o = q.v2() ;
0131 float3* d = q.v3() ;
0132
0133 t_min = _t_min ;
0134
0135 o->x = x ;
0136 o->y = y ;
0137 o->z = z ;
0138
0139 d->x = ray_direction.x ;
0140 d->y = ray_direction.y ;
0141 d->z = ray_direction.z ;
0142
0143 Simtrace(nd, q );
0144 }
0145 return xy ;
0146 }
0147
0148 bool csg_intersect_prim_test::Simtrace( CSGNode* nd, quad4& q )
0149 {
0150 float3* ray_origin = q.v2() ;
0151 float3* ray_direction = q.v3() ;
0152 float t_min = q.q1.f.w ;
0153
0154 float4& isect = q.q0.f ;
0155 bool valid_isect = false ;
0156 bool dumpxyz = false ;
0157 Intersect(valid_isect, isect, nd, t_min, *ray_origin, *ray_direction ) ;
0158 if( valid_isect )
0159 {
0160 float t = isect.w ;
0161 float3 ipos = (*ray_origin) + t*(*ray_direction) ;
0162 q.q1.f.x = ipos.x ;
0163 q.q1.f.y = ipos.y ;
0164 q.q1.f.z = ipos.z ;
0165 }
0166 return valid_isect ;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 inline int csg_intersect_prim_test::HalfCylinderXY()
0196 {
0197 float radius = 100.f ;
0198 CSGNode* nd = nullptr ;
0199 {
0200 float v = 1.f/sqrtf(2.f);
0201 float z0 = -50.f ;
0202 float z1 = 50.f ;
0203 nd = CSGNode::HalfCylinder(v,v,0.f,0.f, radius, z0, z1);
0204 }
0205
0206
0207
0208 float oz = 100.f ;
0209 float3 d = {0.f, 0.f, -1.f} ;
0210 float t_min = 0.f ;
0211
0212 int nx = 41 ;
0213 int ny = 41 ;
0214
0215 float ext = radius*1.1f ;
0216
0217 NP* xy = XY(nd, nx, ny, -ext, ext, -ext, ext, oz, t_min, d );
0218
0219 std::cout << "csg_intersect_prim_test::HalfCylinderXY xy " << ( xy ? xy->sstr() : "-" ) << "\n" ;
0220
0221 NPFold* f = new NPFold ;
0222 f->add("xy", xy);
0223 f->save("$FOLD/$TEST");
0224
0225 return 0 ;
0226 }
0227
0228 int main()
0229 {
0230 return csg_intersect_prim_test::Main() ;
0231 }
0232
0233