EBGeometry
Compact, header-only C++ library for fast evaluation of signed distance functions
Loading...
Searching...
No Matches
Classes | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
EBGeometry::TriangleSoAT< T, W > Struct Template Reference

SoA (Structure of Arrays) layout for W triangles, enabling SIMD evaluation. More...

#include <EBGeometry_TriangleSoA.hpp>

Inheritance diagram for EBGeometry::TriangleSoAT< T, W >:
Inheritance graph
[legend]

Classes

struct  LaneSource
 The triangle accessor TriangleDistance::signedDistance() reads lanes [m_offset, m_offset + lanes of V) through: V = T reads one lane, V = SIMD::Pack<T, N> loads N lanes (m_offset a multiple of N, so the loads are aligned). More...
 

Public Member Functions

void pack (const Triangle< T > *tris, uint32_t count) noexcept
 Pack count triangles from tris[0..count-1] into this SoA group.
 
T signedDistance (const Vec3T< T > &a_point) const noexcept
 Evaluate signed distance from a_point to the closest triangle in this group.
 
Array< T, W > signedDistances (const Vec3T< T > &a_point) const noexcept
 Signed distances from a_point to every one of the W lane triangles.
 
uint32_t nearestLane (const Vec3T< T > &a_point, T &a_d2) const noexcept
 The lane nearest a point and its squared distance, without a sign.
 
T signedDistanceAt (uint32_t a_lane, const Vec3T< T > &a_point) const noexcept
 One lane's signed distance: on the host, bit for bit the value signedDistances() gives that lane; on a device, the same to rounding.
 
T rayCrossing (const Vec3T< T > &a_origin, const Vec3T< T > &a_direction, T a_tMin, T a_tMax, uint32_t &a_lane) const noexcept
 Where a ray first crosses a triangle in this group.
 
void rayCrossings (const Vec3T< T > &a_origin, const Vec3T< T > &a_direction, T a_tMin, T a_tMax, T *a_crossings) const noexcept
 Where a ray crosses each triangle in this group.
 
Vec3T< T > getNormal (uint32_t a_lane) const noexcept
 The unit normal of one lane's triangle.
 
template<class BV >
BV computeBoundingVolume () const noexcept
 Compute the bounding volume enclosing all valid triangles in this group.
 
Vec3T< T > getVertex (size_t a_lane, size_t a_vertex) const noexcept
 Vertex a_vertex of the triangle in lane a_lane.
 

Protected Member Functions

T signedDistanceLane (uint32_t a_lane, const Vec3T< T > &a_point) const noexcept
 Signed distance from a_point to the single triangle stored in lane a_lane.
 
template<size_t N>
void signedDistancesSIMD (const Vec3T< T > &a_point, T *a_distances) const noexcept
 Signed distances to the lanes below m_validCount, N at a time, with SIMD::Pack<T, N>.
 
template<size_t N>
void unsignedDistances2SIMD (const Vec3T< T > &a_point, T *a_d2) const noexcept
 Every lane's squared unsigned distance with SIMD packs of N lanes, as signedDistancesSIMD().
 
template<size_t N>
void rayCrossingsSIMD (const Vec3T< T > &a_origin, const Vec3T< T > &a_direction, T a_tMin, T a_tMax, T *a_crossings) const noexcept
 Ray crossings of the lanes below m_validCount, N at a time, with SIMD::Pack<T, N>.
 

Protected Attributes

T m_vx [3][W]
 x-coordinates of vertex positions. m_vx[i][j] = x-coord of vertex i for triangle j.
 
T m_vy [3][W]
 y-coordinates of vertex positions. m_vy[i][j] = y-coord of vertex i for triangle j.
 
T m_vz [3][W]
 z-coordinates of vertex positions. m_vz[i][j] = z-coord of vertex i for triangle j.
 
T m_nx [W]
 x-components of face normals. m_nx[j] = x-component of the face normal for triangle j.
 
T m_ny [W]
 y-components of face normals.
 
T m_nz [W]
 z-components of face normals.
 
T m_vnx [3][W]
 x-components of vertex normals. m_vnx[i][j] = x of vertex normal i for triangle j.
 
T m_vny [3][W]
 y-components of vertex normals. m_vny[i][j] = y of vertex normal i for triangle j.
 
T m_vnz [3][W]
 z-components of vertex normals. m_vnz[i][j] = z of vertex normal i for triangle j.
 
T m_enx [3][W]
 x-components of edge normals. m_enx[i][j] = x of edge normal i for triangle j.
 
T m_eny [3][W]
 y-components of edge normals. m_eny[i][j] = y of edge normal i for triangle j.
 
T m_enz [3][W]
 z-components of edge normals. m_enz[i][j] = z of edge normal i for triangle j.
 
uint32_t m_validCount = 0
 Number of valid (non-padded) triangles in this group (1..W).
 

Detailed Description

template<class T, size_t W>
struct EBGeometry::TriangleSoAT< T, W >

SoA (Structure of Arrays) layout for W triangles, enabling SIMD evaluation.

signedDistance() and signedDistances() evaluate TriangleDistance::signedDistance(), the one triangle kernel, on SIMD::NativeWidth<T, W>() lanes at a time: the widest SSE4.1, AVX or AVX-512F register the compiler's flags provide whose lane count divides W (so W = 8 doubles under AVX takes two 4-lane registers, and W = 4 doubles under SSE4.1 two 2-lane ones). Where no register fits, and in every device pass, the same kernel runs on one triangle at a time.

Warning
This type is over-aligned (up to 64 bytes, for AVX-512F) via alignas. The library's own usage is safe: PackedBVH stores groups (inside TriangleAoSoA) in a Pool-backed PODVector, which reserves each array at its element's alignment inside a block aligned to PoolBaseAlign (256 bytes), and the build-time std::vector staging relies on C++17's std::allocator respecting over-alignment. If you allocate a TriangleSoAT yourself outside of that path — a raw new, a container with a custom/pre-C++17-style allocator, placement-new into externally-owned storage, or a malloc'd buffer — you are responsible for ensuring the memory is aligned to alignof(TriangleSoAT<T, W>); nothing in this class enforces or checks that, and a misaligned SIMD load will crash (or silently read the wrong data on some platforms) rather than failing gracefully.
Template Parameters
TFloating-point precision.
WTriangles per group. Any W works; a multiple of the register's lane count (see the details) is evaluated with SIMD.

Member Function Documentation

◆ computeBoundingVolume()

template<class T , size_t W>
template<class BV >
BV EBGeometry::TriangleSoAT< T, W >::computeBoundingVolume ( ) const
noexcept

Compute the bounding volume enclosing all valid triangles in this group.

Requires the group to have already been packed via pack() (1 <= m_validCount <= W).

Template Parameters
BVBounding volume type (e.g. AABBT<T>); must be constructible from a point array (a Vec3T<T> pointer and a count).
Returns
Bounding volume enclosing all vertices of the m_validCount triangles.

◆ getNormal()

template<class T , size_t W>
Vec3T< T > EBGeometry::TriangleSoAT< T, W >::getNormal ( uint32_t  a_lane) const
noexcept

The unit normal of one lane's triangle.

Parameters
[in]a_laneLane index. Must satisfy 0 <= a_lane < W.
Returns
The face normal.

◆ getVertex()

template<class T , size_t W>
Vec3T< T > EBGeometry::TriangleSoAT< T, W >::getVertex ( size_t  a_lane,
size_t  a_vertex 
) const
inlinenoexcept

Vertex a_vertex of the triangle in lane a_lane.

Parameters
[in]a_laneLane index, below W.
[in]a_vertexVertex index, below 3.
Returns
The vertex.

◆ nearestLane()

template<class T , size_t W>
uint32_t EBGeometry::TriangleSoAT< T, W >::nearestLane ( const Vec3T< T > &  a_point,
T &  a_d2 
) const
noexcept

The lane nearest a point and its squared distance, without a sign.

The first lane, of m_validCount, with the smallest TriangleDistance::unsignedDistance2(): the lane signedDistance() would pick (except where two lanes are equally near to rounding), found without signing every lane. A nearest-triangle search keeps the best of these and signs only the winner, with signedDistanceAt().

Parameters
[in]a_pointThe point.
[out]a_d2The lane's squared distance.
Returns
The lane.

◆ pack()

template<class T , size_t W>
void EBGeometry::TriangleSoAT< T, W >::pack ( const Triangle< T > *  tris,
uint32_t  count 
)
noexcept

Pack count triangles from tris[0..count-1] into this SoA group.

Pads lanes count..W-1 by repeating the last real triangle so that all W lanes hold valid data and SIMD loads never read uninitialized memory.

Parameters
[in]trisSource triangle array with at least count elements. Must not be null.
[in]countNumber of valid triangles to pack. Must satisfy 1 <= count <= W.

◆ rayCrossing()

template<class T , size_t W>
T EBGeometry::TriangleSoAT< T, W >::rayCrossing ( const Vec3T< T > &  a_origin,
const Vec3T< T > &  a_direction,
T  a_tMin,
T  a_tMax,
uint32_t &  a_lane 
) const
noexcept

Where a ray first crosses a triangle in this group.

TriangleRay::crossing() on the m_validCount triangles, SIMD::NativeWidth<T, W>() at a time, from either side of each triangle. The nearest crossing in [a_tMin, a_tMax] wins, the first such lane on a tie. Requires the group to have already been packed via pack() (1 <= m_validCount <= W).

Parameters
[in]a_originRay origin.
[in]a_directionRay direction.
[in]a_tMinStart of the interval.
[in]a_tMaxEnd of the interval.
[out]a_laneSet to the lane of the crossing; unchanged if there is none.
Returns
The distance along the ray of the crossing, or +infinity if there is none.

◆ rayCrossings()

template<class T , size_t W>
void EBGeometry::TriangleSoAT< T, W >::rayCrossings ( const Vec3T< T > &  a_origin,
const Vec3T< T > &  a_direction,
T  a_tMin,
T  a_tMax,
T *  a_crossings 
) const
noexcept

Where a ray crosses each triangle in this group.

The per-lane analogue of rayCrossing(): the same kernel and lane count, without the reduction to the nearest, so that a caller can collect every crossing. Lanes m_validCount..W-1 are +infinity. Requires the group to have already been packed via pack() (1 <= m_validCount <= W).

Parameters
[in]a_originRay origin.
[in]a_directionRay direction.
[in]a_tMinStart of the interval.
[in]a_tMaxEnd of the interval.
[out]a_crossingsW values: each lane's crossing, or +infinity.

◆ rayCrossingsSIMD()

template<class T , size_t W>
template<size_t N>
void EBGeometry::TriangleSoAT< T, W >::rayCrossingsSIMD ( const Vec3T< T > &  a_origin,
const Vec3T< T > &  a_direction,
T  a_tMin,
T  a_tMax,
T *  a_crossings 
) const
protectednoexcept

Ray crossings of the lanes below m_validCount, N at a time, with SIMD::Pack<T, N>.

Host-only, like signedDistancesSIMD(). Lanes of a chunk that starts at or past m_validCount are not written.

Template Parameters
NLane count, SIMD::NativeWidth<T, W>(); must be > 1 and divide W.
Parameters
[in]a_originRay origin.
[in]a_directionRay direction.
[in]a_tMinStart of the interval.
[in]a_tMaxEnd of the interval.
[out]a_crossingsW values, aligned to N * sizeof(T): the crossing, or +infinity.

◆ signedDistance()

template<class T , size_t W>
T EBGeometry::TriangleSoAT< T, W >::signedDistance ( const Vec3T< T > &  a_point) const
noexcept

Evaluate signed distance from a_point to the closest triangle in this group.

Returns the signed distance with minimum absolute value among m_validCount triangles, the first such lane on a tie. The lanes are evaluated SIMD::NativeWidth<T, W>() at a time (see the class description). Requires the group to have already been packed via pack() (1 <= m_validCount <= W).

Parameters
[in]a_pointQuery point. Must be finite.
Returns
Signed distance from a_point to the closest valid triangle, with sign determined by the outward normal of the nearest feature (face, edge, or vertex).

◆ signedDistanceAt()

template<class T , size_t W>
T EBGeometry::TriangleSoAT< T, W >::signedDistanceAt ( uint32_t  a_lane,
const Vec3T< T > &  a_point 
) const
noexcept

One lane's signed distance: on the host, bit for bit the value signedDistances() gives that lane; on a device, the same to rounding.

Parameters
[in]a_laneLane, below the number of packed triangles.
[in]a_pointThe point.
Returns
The signed distance.

◆ signedDistanceLane()

template<class T , size_t W>
T EBGeometry::TriangleSoAT< T, W >::signedDistanceLane ( uint32_t  a_lane,
const Vec3T< T > &  a_point 
) const
protectednoexcept

Signed distance from a_point to the single triangle stored in lane a_lane.

TriangleDistance::signedDistance() on one lane: the path signedDistance() and signedDistances() take where no SIMD register fits. Reads only lane a_lane's coordinates/normals; performs no reduction.

Parameters
[in]a_laneLane index. Must satisfy 0 <= a_lane < W.
[in]a_pointQuery point.
Returns
Signed distance from a_point to lane a_lane's triangle, sign from its nearest feature.

◆ signedDistances()

template<class T , size_t W>
Array< T, W > EBGeometry::TriangleSoAT< T, W >::signedDistances ( const Vec3T< T > &  a_point) const
noexcept

Signed distances from a_point to every one of the W lane triangles.

The per-lane analogue of signedDistance(): signedDistance() horizontally reduces the W per-triangle distances to the single minimum-|value| entry, whereas this returns all W of them so a caller can recover which lane won – the piece the reduction discards. Computed with the same kernel and lane count as signedDistance(), so each lane is exactly the value signedDistance() compared. All W lanes are filled: padded lanes (m_validCount..W-1) repeat the last real triangle's distance, matching pack()'s padding, so a caller iterating lanes should stop at m_validCount (or de-duplicate). Requires the group to have already been packed via pack() (1 <= m_validCount <= W).

Parameters
[in]a_pointQuery point. Must be finite.
Returns
Per-lane signed distances, one per W lanes.

◆ signedDistancesSIMD()

template<class T , size_t W>
template<size_t N>
void EBGeometry::TriangleSoAT< T, W >::signedDistancesSIMD ( const Vec3T< T > &  a_point,
T *  a_distances 
) const
protectednoexcept

Signed distances to the lanes below m_validCount, N at a time, with SIMD::Pack<T, N>.

Host-only: the packs exist only in a host pass. Lanes of a chunk that starts at or past m_validCount are not written.

Template Parameters
NLane count, SIMD::NativeWidth<T, W>(); must be > 1 and divide W.
Parameters
[in]a_pointQuery point.
[out]a_distancesW values, aligned to N * sizeof(T).

◆ unsignedDistances2SIMD()

template<class T , size_t W>
template<size_t N>
void EBGeometry::TriangleSoAT< T, W >::unsignedDistances2SIMD ( const Vec3T< T > &  a_point,
T *  a_d2 
) const
protectednoexcept

Every lane's squared unsigned distance with SIMD packs of N lanes, as signedDistancesSIMD().

Template Parameters
NLanes per pack.
Parameters
[in]a_pointThe point.
[out]a_d2W squared distances (lanes at or past m_validCount unspecified).

Member Data Documentation

◆ m_validCount

template<class T , size_t W>
uint32_t EBGeometry::TriangleSoAT< T, W >::m_validCount = 0
protected

Number of valid (non-padded) triangles in this group (1..W).

Zero-initialized so that a default-constructed (not-yet-packed) group reliably fails the EBGEOMETRY_EXPECT(m_validCount >= 1) precondition in signedDistance() and computeBoundingVolume(), rather than reading whatever indeterminate value happened to be there.


The documentation for this struct was generated from the following file: