Sphere clouds

Particles of differing sizes, kept as a center and a radius each in arrays of the program’s own: the signed distance to their union, and the particle closest to a point, through a SphereCloudBVH (see Point clouds). The source is at Examples/SphereClouds/main.cpp.

_images/example_SphereClouds.jpg

Fig. 33 2,000 particles in the unit cube, with radii between 0.01 and 0.06.

The code that runs on either side

The query functor ClosestParticle holds the cloud by value and maps a point to the closest particle, through an EBGEOMETRY_HOST_DEVICE call operator. A cloud owns no memory – it describes the spheres and the BVH in a Pool – so it is trivially copyable, and a kernel can receive it by value once it describes memory the device can read.

Building the cloud

The cloud is built from the program’s arrays of centers and radii (or from one array of SphereCloud::Sphere), and keeps its own copy in the pool, which must outlive it:

EBGeometry::Pool pool(EBGeometry::hostMemoryResource());

const SphereCloudBVH<T> cloud(pool, centers, radii);

A query reports a particle by its index in those arrays, so data the cloud does not hold (here a material per particle) stays in the program’s own arrays, indexed the same way.

Using it on the host

signedDistance(p) is the smallest \(|p - c| - r\) over the particles: negative inside a particle, and the distance to the nearest one outside them all. closestSphere(p) names that particle and gives the same distance. The program prints both at a few points, and the value at a particle’s center.

The same query on a GPU

The pool is frozen and mirrored into GPU::memoryResource(), and rebasedView() gives a cloud that reads the copy; GPU::transform() runs ClosestParticle once per point in a kernel. In a plain C++ build the same lines run on the host.

Looking at it

The example ends with Render::view(cloud, pool, argc, argv); X cuts the cloud open.

The window needs SDL2 and is built with make VIEWER=SDL2 or cmake -DEBGEOMETRY_VIEWER=SDL2 (see The viewer window (EBGEOMETRY_VIEWER)); otherwise, and with --no-view or without a display, view() prints why and returns. Drag to orbit and scroll to zoom; the window lists its other keys (see The viewer’s keys).

Building and running

See Building for how to compile it with CMake, GNU Make, or a direct compiler invocation. Built for a GPU (see Running on a GPU), the queries and the window run on the device.

cd Examples/SphereClouds
./SphereClouds.ex