Object Spaces

Each geometric object in Realsoft Graphics Oy defines local object space in which all geometric attributes and the sub objects are defined.

An object space is represented by a row-dominated 4x4 matrix, which can be fetched by calling:


    R3MATRIX *m;

    R3GetAttrs(obj,
               R3T(R3PRIMA_Matrix, &m),
               R3TAG_END);

The matrix defines transformation which maps a point from object's local space into the objects parent space.

Because geometric objects can be arranged to hierarhical structures called 'trees', the transformation which maps a point from object's local space to world space' is the summ of all parent spaces of the point.


    root
      \
     level 
        \
        sds 
          \
        [vertice]

To fetch the matrix that maps 'vertice' to world space (the space in which 'root' object is defined), call:


    R3MATRIX m;

    R3DoA(sds, R3PRIMM_GETTOABSSPACEMATRIX, &m);

You can then transform the the sds vertice to world space by calling:


    R3VECTOR worldp, sdsp;
    R3MxTransform(&worlp, m, &sdsp);

Correspondingly, to fetch the matrix that maps a point from world space to objects local space, call:


    R3MATRIX m;

    R3DoA(obj, R3PRIMM_GETTOOBJSPACEMATRIX, &m);

Which is the same thing as calling inverting the 'toabspace' matrix:


    R3MATRIX m, im;

    R3DoA(obj, R3PRIMM_GETTOABSSPACEMATRIX, &m);
    R3MxInvert(im, m);

However, for sake of speed, you should always fetch the matrices by using the above methods (the system caches the matrices).

There are also methods for transforming a single point to a world/object space.


    R3DoA(obj, R3PRIMM_POINTTOABSSPACE, &point);
    R3DoA(obj, R3PRIMM_POINTTOOBJSPACE, &point);

Note that if you need to transform several points to abs space, you should first fetch the total transformation matrix and use R3MxTransfor() function, rather than calling the above methods. This way you can avoid the overhead caused by calling a method per geometric point.

Transforming Objects

For example, to move an object in world x axis, call:


    R3PRIMTRANSFORM t;
    memset(&t, 0, sizeof(t));

    R3MxTranslate(t.tr, 0.1, 0.0, 0.0);

    R3DoA(obj, R3PRIMM_TRANSFORM, &t);

You can also control objects local space via four attributes R3PRIMA_MatrixTranslate, R3PRIMA_MatrixScale, R3PRIMA_MatrixRotate and R3PRIMA_MatrixSkew. For example, to move the origin of the objects local space to world origin, call:


    R3VECTOR origin;
    VSet(&origin, .0, .0, .0);

    R3SetAttrs(obj,
               R3T(R3PRIMA_MatrixTranslate, &origin),
               R3TAG_END);

You can also manipulate objects local matrix directly. For example, to reset objects space matrix to identity, call:


    R3MATRIX m;
    R3MxIdentity(m);

    R3SetAttrs(obj,
               R3T(R3PRIMA_Matrix, &m),
               R3TAG_END);

Note: When object space is touched, the base class sends R3PRIMM_MATRIXCHANGED method to the object. This method propagages through the object hierarchy to all the sub objects. If you need to plug-in an object which has to maintain geometric data in world space, catch this method. It tells you when the total matrix of your object has changed.

Matrix Operations

Realsoft 3D defines all necessary matrix operations, such as concatenation, inversion and a large number of functions that can be used for defining various often needed transformations.

Available matrix functions are defined in 'inc/oops/r3matrix.h' header file.

There are two kind of functions: one that set the given transformation to the given matrix, overriding the previous value of the matrix. And then there are functions that concatenate the given transformation to the current value of the matrix.

For example:


    R3MxTranslate(m, x, y, z);
    R3MxConcatTranslate(m, x, y, z);

The former initializes the given matrix with the specified translation. The latter concatenates the translation to the matrix.

The system works so that the last concatenated matrix is applied first.

For example:


    R3MATRIX m;
    R3VECTOR origin, axis;
    R3FLOAT angle;
    
    R3MxTranslate(m, 0.1, 0, 0);
    R3MxConcatRotate(tr.tr, angle, &origin, &axis);

creates a matrix that first rotates the object and then translates it.