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

4.10.2 Using Mesh Objects

Written by Jorrit Tyberghein, jorrit.tyberghein@gmail.com.

This section explains how to use Mesh Objects in general. It doesn't go into detail about the specific Mesh Object Types that Crystal Space supports.

General

When the engine works with instances of Mesh Objects it does so through the `iMeshWrapper' interface. `iMeshWrapper' holds the reference to the `iMeshObject' instances implementing the particular type of Mesh Object. `iMeshWrapper' is responsible for deciding when to draw a Mesh Object and when to light it. `iMeshWrapper' also manages the position of the object in the world and manages possible hierarchical transformations (i.e. `iMeshWrapper' has an array of `iMeshWrapper' children).

Loading From Map File

The easiest way to use Mesh Objects is to simply specify them in the map file for your level. There are two things that you need to do for that. First you have to specify an entry at top-level (directly inside the `world' statement) like this (this example uses the fountain plug-in to make a fountain):

 
<meshfact name="fountainFactory">
  <plugin>crystalspace.mesh.loader.factory.fountain</plugin>
  <params />
</meshfact>

This will use the mesh object loader plug-in which is identified by the SCF name mentioned by the `plugin' statement to load a factory (type `iMeshObjectFactory') and register it with the engine. There are no parameters for the fountain's Mesh Object Factory so that's why the `params' block is empty. But you still have to specify it. Other mesh object factories may accept parameters.

Because the fountain defines no parameters for the Mesh Object Factory you only have to create one factory in order to make all fountains you need. But in some cases you may have to create multiple factories depending on the object characteristics you want.

To place a fountain in some room (sector) you use a `meshobj' statement, within the definition of a room or sector, like this:

 
<meshobj name="fountain">
  <plugin>crystalspace.mesh.loader.fountain</plugin>
  <params>
    <factory>fountainFactory</factory>
    <number>300</number>
    <material>spark</material>
    <origin x="0" y="0" z="0"/>
    <dropsize w=".05" h=".05"/>
    <color red="0.7" green="0.9" blue="1.0"/>
    <accel x="0" y="-.1" z="0"/>
    <falltime>3</falltime>
    <speed>1</speed>
    <elevation>1.5</elevation>
    <azimuth>0</azimuth>
    <opening>.2</opening>
    <mixmode>
      <add />
    </mixmode>
  </params>
  <move>
    <v x="-10" y="-1" z="14"/>
    <matrix>
      <rot x="1.5"/>
    </matrix>
  </move>
</meshobj>

This code fragment uses the `crystalspace.mesh.loader.fountain' loader plug-in named to load a Mesh Object (type `iMeshObject') and register it with the engine (while placing it in the current sector). In this case there are many parameters. The first parameter should always be the name of the factory. This is true for all Mesh Objects regardless of their type. For a complete list of parameters available, you should refer to the fountain documentation.

The `move' statement is outside of the `params' block. The reason for this is that the position of Mesh Objects is controlled by the engine and not by the Mesh Object itself.

In addition to the above statements you can also nest other `meshobj' statements to create a hierarchy of Mesh Objects (not shown in the example above). If you do that, then the `move' statement must be interpreted relative to the parent.

When you have Mesh Objects loaded into Crystal Space using the map file syntax illustrated above, then you can query the parameters from your application by using the standard API in the `iEngine' interface.

Using Directly From Code

You can also create Mesh Objects directly from your application. The engine has a few convenience functions you can use for that (iEngine::CreateMeshwrapper() and iEngine::CreateMeshFactory()). But here we show you the full way to create meshes from code:

Here is a code example for creating an instance of the genmesh plug-in.

 
void Initialize ()
{
  ...
  // First create the factory:
  csRef<iMeshFactoryWrapper> fact = engine->CreateMeshFactory (
    "crystalspace.mesh.object.genmesh", "cubeFact");
  csRef<iGeneralFactoryState> factstate = scfQueryInterface<iGeneralFactoryState> (
    fact->GetMeshObjectFactory ());

  csEllipsoid ellips (csVector3 (0, 0, 0), csVector3 (1, 1, 1));
  factstate->GenerateSphere (ellips, 8);
  factstate->CalculateNormals ();
  ...
}
...
void SetupWorld ()
{
  ...
  // Make a ball using the genmesh plug-in.
  csRef<iMeshWrapper> ball =
    engine->CreateMeshWrapper (fact, "ball", room, csVector3 (-3, 5, -3));
  csRef<iGeneralMeshState> ballstate = scfQueryInterface<iGeneralMeshState> (
    ball->GetMeshObject ());
  ballstate->SetMaterialWrapper (myMaterial);
  ...
}

This example will load a ball using the plug-in and place it at (-3,5,-3) in `room'.

iGeneralFactoryState and iGeneralMeshState are the state interfaces for setting the characteristics of genmesh Mesh Objects.

Generic Mesh Creation Code

In general you should use the following code to create any kind of mesh:

 
  // First create the factory:
  csRef<iMeshFactoryWrapper> fact = engine->CreateMeshFactory (
	"crystalspace.mesh.object.meshtype", "factoryName");
  csRef<iMeshtypeFactoryState> factstate = scfQueryInterface<
  	iMeshtypeFactoryState> (fact->GetMeshObjectFactory ());
  ...
  // Then make one or more meshes:
  csRef<iMeshWrapper> mesh = engine->CreateMeshWrapper (
  	fact, "meshName", sector, csVector3 (-3, 5, -3));
  csRef<iMeshtypeObjectState> meshstate = scfQueryInterface<
  	iMeshtypeObjectState> (mesh->GetMeshObject ());
  ...

Replace `meshtype' with the correct mesh type (like `genmesh', `thing', ...). Replace iMeshtypeFactoryState with the correct factory state and iMeshtypeObjectState with the correct object state.


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

This document was generated using texi2html 1.76.