File indexing completed on 2026-04-09 07:49:47
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008 #include <cassert>
0009 #include <iostream>
0010 #include <iomanip>
0011
0012 #include <glm/glm.hpp>
0013 #include "scuda.h"
0014 #include "squad.h"
0015 #include "sgeomdefs.h"
0016
0017 #include "G4VSolid.hh"
0018 #include "G4ThreeVector.hh"
0019
0020 struct ssolid
0021 {
0022 static void GetCenterExtent( float4& ce, const G4VSolid* solid );
0023 static void GetCenterExtent( glm::tvec4<double>& ce, const G4VSolid* solid );
0024 static G4double Distance_(const G4VSolid* solid, const G4ThreeVector& pos, const G4ThreeVector& dir, EInside& in,
0025 G4ThreeVector* isect=nullptr
0026 );
0027 static G4double Distance(const G4VSolid* solid, const G4ThreeVector& pos, const G4ThreeVector& dir, bool dump );
0028 static void Simtrace( quad4& p, const G4VSolid* solid, bool dump=false);
0029 };
0030
0031 inline void ssolid::GetCenterExtent( glm::tvec4<double>& ce, const G4VSolid* solid )
0032 {
0033 G4ThreeVector pMin ;
0034 G4ThreeVector pMax ;
0035 solid->BoundingLimits(pMin, pMax);
0036 G4ThreeVector center = ( pMin + pMax )/2. ;
0037 G4ThreeVector fulldiag = pMax - pMin ;
0038 G4ThreeVector halfdiag = fulldiag/2. ;
0039 G4double extent = std::max( std::max( halfdiag.x(), halfdiag.y() ), halfdiag.z() ) ;
0040
0041 ce.x = center.x() ;
0042 ce.y = center.y() ;
0043 ce.z = center.z() ;
0044 ce.w = extent ;
0045 }
0046
0047 inline void ssolid::GetCenterExtent( float4& ce, const G4VSolid* solid )
0048 {
0049 glm::tvec4<double> ce_ ;
0050 GetCenterExtent(ce_, solid );
0051 ce.x = ce_.x ;
0052 ce.y = ce_.y ;
0053 ce.z = ce_.z ;
0054 ce.w = ce_.w ;
0055 }
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 inline G4double ssolid::Distance_(const G4VSolid* solid, const G4ThreeVector& pos, const G4ThreeVector& dir, EInside& in,
0067 G4ThreeVector* isect
0068 )
0069 {
0070 in = solid->Inside(pos) ;
0071 G4double t = kInfinity ;
0072 switch( in )
0073 {
0074 case kInside: t = solid->DistanceToOut( pos, dir ) ; break ;
0075 case kSurface: t = solid->DistanceToOut( pos, dir ) ; break ;
0076 case kOutside: t = solid->DistanceToIn( pos, dir ) ; break ;
0077 default: assert(0) ;
0078 }
0079 if( t != kInfinity && isect != nullptr ) *isect = pos+t*dir ;
0080 return t ;
0081 }
0082
0083
0084
0085 inline G4double ssolid::Distance(const G4VSolid* solid, const G4ThreeVector& pos, const G4ThreeVector& dir, bool dump )
0086 {
0087 EInside in ;
0088 G4double t = Distance_( solid, pos, dir, in );
0089
0090 if(dump && t != kInfinity)
0091 {
0092 std::cout
0093 << " pos "
0094 << "("
0095 << std::fixed << std::setw(10) << std::setprecision(3) << pos.x() << " "
0096 << std::fixed << std::setw(10) << std::setprecision(3) << pos.y() << " "
0097 << std::fixed << std::setw(10) << std::setprecision(3) << pos.z()
0098 << ")"
0099 << " dir "
0100 << "("
0101 << std::fixed << std::setw(10) << std::setprecision(3) << dir.x() << " "
0102 << std::fixed << std::setw(10) << std::setprecision(3) << dir.y() << " "
0103 << std::fixed << std::setw(10) << std::setprecision(3) << dir.z()
0104 << ")"
0105 << " in " << sgeomdefs::EInside_(in )
0106 ;
0107
0108 if( t == kInfinity)
0109 {
0110 std::cout
0111 << " t " << std::setw(10) << "kInfinity"
0112 << std::endl
0113 ;
0114 }
0115 else
0116 {
0117 G4ThreeVector ipos = pos + dir*t ;
0118 std::cout
0119 << " t " << std::fixed << std::setw(10) << std::setprecision(3) << t
0120 << " ipos "
0121 << "("
0122 << std::fixed << std::setw(10) << std::setprecision(3) << ipos.x() << " "
0123 << std::fixed << std::setw(10) << std::setprecision(3) << ipos.y() << " "
0124 << std::fixed << std::setw(10) << std::setprecision(3) << ipos.z()
0125 << ")"
0126 << std::endl
0127 ;
0128 }
0129 }
0130 return t ;
0131 }
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 inline void ssolid::Simtrace(quad4& p, const G4VSolid* solid, bool dump)
0155 {
0156 G4ThreeVector ori(p.q2.f.x, p.q2.f.y, p.q2.f.z);
0157 G4ThreeVector dir(p.q3.f.x, p.q3.f.y, p.q3.f.z);
0158
0159 G4double t = Distance( solid, ori, dir, dump );
0160
0161
0162 if( t == kInfinity ) return ;
0163
0164 G4ThreeVector ipos = ori + dir*t ;
0165 float tmin = 0.f ;
0166
0167 G4ThreeVector inrm = solid->SurfaceNormal(ipos) ;
0168 p.q0.f.x = float(inrm.x()) ;
0169 p.q0.f.y = float(inrm.y()) ;
0170 p.q0.f.z = float(inrm.z()) ;
0171 p.q0.f.w = t ;
0172
0173 p.q1.f.x = float(ipos.x()) ;
0174 p.q1.f.y = float(ipos.y()) ;
0175 p.q1.f.z = float(ipos.z()) ;
0176 p.q1.f.w = tmin ;
0177 }
0178
0179