Project: 3D Craft -- Vertices

This page describes vertices and their use in Project: 3D Craft. It is generally broken up into two sections, structure definition and the vertex API. Below are hot links to specific sections:

As you will see below there are lots you can do with vertices but a comment that John Carmack of Id Software fame once made really stuck with me, it went something like:

"One measure of 3-D coding is how fast the code can transform the vertices, a measure of 3-D design is how rarely those vertices need to be transformed."

His point, which is as valid now as it was when he said this, is that the art of good 3-D programming is in not doing any work that you don't absolutely need to do.


Vertex Definition -- p3dc_VRTX

The most fundamental compound type in P3DC is the p3dc_VRTX structure. It has the following members;

Member Type Description
v p3dc_PNT3 This is the vertex's position in the world. In many engines this would be the only thing necessary but in P3DC there are additional values that are computed by the engine and tied to each vertex.
xid unsigned short The transform id, xid, identifies the last transform used to transform this vertex. This is an accellerator in that if the same vertex needs to be transformed again by the same transform, the cached values are used and many multiplies are saved.
ccode unsigned short This value contains the clipping code for the transformed vertex. When the vertex is transformed, if it is transformed into "view" space, meaning that tv.w is not equal to 1.0, then the vertex transformation code computes the "out code" for this vertex based on the x, y, z, and w values in the tv member. For x and y, values that are less than -w or greater than +w will be clipped, and for z values that are less than 0 or greater than +w will be clipped. This information is stored in this member as a clipping accellerator.
tv p3dc_PNT4 This structure holds the transformed vertex. This is a four element vector because the point may be transformed into homogenous co-ordinates. (this is done just prior to clipping).

Vertices are the fundamental point in P3DC, they define points, the endpoints of lines, and when they are co-planar they define a polygon or face.


Vertex Application Programming Interface

Vertices have a set of interfaces that are used to allocate, free, and manipulate them. These interfaces are described in this section of the document.

p3dc_VRTX * p3dc_new_vrtx( p3dc_FLOAT x, y, z )

This function allocates a new vertex structure and initializes it's v member to contain the values passed in for x, y, and z. All other members are cleared to zero.

void p3dc_free_vrtx( p3dc_VRTX **vrtx_ptr )

This function frees a vertex (see the discussion on memory management for a more complete description). The freed vertex is added to the free list for later re-use. Note that it gets passed a pointer to a pointer, the pointer is set to NULL after the vertex is freed.

void p3dc_xfrm_vrtx( p3dc_VRTX *res, p3dc_XFRM *xfrm, p3dc_VRTX *src )

This function transforms the vertex referenced by src by the transformation pointed to by xfrm (if the xid member of src matches the id value of xfrm then the cached values in src->tv are used instead.) If the pointer res is not null, then transformed values are copied into this vertex's untransformed member v. You use this capability when transforming from one co-ordinate space to another, like for example transforming one model into the model space of another model.

p3dc_VRTX * p3dc_cross_vrtx( p3dc_VRTX *R, *A, *B )

This function computes the cross product (vector product) R = A x B of two vertices. It assumes they represent two vectors that start at the origin. The code takes steps to allow the result to be the same as either A or B. If the pointer R is null then a new vertex is allocated and returned.

p3dc_VRTX * p3dc_sub_vrtx( p3dc_VRTX *R, *A, *B )

This function computes the vector difference R = B - A. This function is useful for computing a direction vector between two points. Assuming that A and B represent world co-ordinates, the result R is the vector pointing from A to B. If the pointer R is null then a new vertex is allocated and returned.

p3dc_VRTX * p3dc_cross3_vrtx( p3dc_VRTX *R, *O, *A, *B )

This function computes the cross product (vector product) R = (A - O) x (B - O). Which is effectively saying from three points O, A, and B compute the cross product. And when you think about it, if you've got three vertices of a triangle (smallest polygon) this will compute the normal vector (except it still needs to be normalized into a unit vector, see p3dc_unit_vrtx) If the pointer R is null a new vertex is allocated and returned.

p3dc_FLOAT p3dc_dot_vrtx( p3dc_VRTX *A, *B )

This function computes the dot (or scalar) product A * B. It is returned as a float. Note that the scalar product of a vector with itself it its length.

p3dc_FLOAT p3dc_dot3_vrtx( p3dc_VRTX *O, *A, *B )

This function computes the dot (or scalar) product of (A-O) * (B-O) which is mathematically equivalent to the dot product of two vectors whose origin is O and whose end points in world space are A and B.

p3dc_VRTX * p3dc_unit_vrtx( p3dc_VRTX *R, p3dc_VRTX *A )

This function "normalizes" a vertex A that is presumed to start at the origin. This is used to compute unit vectors in a given direction. If R is null a new vertex is allocated.

p3dc_VRTX * p3dc_normal_vrtx( p3dc_VRTX *R, *A, *B, *C )

This function computes the unit normal vertex for the plane defined by the points ABC. These should be in counter clockwise order for the "front" normal and clockwise order for the "back" normal. If the pointer R is null then a new vertex is allocated and returned.

p3dc_VRTX * p3dc_scale_vrtx( p3dc_VRTX *R, *p3dc_VRTX *A, p3dc_FLOAT s )

This function multiplies a vector A by a scalar s and returns the result in R. If R is null then a new vertex is allocated.

p3dc_VRTX * p3dc_add_vrtx( p3dc_VRTX *R, *A, *B )

This function returns the vector sum A + B. If the pointer R is null then a new vertex is allocated and returned.