Crystal Space: 4.10.7 Mesh Movement

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 4.10.7 Mesh Movement

This section describes how to move meshes around in your world.

#### Object and World Space

It is very important to understand the concept of object and world space when talking about moving objects. Object space is the coordinate system that is used for describing the object itself independent of where it is. Depending on the type of object it is usually convenient to place the origin of that object space at a central spot. For an actor you probably want it in at the center of the feet so that you can move the (0,0,0) point on the ground and the actor will stand correctly.

World space is where the object will end up after it has been moved. Even after an object is moved to some other location the object coordinates will be unmodified (unless `HardTransform` is used, see later for that).

#### The ``iMovable'`

The basic class that is use to control the position of a mesh is the ``iMovable'`. Every mesh wrapper has one (note that it is the engine that is responsible for knowing where a mesh is, the mesh itself does not care except when it wants to be rendered or lit).

A movable contains a list of sectors and a transformation (``csReversibleTransform'`) from object to world space. A transformation is itself a position (``csVector3'`) and a matrix (``csMatrix3'`).

The reason that a movable contains a list of sectors and not just one sector is that a mesh can be in several sectors at the same time. This happens when the mesh crosses a portal and one side of the mesh is in sector A while the other is in sector B. The engine keeps track of this and will correctly render such objects provided the list of sectors is correctly. Unfortunately the engine gives little support for detecting in which sectors a mesh will be after it moves. This support will certainly arrive at some point in the near future.

#### Moving a Mesh

``iMovable'` contains various functions to help control movement. Here is an example of some code that places an object in some sector and position:

    iMeshWrapper* mesh = ...;
    iMovable* movable = mesh->GetMovable ();
    movable->SetSector (room);
    movable->SetPosition (csVector3 (2, 3, 1));
    movable->UpdateMove ();

One important function is `UpdateMove()`. This function MUST be called after moving an object. It makes sure internal data structures (for visibility and whatever) are recalculated for the new position of the object.

Here is another example where you let the mesh point to some point in space:

    iMeshWrapper* mesh;
    iMovable* movable = mesh->GetMovable ();
    csVector3 pos (1, 1, 0);
    movable->SetPosition (pos);
    movable->GetTransform().LookAt(
      csVector3 (5, 2, 0)-pos, csVector3 (0, 1, 0));
    movable->UpdateMove ();

The `LookAt()` function is very nice. It takes a position relative to the position where the object is and points the object in the direction of that point. The up-vector will be used to control the orientation along that axis. To really make this work well it is recommended that you design your objects so that X is one unit to the right, Y is one unit above, and Z points forwards. This is the way that CS works. But `LookAt()` can be used for any configuration.

Note: `movable->GetTransform()` returns the ``csReversibleTransform'` itself on which you can do various manipulations.

#### Hierarchical Transformations

Sometimes meshes can be put in a hierarchical relationship. This means that there is a parent mesh and children which have a position relative to that parent. For those children the movable is also used with a few small exceptions. First of all the list of sectors is not used as it is the parent mesh that will contain the correct list of sectors for all meshes in its hierarchy. Second the transform in the movable defines the position of the mesh relative to its parent. So if you call `movable->GetTransform()` you will not get the transform which will result in the position of the object but only the transform relative to the parent's local object space. To get the transform which will transform object space of that mesh to world space you need to call `GetFullTransform()`. Note that modifying this transform will not have any effect on the mesh (unlike modifying the transform returned by `GetTransform()`).

#### The `HardTransform()` Function

Some meshes also support the `HardTransform()` function. This function relocates the object space coordinates itself. In other words, it changes the object space origin of the object. This can be useful if you have objects that were designed with an origin that is less that desirable and you first want to move them so that the origin is ok. That can make later transformations from object to world space easier. `HardTransform()` is not a function of ``iMovable'` but of ``iMeshWrapper'` (which will in turn delegate this to the mesh object itself).

#### Finding Mesh Movement Direction

0,0,1 is the vector pointing forward in local object space for the mesh. Using the transform from the movable you can translate this to world space. With This2Other() you can transform the object space vector to world space. So:

    csVector3 v = mesh->GetMovable()->GetTransform()->This2Other (
    	csVector3 (0, 0, 1));

'v' will be the vector one unit in front of the mesh (in the direction the mesh is facing).

#### Include Files

The include files useful for this section are:

    #include <csgeom/transfrm.h>
    #include <iengine/movable.h>
    #include <iengine/mesh.h>

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ]

This document was generated using texi2html 1.76.