@@ -31,6 +31,58 @@ namespace hiprt
3131{
3232class alignas ( alignof ( float3 ) ) Triangle
3333{
34+ private:
35+ template <uint32_t N>
36+ struct PolygonN
37+ {
38+ static constexpr uint32_t MaxVertexCount = N;
39+ float3 m_vertices[MaxVertexCount];
40+ uint32_t m_count;
41+ };
42+ using Polygon = PolygonN<16 >;
43+
44+ HIPRT_HOST_DEVICE static bool inside ( const float3& p, uint32_t axis, float pos, bool isMin, const float maxExtent )
45+ {
46+ if ( isMin )
47+ return ( &p.x )[axis] >= pos - ObbEpsilon * maxExtent;
48+ else
49+ return ( &p.x )[axis] <= pos + ObbEpsilon * maxExtent;
50+ }
51+
52+ HIPRT_HOST_DEVICE static float3 intersect ( const float3& a, const float3& b, uint32_t axis, float pos )
53+ {
54+ float da = ( &a.x )[axis] - pos;
55+ float db = ( &b.x )[axis] - pos;
56+ float t = da / ( da - db );
57+ return a + t * ( b - a );
58+ }
59+
60+ HIPRT_HOST_DEVICE static void
61+ clip ( const Polygon& inPoly, uint32_t axis, float pos, bool isMin, Polygon& outPoly, const float maxExtent )
62+ {
63+ outPoly.m_count = 0 ;
64+ if ( inPoly.m_count == 0 ) return ;
65+
66+ for ( uint32_t i = 0 ; i < inPoly.m_count ; i++ )
67+ {
68+ const float3& curr = inPoly.m_vertices [i];
69+ const float3& prev = inPoly.m_vertices [( i + inPoly.m_count - 1 ) % inPoly.m_count ];
70+ bool currIn = inside ( curr, axis, pos, isMin, maxExtent );
71+ bool prevIn = inside ( prev, axis, pos, isMin, maxExtent );
72+
73+ if ( currIn )
74+ {
75+ if ( !prevIn ) outPoly.m_vertices [outPoly.m_count ++] = intersect ( prev, curr, axis, pos );
76+ if ( outPoly.m_count < Polygon::MaxVertexCount ) outPoly.m_vertices [outPoly.m_count ++] = curr;
77+ }
78+ else if ( prevIn )
79+ {
80+ if ( outPoly.m_count < Polygon::MaxVertexCount )
81+ outPoly.m_vertices [outPoly.m_count ++] = intersect ( prev, curr, axis, pos );
82+ }
83+ }
84+ }
85+
3486 public:
3587 Triangle () = default ;
3688
@@ -109,44 +161,28 @@ class alignas( alignof( float3 ) ) Triangle
109161 rightBox.intersect ( box );
110162 }
111163
112- template <typename BoundingVolume>
113- HIPRT_HOST_DEVICE void
114- crop ( const uint32_t axis, const float position, const Aabb& box, BoundingVolume& boundingVolume ) const
164+ HIPRT_HOST_DEVICE Obb obb ( const Aabb& box, uint32_t matrixIndex ) const
115165 {
116- // use enlarged box to make sure that the split points are inside
117- Aabb enlargedBox = box;
118- enlargedBox.m_min -= ObbEnlargeEpsilon * box.extent ();
119- enlargedBox.m_max += ObbEnlargeEpsilon * box.extent ();
120-
121- Aabb croppedBox;
122- const float3* vertices = &m_v0;
123- const float3* v1 = &vertices[2 ];
124- for ( uint32_t i = 0 ; i < 3 ; i++ )
125- {
126- const float3* v0 = v1;
127- v1 = &vertices[i];
128- const float v0p = ( &v0->x )[axis];
129- const float v1p = ( &v1->x )[axis];
130-
131- if ( enlargedBox.contains ( *v0 ) )
132- {
133- boundingVolume.grow ( *v0 );
134- croppedBox.grow ( *v0 );
135- }
136-
137- if ( ( v0p < position && v1p > position ) || ( v0p > position && v1p < position ) )
138- {
139- const float3 t = mix ( *v0, *v1, clamp ( ( position - v0p ) / ( v1p - v0p ), 0 .0f , 1 .0f ) );
140- if ( enlargedBox.contains ( t ) )
141- {
142- boundingVolume.grow ( t );
143- croppedBox.grow ( t );
144- }
145- }
146- }
147-
148- // fallback when the cropped box is invalid
149- if ( !croppedBox.valid () ) boundingVolume.grow ( box );
166+ Polygon poly0, poly1;
167+ poly0.m_vertices [0 ] = m_v0;
168+ poly0.m_vertices [1 ] = m_v1;
169+ poly0.m_vertices [2 ] = m_v2;
170+ poly0.m_count = 3 ;
171+ poly1.m_count = 0 ;
172+
173+ const float maxExtent = fmaxf ( fmaxf ( box.extent ().x , box.extent ().y ), box.extent ().z );
174+ clip ( poly0, 0 , box.m_min .x , true , poly1, maxExtent );
175+ clip ( poly1, 0 , box.m_max .x , false , poly0, maxExtent );
176+ clip ( poly0, 1 , box.m_min .y , true , poly1, maxExtent );
177+ clip ( poly1, 1 , box.m_max .y , false , poly0, maxExtent );
178+ clip ( poly0, 2 , box.m_min .z , true , poly1, maxExtent );
179+ clip ( poly1, 2 , box.m_max .z , false , poly0, maxExtent );
180+
181+ Obb obb ( matrixIndex );
182+ for ( uint32_t i = 0 ; i < poly0.m_count ; i++ )
183+ obb.grow ( poly0.m_vertices [i] );
184+
185+ return obb;
150186 }
151187
152188 HIPRT_HOST_DEVICE Aabb aabb () const
0 commit comments