ndt

Object Definitions

The ndt ray-tracer uses a modular object definition model. Each object type is defined in a single C file that defines several functions that will be called as needed by the ray-tracing engine.

Function Overview

Required:

The functions described below are required for each object.

int type_name(char *name, int size);

The type_name function provides the name that will be used in scene_alloc_object of the C API or the type field of an object when using a YAML file.

Parameters:

Returns:


int params(object *obj, int *n_pos, int *n_dir, int *n_size, int *n_flags, int *n_obj);

The params function provides the number of each type of data is required to describe the location and shape of an object. For objects that require a variable number of parameters depending on the number of dimensions, the dimensions field of the passed in object can be checked.

Parameters:

Returns:


int bounding_points(struct gen_object * obj, bounds_list *list);

The bounding_points function finds a set of points such that any sphere that surrounds all of the points will also completely surround the object. Points are added to the bounding set using the bounds_list_add function. To improve performance, each object is surrounded by a bounding sphere that is checked for intersection with a ray before checking to see if the actual object intersects a ray. Thus a tighter bound gives fewer false positives and therefore better performance. Each point can be padded with a radius around it that will also be included in the final bounding sphere. For infinitely large objects (e.g., hyperplanes), the passed in list should remain empty.

Parameters:

Returns:


int intersect(object * obj, vectNd *o, vectNd *v, vectNd *res, vectNd *normal, object **obj_ptr);

The intersect function checks to see if the passed in object (obj) and a ray (starting from o and moving along v) intersect. If an intersection occurs, res is to be set to the point of the intersections, and normal is to be set to the normal vector at that point.

Parameters:

Returns:


int cleanup(object * obj);

The cleanup function frees any additional persistent memory or vectors that an object may have allocated for ray-invarient values that were pre-computed beyond the prepped_t structure. This function will only be called when an object is freed.

Note: Only required for objects that allocate additional memory or vectors outside the lists discussed in *params functions.*

Parameters:

Returns:

Optional:

The functions below are optional. If they are omitted, a default function will be provided.

Each of these functions are passed an object (obj) and a location vector (at). They then fill in the color, reflectivity, or transparency at that location for that object.

int get_color(object *obj, vectNd *at, double *red, double *green, double *blue);

int get_reflect(object *obj, vectNd *at, double *red_r, double *green_r, double *blue_r);

int get_trans(object *obj, vectNd *at, int *transparent);

Adding New Objects

To add a new object type, copy stubs.c to a new filename (e.g., custom.c). Be sure to change the name in type_name from stubs to something meaningful. Add code as needed to the four required functions. Any values that need to be computed during intersection checking, but don’t vary with the ray being checked can be pre-computed in the prepare function and stored in the prepped_t structure.

Once the object has been defined, the C code must be compiled into a shared object that can be loaded at runtime. The Makefile in the objects subdirectory should automatically build any C files into shared objects, and ndt will load any suitable shared objects in the objects subdirectory at runtime.

To build the shared object files:

$ cd objects
$ make

It should now be possible to refer to the new object by its type name in either scene_alloc_object calls or the type field of objects in a YAML file.