Fractional representation is almost unavoidable when transforming 3D scenes into 2D co-ordinates, but there is usually a performance penalty associated when using floating point types, so BRender also provides a fixed point representation. This is in the form of an alternate library. The same types are used, so the switch between fixed and floating point is performed at compile time. Naturally there are range and precision considerations, but at least you have the choice. In fact, on some platforms with dedicated hardware, the floating point library is faster than the fixed point one.
3D scenes in terms of models, positions and transformations, are conventionally described in terms of Cartesian co-ordinates, vectors, and matrices. BRender provides data types and structures to cater for this, and goes even further, providing a dedicated angle type, the Euler Angle Set, for simpler rotation transforms, and the Unit Quaternion for sophisticated rotational transforms.
Various BRender data structures and functions still make occasional use of basic C types such as
unsigned. However, such use tends to be for simple integer quantities and flags. The floating point types are rarely used except of course for arguments and results of conversion functions.
BRender defines a selection of sized signed and unsigned integer types, for uses where a specific word size is critical (see
BRender defines a selection of fixed point types for later use by application oriented types (see
Although a scalar type could suffice for an angle, it tends to end up representing rotations given that a scalar is not necessarily restricted to a range corresponding to a single rotation. For the purpose of strictly representing an angle (as opposed to a rotation), the
type is provided. By its nature, this type can only represent angles, readily appreciated given that it is a two byte type, with 65536 corresponding to 360xbc , i.e. 0xbc .
When it comes to representing numbers in general, particularly co-ordinates, a number is needed that can take on a wide range of values. A floating point number is ideal, but as not all platforms can deal with these (quickly or at all), BRender's general value type is library dependant. Using one library
compiles to a
float, using the other it compiles to a fixed point representation (
Where storage is critical and values are always less than unity in magnitude, it makes sense to only store the fractional components of values. For this reason BRender defines signed and unsigned fraction types (see
). These are not generally expected to be used by the application, but may come in handy when large numbers of fraction based data structures are required.
The vector plays a central part in 3D geometry and BRender implements 2, 3 and 4 element vectors to enable efficient representations. 2D vectors can be implemented either using 2 element vectors (any homogenous element being implicit), or as 3 element vectors, with an explicit homogenous element. 3D vectors can be implemented either using 3 element vectors (any homogenous element being implicit), or as 4 element vectors, with an explicit homogenous element.
With 2D texture and 3D geometry transformations being crucial to 3D rendering, BRender implements various matrix data structures and arithmetic functions.
is effectively a 2D 3x3 transformation matrix (for use with homogenous 2D co-ordinates) with an implicit third column. Similarly,
is effectively a 3D 4x4 transformation matrix (for use with homogenous 3D co-ordinates) with an implicit fourth column.
is a fully defined 3D 4x4 transformation matrix (for use with homogenous 3D co-ordinates).
Note that BRender applies a matrix to a vector by pre-multiplying the matrix by the vector. Furthermore, a matrix A is multiplied by matrix B (written AB) by computing the dot product of each row of A with each column of B for each element. Further still, ABC is understood to mean (AB)C (equivalent to A(BC)). Post-Multiply M by A means MA, and Pre-Multiply M by A means AM.
Euler Angle Sets
The Euler*1 Angle Set is a set of three angles and an ordering that represents a rotational transformation about each of the orthogonal axes. It is an easier and simpler way of specifying such transforms, rather than composing them out of rotational matrices.
The quaternions form an extension to the real numbers that can be used to represent rotations. Just as we form the complex numbers by starting with the real numbers and including an extra number i with the property i2=-1, the quaternions are formed by adding in three extra numbers: i, j, and k, with i2=j2=k2=-1. In addition these new numbers obey the following rules:
Just as with complex numbers, the modulus of a quaternion is defined by:
The quaternions with unit modulus are known as the unit quaternions.
The inverse of a unit quaternion*2 q=w+xi+yj+zk, is q-1=w-xi-yj-zk. So we have qq-1=q-1q=1.
Rotations may be represented as unit quaternions as follows. Suppose we wish to rotate through an angle q around the axis defined by the unit vector (nx,ny,nz). The corresponding quaternion q is given by:
The value of quaternions lies in the fact that if we multiply the quaternions for two rotations together then the resulting quaternion represents the resulting rotation. These operations are considerably simpler than those needed to represent rotations using matrices.
More explicitly, given a vector (vx,vy,vz), we apply the rotation via the quaternion q representing it using the following formula:
There is a further property of quaternions requiring a little more discussion. A rotation through 360xbc is effectively the same as no rotation. However, if we substitute 0xbc and 360xbc into the earlier formula for q above, we find that these rotations are represented by +1 and -1 respectively. This means that both +1 and -1 represent the identity transform. This is not a problem though, it simply means that every rotation can be represented by two different quaternions. If we use the above formula for applying a quaternion to a vector, then whichever of the two equivalent quaternions we choose, we will still obtain the same result.