Graphics Reference
In-Depth Information
< distance .The
method returns true . Parameter distance is overwritten with r and value
is a pointer to the primitive on which the intersection lies.
This interface is motivated by the common applications of the query method,
such as the one from Listing 37.2. For example, consider the cases of ray casting
for eye rays, light rays (photons), moving particles, or picking (a.k.a. selecting)
an object whose projection lies under a mouse pointer. In each case, there may
be many objects that have a nonzero intersection with the ray, but the caller only
needs to know about the one producing the intersection closest to the ray origin.
These objects might be stored in multiple data structures—perhaps distinguishing
static and dynamic objects or ones whose different geometry is better suited to
different data structures. Given an intersection query result from one data struc-
ture, the query to the second data structure need not search any farther than the
previously found intersection. The caller almost always will overwrite the previ-
ously closest-known distance, so it makes sense to simply update that in place.
Listing 37.2 demonstrates a terse yet readable implementation of this case. Note
that there's potential for a subtle bug in this code—if the second ray intersection
were accidentally written as hit = hit || dynamicObjects..., then any inter-
section with a static object would preclude ever testing for a closer intersection
with a dynamic object. Misuse of the early-out behavior of the logical OR opera-
tor is a danger not limited to ray intersection or computer graphics, of course!
3. The intersection closest to the ray origin is at distance r
Listing 37.2: Typical application of FirstRayIntersection
in a ray-tracing renderer.
1
2
3
4
5
6
7
8
9
10
11
12
13
Radiance rayTrace( const Ray & ray) {
float distance = INFINITY;
Value * ptr = NULL;
bool hit = staticObjects.firstRayIntersection (ray, ptr, distance);
hit = dynamicObjects.firstRayIntersection(ray, ptr, distance) || hit;
if (hit) {
return shade(ptr, ray.origin + distance * ray.direction);
} else {
return Radiance(0);
}
}
Even when the high-level scene management code creates only one spatial
data structure, there are likely many spatial data structures in the program. This is
because, like any other sophisticated data structures, complex spatial data struc-
tures tend to be implemented using multiple instances of simpler spatial data
structures. For example, the contents of each node in a spatial tree are typically
stored in a spatial list, and the child subtrees of that node are simply other instances
of spatial trees. Intersection methods like the ones proposed here that are designed
to accumulate the results from multiple structures make it easy to design complex
spatial data structures.
In addition to the convenience for the caller of passing a distance limit that will
be updated, there are some applications for which there is inherently some limit to
how far the caller wants to search. Examples include picking with a range-limited
virtual tool or casting a shadow ray to a light source. Communicating the search
limit to the data structure allows it to optimize searching for the intersection.
 
Search WWH ::




Custom Search