Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:48:52

0001 /**
0002 csg_intersect_leaf_test.cc
0003 ===========================
0004 
0005 ::
0006 
0007     ~/o/CSG/tests/csg_intersect_leaf_test.sh
0008 
0009 
0010 1. creates single CSGNode sphere
0011 2. setup environment for intersect_leaf call
0012 3. does simtrace circle_scan with and without normalization
0013 4. intersects saved into NPFold for python analysis
0014 
0015 
0016 **/
0017 
0018 #include <cstdio>
0019 
0020 #include "ssys.h"
0021 #include "scuda.h"
0022 #include "squad.h"
0023 #include "sqat4.h"
0024 #include "csg_intersect_leaf.h"
0025 
0026 #include "CSGNode.h"
0027 #include "NPFold.h"
0028 
0029 
0030 struct Geometry
0031 {
0032     CSGNode nd ;
0033     const float4* plan ;
0034     const CSGNode* node ;
0035 
0036     std::vector<qat4> tran ;
0037     std::vector<qat4> itra ;
0038 
0039     Geometry(float z_scale=0.5f);
0040 
0041     bool simtrace( quad4& p, bool norm ) const ;
0042     NP* circle_scan(bool norm) const ;
0043 };
0044 
0045 
0046 inline Geometry::Geometry(float z_scale)
0047     :
0048     nd(CSGNode::Sphere(100.f)),
0049     plan(nullptr),
0050     node(&nd)
0051 {
0052     std::array<float,16> ta = { 1.f , 0.f, 0.f, 0.f,
0053                                 0.f , 1.f, 0.f, 0.f,
0054                                 0.f , 0.f, z_scale, 0.f,
0055                                 0.f , 0.f, 0.f, 1.f } ;
0056 
0057     std::array<float,16> va = { 1.f , 0.f, 0.f,  0.f,
0058                                 0.f , 1.f, 0.f,  0.f,
0059                                 0.f , 0.f, 1.f/z_scale, 0.f,
0060                                 0.f , 0.f, 0.f,  1.f } ;
0061 
0062     qat4 t(ta.data()) ;
0063     qat4 v(va.data()) ;
0064 
0065     tran.push_back(t);
0066     itra.push_back(v);
0067 
0068     nd.setTransform( 1u + 0u );   // 0u means none
0069 }
0070 
0071 /**
0072 Geometry::simtrace
0073 -------------------
0074 
0075 Follow quad4 layout from CSGQuery::simtrace
0076 
0077 Notice no mystery regarding access to the transforms, the itra is
0078 simply an argument to the intersect_leaf call.
0079 
0080 **/
0081 
0082 bool Geometry::simtrace( quad4& p, bool norm ) const
0083 {
0084     float3* ray_origin = p.v2() ;
0085     float3* ray_direction = p.v3() ;
0086     float t_min = p.q1.f.w ;
0087 
0088     // the 1st float4 argumnent gives surface normal at intersect and distance
0089 
0090     float4& isect = p.q0.f ;
0091     bool valid_isect = false ;
0092     bool dumpxyz = false ;
0093     intersect_leaf(valid_isect, isect, node, plan, itra.data(), t_min, *ray_origin, *ray_direction, dumpxyz ) ;
0094     if( valid_isect )
0095     {
0096         if(norm)
0097         {
0098             float3* nrm = p.v0();
0099             *nrm = normalize(*nrm);
0100         }
0101 
0102         float t = p.q0.f.w ;
0103         float3 ipos = (*ray_origin) + t*(*ray_direction) ;
0104         p.q1.f.x = ipos.x ;
0105         p.q1.f.y = ipos.y ;
0106         p.q1.f.z = ipos.z ;
0107         //p.q1.f.w = distance(ipos) ;     // HMM: overwrite of tmin is problematic
0108     }
0109     return valid_isect ;
0110 }
0111 
0112 
0113 NP* Geometry::circle_scan(bool norm) const
0114 {
0115     const int N = 360 ;
0116     NP* a = NP::Make<float>(N,4,4);
0117     quad4* aa = a->values<quad4>()  ;
0118 
0119     for(int i=0 ; i < N ; i++)
0120     {
0121         quad4& q = aa[i] ;
0122 
0123         float phi = M_PIf*float(i)/180.f ;
0124 
0125         float& t_min = q.q1.f.w ;
0126         float3* ori = q.v2() ;
0127         float3* dir = q.v3() ;
0128 
0129         t_min = 0.f ;
0130 
0131         ori->x = 0.f ;
0132         ori->y = 0.f ;
0133         ori->z = 0.f ;
0134 
0135         dir->x = cos(phi) ;
0136         dir->y = 0.f ;
0137         dir->z = sin(phi) ;
0138 
0139         simtrace(q, norm);
0140     }
0141     return a ;
0142 }
0143 
0144 
0145 void test_intersect_leaf()
0146 {
0147     float z_scale = 0.5f ;
0148     //float z_scale = 1.0f ;
0149 
0150     Geometry g(z_scale) ;
0151 
0152     NPFold* f = new NPFold ;
0153     f->add("a", g.circle_scan(false) );
0154     f->add("b", g.circle_scan(true) );
0155     f->save("$FOLD");
0156 }
0157 
0158 
0159 int main()
0160 {
0161     test_intersect_leaf() ;
0162 
0163     return 0 ;
0164 }