Support Forum G3D Web Page |
Native C++ implementation of a static bounding interval hierarchy that is very good for box queries and OK for ray-triangle.
More...
Inherits G3D::TriTreeBase.
Classes | |
class | Settings |
class | Stats |
Public Types | |
typedef unsigned int | IntersectRayOptions |
Options for intersectRays. More... | |
enum | SplitAlgorithm { MEAN_EXTENT, MEDIAN_AREA, MEDIAN_COUNT, SAH } |
Public Member Functions | |
NativeTriTree () | |
~NativeTriTree () | |
virtual const String & | className () const override |
virtual void | clear () override |
void | draw (RenderDevice *rd, int level, bool showBoxes=true, int minNodeSize=0) |
Render the tree for debugging and visualization purposes. More... | |
virtual void | intersectBox (const AABox &box, Array< Tri > &results) const override |
Returns all triangles that lie within the box. More... | |
shared_ptr< Surfel > | intersectRay (const Ray &ray) const |
Special single-ray CPU function for simplicity. More... | |
virtual bool | intersectRay (const Ray &ray, Hit &hit, IntersectRayOptions options=IntersectRayOptions(0)) const=0 |
Intersect a single ray. More... | |
shared_ptr< Surfel > | intersectRay (const Ray &ray) const |
Special single-ray CPU function for simplicity. More... | |
virtual bool | intersectRay (const Ray &ray, Hit &hit, IntersectRayOptions options=IntersectRayOptions(0)) const override |
Intersect a single ray. More... | |
shared_ptr< Surfel > | intersectRay (const PrecomputedRay &ray, IntersectRayOptions options, const Vector3 &directiondX, const Vector3 &directiondY) const |
bool | intersectRay (const PrecomputedRay &ray, Hit &hit, IntersectRayOptions options=IntersectRayOptions(0)) const |
virtual void | intersectRays (const Array< Ray > &rays, Array< Hit > &results, IntersectRayOptions options=IntersectRayOptions(0)) const=0 |
Batch ray casting. More... | |
virtual void | intersectRays (const Array< Ray > &rays, Array< shared_ptr< Surfel >> &results, IntersectRayOptions options=IntersectRayOptions(0), const Array< float > &coneBuffer=Array< float >()) const=0 |
Values in results will be reused if already allocated, which can increase performance. More... | |
virtual void | intersectRays (const shared_ptr< Texture > &rayOrigin, const shared_ptr< Texture > &rayDirection, const shared_ptr< GBuffer > &results, IntersectRayOptions options=IntersectRayOptions(0), const shared_ptr< Texture > &rayCone=nullptr) const=0 |
virtual void | intersectRays (const shared_ptr< GLPixelTransferBuffer > &rayOrigin, const shared_ptr< GLPixelTransferBuffer > &rayDirection, const shared_ptr< GLPixelTransferBuffer > results[5], IntersectRayOptions options=IntersectRayOptions(0), const shared_ptr< GLPixelTransferBuffer > &rayCone=nullptr, const int baseMipLevel=0, const Vector2int32 wavefrontDimensions=Vector2int32(-1,-1), const RenderMask renderMask=0xFFFFFFFF) const=0 |
virtual void | intersectRays (const shared_ptr< Texture > &rayOrigin, const shared_ptr< Texture > &rayDirection, const shared_ptr< Texture > &booleanResults, IntersectRayOptions options=IntersectRayOptions(0)) const=0 |
virtual void | intersectRays (const shared_ptr< GLPixelTransferBuffer > &rayOrigin, const shared_ptr< GLPixelTransferBuffer > &rayDirection, const shared_ptr< GLPixelTransferBuffer > &booleanResults, IntersectRayOptions options=IntersectRayOptions(0)) const=0 |
virtual void | intersectRays (const Array< Ray > &rays, Array< bool > &results, IntersectRayOptions options=IntersectRayOptions(0)) const=0 |
virtual void | intersectRays (const Array< Ray > &rays, Array< shared_ptr< Surfel >> &results, IntersectRayOptions options=IntersectRayOptions(0), const Array< float > &coneBuffer=Array< float >()) const override |
Values in results will be reused if already allocated, which can increase performance. More... | |
virtual void | intersectRays (const shared_ptr< Texture > &rayOrigin, const shared_ptr< Texture > &rayDirection, const shared_ptr< GBuffer > &results, IntersectRayOptions options=IntersectRayOptions(0), const shared_ptr< Texture > &rayCone=nullptr) const override |
virtual void | intersectRays (const shared_ptr< GLPixelTransferBuffer > &rayOrigin, const shared_ptr< GLPixelTransferBuffer > &rayDirection, const shared_ptr< GLPixelTransferBuffer > results[5], IntersectRayOptions options=IntersectRayOptions(0), const shared_ptr< GLPixelTransferBuffer > &rayCone=nullptr, const int baseMipLevel=0, const Vector2int32 wavefrontDimensions=Vector2int32(-1,-1), const RenderMask mask=0xFF) const override |
virtual void | intersectRays (const shared_ptr< Texture > &rayOrigin, const shared_ptr< Texture > &rayDirection, const shared_ptr< Texture > &booleanResults, IntersectRayOptions options=IntersectRayOptions(0)) const override |
virtual void | intersectRays (const shared_ptr< GLPixelTransferBuffer > &rayOrigin, const shared_ptr< GLPixelTransferBuffer > &rayDirection, const shared_ptr< GLPixelTransferBuffer > &booleanResults, IntersectRayOptions options=IntersectRayOptions(0)) const override |
virtual void | intersectRays (const Array< Ray > &rays, Array< bool > &results, IntersectRayOptions options=IntersectRayOptions(0)) const override |
virtual void | intersectRays (const Array< Ray > &rays, Array< Hit > &results, IntersectRayOptions options=IntersectRayOptions(0)) const override |
Batch ray casting. More... | |
void | intersectRays (const Array< PrecomputedRay > &rays, Array< Hit > &results, IntersectRayOptions options=IntersectRayOptions(0)) const |
virtual void | intersectSphere (const Sphere &sphere, Array< Tri > &triArray) const override |
Returns all triangles that intersect or are contained within the sphere (technically, this is a ball intersection). More... | |
RealTime | lastBuildTime () const |
Time at which setContents() or rebuild() was last invoked. More... | |
const Tri & | operator[] (int i) const |
Array access to the stored Tris. More... | |
virtual void | rebuild () override |
Rebuild the tree after m_triArray or CPUVertexArray have been mutated. More... | |
void | sample (const Hit &hit, shared_ptr< Surfel > &surfel) const |
virtual void | setContents (const Array< shared_ptr< Surface >> &surfaceArray, ImageStorage newImageStorage=ImageStorage::COPY_TO_CPU) override |
Base class implementation populates m_triArray and m_vertexArray and applies the image storage option. More... | |
virtual void | setContents (const Array< Tri > &triArray, const CPUVertexArray &vertexArray, ImageStorage newStorage=ImageStorage::COPY_TO_CPU) override |
virtual void | setContents (const shared_ptr< class Scene > &scene, ImageStorage newStorage=ImageStorage::COPY_TO_CPU) override |
int | size () const |
Stats | stats (int valuesPerNode) const |
Walk the entire tree, computing statistics. More... | |
const Array< Tri > & | triArray () const |
Array< Tri > & | triArray () |
If you mutate this, you must call rebuild() More... | |
const CPUVertexArray & | vertexArray () const |
CPUVertexArray & | vertexArray () |
If you mutate this, you must call rebuild() More... | |
Static Public Member Functions | |
static const char * | algorithmName (SplitAlgorithm s) |
static shared_ptr< TriTree > | create (bool preferGPUData=true) |
Create an instance of whatever is the fastest implementation subclass for this machine. More... | |
static shared_ptr< TriTree > | create (const shared_ptr< Scene > &scene, ImageStorage newImageStorage) |
static shared_ptr< NativeTriTree > | create () |
Public Attributes | |
RealTime | debugConversionOverheadTime = 0 |
CPU timing of API conversion overhead for the most recent call to intersectRays. More... | |
Static Public Attributes | |
static const IntersectRayOptions | COHERENT_RAY_HINT = 16 |
Make optimizations appropriate for coherent rays (same origin) More... | |
static const IntersectRayOptions | DO_NOT_CULL_BACKFACES = 2 |
Do not allow the intersector to perform backface culling as an optimization. More... | |
static const IntersectRayOptions | NO_PARTIAL_COVERAGE_TEST = 8 |
Disable partial coverage (alpha) testing. More... | |
static const IntersectRayOptions | OCCLUSION_TEST_ONLY = 1 |
Test for occlusion and do not necessarily return valid triIndex, backfacing, etc. More... | |
static const IntersectRayOptions | PARTIAL_COVERAGE_THRESHOLD_ZERO = 4 |
Only fail the partial coverage (alpha) test on zero coverage. More... | |
Protected Member Functions | |
bool | _intersectRay (const Ray &ray, Hit &hit, IntersectRayOptions options) const |
Static Protected Member Functions | |
static void | copyToCPU (const shared_ptr< GLPixelTransferBuffer > &rayOrigin, const shared_ptr< GLPixelTransferBuffer > &rayDirection, Array< Ray > &rayBuffer, const int width=-1, const int height=-1) |
static void | copyToCPU (const shared_ptr< GLPixelTransferBuffer > &rayCoherence, Array< float > &rayCoherenceBuffer) |
template<class T , class ... ArgTypes> | |
static shared_ptr< T > | createShared (ArgTypes &&... args) |
Like std::make_shared, but works for protected constructors. More... | |
Protected Attributes | |
RealTime | m_lastBuildTime = -1e6 |
shared_ptr< CubeMap > | m_sky |
Array< Tri > | m_triArray |
CPUVertexArray | m_vertexArray |
Native C++ implementation of a static bounding interval hierarchy that is very good for box queries and OK for ray-triangle.
The BIH is a tree in which each node is an axis-aligned box containing up to three child nodes: elements in the negative half space of a splitting plane, elements in the positive half space, and elements spaning both sides. When constructing the tree, spanning elements can either be inserted at a spanning node or split and inserted into the child nodes. The presence of a splitting plane allows early-out ray intersection like a kd-tree and the bounding boxes allow relatively tight tree pruning, like a bounding volume hierarchy.
Various algorithms are implemented for choosing the splitting plane that trade between ray-intersection performance and tree-building performance.
|
inherited |
Options for intersectRays.
Default is full intersection with no backface culling optimization and partial coverage (alpha) test passing for values over 0.5.
Enumerator | |
---|---|
MEAN_EXTENT | Produce nodes with approximately equal shape by splitting nodes half-way across the bounds of their contents (similar to an oct-tree). Fastest method for building the tree. |
MEDIAN_AREA | Split nodes so that children have about the same surface area. |
MEDIAN_COUNT | Split nodes so that children have about the same number of triangles. |
SAH | Split nodes so that they have approximately equal intersection times, according to a Surface Area Heuristic. Theory indicates that this gives the highest performance for ray intersection, although that may not be the case for specific scenes and rays. |
G3D::NativeTriTree::NativeTriTree | ( | ) |
G3D::NativeTriTree::~NativeTriTree | ( | ) |
|
inlineprotectedinherited |
|
static |
|
inlineoverridevirtual |
Implements G3D::TriTree.
|
overridevirtual |
Reimplemented from G3D::TriTreeBase.
|
staticprotectedinherited |
|
staticprotectedinherited |
|
staticinherited |
Create an instance of whatever is the fastest implementation subclass for this machine.
preferGPUData | If true, use an implementation that is fast for ray buffers already on the GPU. |
Referenced by G3D::MeshShape::bspTree().
|
staticinherited |
|
inlinestatic |
|
inlinestaticprotectedinherited |
Like std::make_shared, but works for protected constructors.
Call as createShared<myclass>.
void G3D::NativeTriTree::draw | ( | RenderDevice * | rd, |
int | level, | ||
bool | showBoxes = true , |
||
int | minNodeSize = 0 |
||
) |
Render the tree for debugging and visualization purposes.
Inefficent.
level | Show the nodes at or above this level of the tree, where 0 = root |
showBoxes | Render bounding boxes for internal nodes at level == level |
minNodeSize | Do not render triangles at nodes with fewer than this many triangles. Set to zero to disable, set to a high number to spot poorly-constructed nodes |
|
overridevirtual |
Returns all triangles that lie within the box.
Default implementation tests each triangle in turn (linear time).
Reimplemented from G3D::TriTreeBase.
shared_ptr<Surfel> G3D::TriTree::intersectRay |
virtual bool G3D::TriTree::intersectRay |
|
overridevirtual |
Intersect a single ray.
Return value is hit.triIndex != Hit::NONE
for convenience.
Implements G3D::TriTree.
shared_ptr<Surfel> G3D::NativeTriTree::intersectRay | ( | const PrecomputedRay & | ray, |
IntersectRayOptions | options, | ||
const Vector3 & | directiondX, | ||
const Vector3 & | directiondY | ||
) | const |
bool G3D::NativeTriTree::intersectRay | ( | const PrecomputedRay & | ray, |
Hit & | hit, | ||
IntersectRayOptions | options = IntersectRayOptions(0) |
||
) | const |
virtual void G3D::TriTree::intersectRays |
Batch ray casting.
The default implementation calls the single-ray version using Thread::runConcurrently.
virtual void G3D::TriTree::intersectRays |
Values in results will be reused if already allocated, which can increase performance.
virtual void G3D::TriTree::intersectRays |
rayOrigin | must be RGBA32F() = XYZ, min distance |
rayDirection | must be RGBA32F() or RGBA16F() = normalized XYZ, max distance |
rayCone | must be null or a single-channel (R-only) texture. If not null, each element is the cosine of the half-angle of the cone about rayDirection that should be used to select a MIP-level at the intersection point. The easy way to compute this for primary rays is to pass the dot products of adjacent pixel ray directions. |
The GBuffer and both textures must have the same dimensions.
Reconfigures the GBuffer and writes the following fields:
WS_NORMAL is zero at pixels where the ray misses
All other fields are ignored. The GBuffer may be reallocated with textures in a different format as well.
The base class implementation copies all data to the CPU, invokes the intersectRays overload that accepts CPU data, and then copies all data back to the GPU.
virtual void G3D::TriTree::intersectRays |
rayOrigin | must be RGBA32F() = XYZ, min distance |
rayDirection | must be RGBA32F() or RGBA16F() = normalized XYZ, max distance |
rayCone | must be null or a single-channel (R-only) texture. If not null, each element is the cosine of the half-angle of the cone about rayDirection that should be used to select a MIP-level at the intersection point. The easy way to approximate this for primary rays is to pass: sqrt(dot(rayDir, adjacentRayDir) * 0.5 + 0.5) . That is only exact for "square" rays, though, and given the number of approximations involved in both MIP maps and approximating a square pixel footprint with a cone, dropping the square root is also reasonable: dot(rayDir, adjacentRayDir) * 0.5 + 0.5 . |
The GBuffer and all buffers must have the same dimensions.
The GBuffer array must have G3D::GLPixelTransferBuffers with exactly the following semantics and format:
WS_NORMAL is zero at pixels where the ray misses
All other fields are ignored.
The base class implementation copies all data to the CPU, invokes the intersectRays overload that accepts CPU data, and then copies all data back to the GPU.
This is the fastest overload for OptiXTriTree
Only supports the first two bits (0b11 = 3) of renderMask. Reports hits where (renderMask & surface->renderMask() & 3) != 0
virtual void G3D::TriTree::intersectRays |
booleanResults | The red channel is nonzero on hit, 0 on miss. Subclasses are free to change the format of the booleanResults texture to whatever is most convenient for them, so make no assumptions other than that it has a red channel. This is the fastest overload for OptiXTriTree |
virtual void G3D::TriTree::intersectRays |
virtual void G3D::TriTree::intersectRays |
booleanResults | The red channel is nonzero on hit, 0 on miss. Subclasses are free to change the format of the booleanResults texture to whatever is most convenient for them, so make no assumptions other than that it has a red channel. |
|
overridevirtualinherited |
Values in results will be reused if already allocated, which can increase performance.
Implements G3D::TriTree.
Reimplemented in G3D::VulkanTriTree, and G3D::OptiXTriTree.
|
overridevirtualinherited |
|
overridevirtualinherited |
rayOrigin | must be RGBA32F() = XYZ, min distance |
rayDirection | must be RGBA32F() or RGBA16F() = normalized XYZ, max distance |
rayCone | must be null or a single-channel (R-only) texture. If not null, each element is the cosine of the half-angle of the cone about rayDirection that should be used to select a MIP-level at the intersection point. The easy way to approximate this for primary rays is to pass: sqrt(dot(rayDir, adjacentRayDir) * 0.5 + 0.5) . That is only exact for "square" rays, though, and given the number of approximations involved in both MIP maps and approximating a square pixel footprint with a cone, dropping the square root is also reasonable: dot(rayDir, adjacentRayDir) * 0.5 + 0.5 . |
The GBuffer and all buffers must have the same dimensions.
The GBuffer array must have G3D::GLPixelTransferBuffers with exactly the following semantics and format:
WS_NORMAL is zero at pixels where the ray misses
All other fields are ignored.
The base class implementation copies all data to the CPU, invokes the intersectRays overload that accepts CPU data, and then copies all data back to the GPU.
This is the fastest overload for OptiXTriTree
Only supports the first two bits (0b11 = 3) of renderMask. Reports hits where (renderMask & surface->renderMask() & 3) != 0
Implements G3D::TriTree.
Reimplemented in G3D::VulkanTriTree, and G3D::OptiXTriTree.
|
overridevirtualinherited |
Implements G3D::TriTree.
|
overridevirtualinherited |
booleanResults | The red channel is nonzero on hit, 0 on miss. Subclasses are free to change the format of the booleanResults texture to whatever is most convenient for them, so make no assumptions other than that it has a red channel. This is the fastest overload for OptiXTriTree |
Implements G3D::TriTree.
Reimplemented in G3D::VulkanTriTree, and G3D::OptiXTriTree.
|
overridevirtualinherited |
Implements G3D::TriTree.
Reimplemented in G3D::VulkanTriTree, and G3D::OptiXTriTree.
|
overridevirtual |
Batch ray casting.
The default implementation calls the single-ray version using Thread::runConcurrently.
Reimplemented from G3D::TriTreeBase.
void G3D::NativeTriTree::intersectRays | ( | const Array< PrecomputedRay > & | rays, |
Array< Hit > & | results, | ||
IntersectRayOptions | options = IntersectRayOptions(0) |
||
) | const |
|
overridevirtual |
Returns all triangles that intersect or are contained within the sphere (technically, this is a ball intersection).
Default implementation calls intersectBox and then filters the results for the sphere.
Reimplemented from G3D::TriTreeBase.
|
inlineinherited |
Time at which setContents() or rebuild() was last invoked.
|
overridevirtual |
Rebuild the tree after m_triArray or CPUVertexArray have been mutated.
Called automatically by setContents()
Implements G3D::TriTree.
|
overridevirtualinherited |
Base class implementation populates m_triArray and m_vertexArray and applies the image storage option.
Implements G3D::TriTree.
|
overridevirtualinherited |
Implements G3D::TriTree.
Reimplemented in G3D::VulkanTriTree, and G3D::OptiXTriTree.
|
overridevirtualinherited |
Implements G3D::TriTree.
|
inlineinherited |
Stats G3D::NativeTriTree::stats | ( | int | valuesPerNode | ) | const |
Walk the entire tree, computing statistics.
|
inlineinherited |
|
inlineinherited |
If you mutate this, you must call rebuild()
|
staticinherited |
Make optimizations appropriate for coherent rays (same origin)
|
mutableinherited |
CPU timing of API conversion overhead for the most recent call to intersectRays.
|
staticinherited |
Do not allow the intersector to perform backface culling as an optimization.
Backface culling is not required in any case.
|
protectedinherited |
Referenced by G3D::TriTree::lastBuildTime().
|
protectedinherited |
Referenced by G3D::TriTree::operator[](), G3D::TriTree::size(), and G3D::TriTree::triArray().
|
protectedinherited |
Referenced by G3D::TriTree::vertexArray().
|
staticinherited |
Disable partial coverage (alpha) testing.
|
staticinherited |
Test for occlusion and do not necessarily return valid triIndex, backfacing, etc.
data (useful for shadow rays and testing line of sight)
|
staticinherited |
Only fail the partial coverage (alpha) test on zero coverage.