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

### 4.9.10 Terrain Mesh Object

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

This mesh object represents a landscape engine. The basic idea is that the entire landscape is represented by a two dimensional heightmap. This heighmap typically comes from a heightmap image file but it can also come from other sources.

It features:

- Automatic lod.
- Splatting: having multiple detail materials selected with a material palette and smooth transitions between the different materials.
- Static precalculated lighting with shadows.
- Dynamic lighting using bumpmapping and similar techniques.

#### Basic Structure

The following SCF class names are used (for `csLoadPlugin`):

- Type plugin: `crystalspace.mesh.object.terrain.bruteblock`
- Loader plugin: `crystalspace.mesh.loader.terrain`
- Factory loader plugin: `crystalspace.mesh.loader.factory.terrain`

Objects in this plugin implement the following SCF interfaces, which you can retrieve with `scfQueryInterface`:

- MeshObject
  - Implements ``iMeshObject'`
  - Implements ``iTerrainObjectState'`
- MeshObjectFactory
  - Implements ``iMeshObjectFactory'`
  - Implements ``iTerrainFactoryState'`
- MeshObjectType
  - Implements ``iMeshObjectType'`

#### Factory State Interface

Use the ``iTerrainFactoryState'` SCF interface to access settings for a terrain factory. The definition of this interface can be found in ``CS/include/imesh/terrain.h'` and that is also the include file you need to include in your applications to use this plugin. Using this interface you can access the terraformer and sample area for a terrain factory.

#### Object State Interface

``iTerrainObjectState'` (residing in ``CS/include/imesh/terrain.h'`) is the SCF interface that you can use to manipulate settings for a terrain object. By using this interface you can access the base material, material palette, and various other settings for the terrain object.

#### How Does it Work

The easiest way to explain how the landscape engine works is to show an example world file:

    <world>
      <textures>
        <texture name="andrew_marble4.jpg">
          <file>/lib/stdtex/andrew_marble4.jpg</file>
        </texture>
        <texture name="stone4.gif">
          <file>/lib/std/stone4.gif</file>
        </texture>
        <texture name="grass.png">
          <file>/lev/terrain/grass.png</file>
        </texture>
        <texture name="materialmap_base.png">
          <file>/lev/terrain/materialmap_base.png</file>
        </texture>
      </textures>

      <shaders>
        <shader><file>/shader/terrain_fixed_base.xml</file></shader>
        <shader><file>/shader/terrain_fixed_splatting.xml</file></shader>
      </shaders>

      <materials>
        <material name="Base">
          <texture>materialmap_base.png</texture>
          <shader type="ambient">terrain_fixed_base</shader>
        </material>
        <material name="Marble">
          <texture>andrew_marble4.jpg</texture>
          <shadervar name="texture scale" type="vector2">16,16</shadervar>
          <shader type="terrain splat">terrain_fixed_splatting</shader>
        </material>
        <material name="Stone">
          <texture>stone4.gif</texture>
          <shadervar name="texture scale" type="vector2">16,16</shadervar>
          <shader type="terrain splat">terrain_fixed_splatting</shader>
        </material>
        <material name="Grass">
          <texture>grass.png</texture>
          <shadervar name="texture scale" type="vector2">16,16</shadervar>
          <shader type="terrain splat">terrain_fixed_splatting</shader>
        </material>
      </materials>

      <addon>
        <plugin>crystalspace.renderloop.loop.loader</plugin>
        <paramsfile>/shader/std_rloop_terrainfixed.xml</paramsfile>
      </addon>

      <settings>
        <clearzbuf>yes</clearzbuf>
        <renderloop>std_rloop_terrainfixed</renderloop>
      </settings>

      <start>
        <sector>room</sector>
        <position x="0" y="30" z="0" />
      </start>

      <addon plugin="crystalspace.terraformer.simple.loader">
        <name>simple</name>
        <heightmap>/lev/terrain/heightmap_257x257.png</heightmap>
        <scale x="256" y="32" z="256" />
      </addon>

      <meshfact name="TerrainFact">
        <plugin>crystalspace.mesh.loader.factory.terrain</plugin>
        <params>
          <plugin>crystalspace.mesh.object.terrain.bruteblock</plugin>
          <terraformer>simple</terraformer>
          <sampleregion>
            <min x="-256" y="-256" />
            <max x="256" y="256" />
          </sampleregion>
        </params>
      </meshfact>

      <sector name="room">
         <light name="sun">
           <center x="-50000" y="86030" z="0" />
           <color red="0.85903" green="0.80995" blue="0.70420" />
           <radius>1000000</radius>
         </light>

        <meshobj name="Terrain">
          <plugin>crystalspace.mesh.loader.terrain</plugin>
          <params>
            <factory>TerrainFact</factory>
            <material>Base</material>
    	<materialpalette>
    	  <material>Grass</material>
    	  <material>Marble</material>
    	  <material>Stone</material>
    	</materialpalette>
    	<lodvalue name="splatting distance">200</lodvalue>
      	<lodvalue name="block resolution">16</lodvalue>
      	<lodvalue name="block split distance">8</lodvalue>
      	<lodvalue name="minimum block size">32</lodvalue>
      	<lodvalue name="cd resolution">256</lodvalue>
    	<materialmap image="/lev/terrain/materialmap.png" />
    	<staticlighting>yes</staticlighting>
    	<castshadows>yes</castshadows>
          </params>
        </meshobj>
      </sector>
    </world>

#### Textures and Materials

In the first part of this world file we define the textures as used by the landscape mesh. In this particular example we use ``materialmap_base.png'` as the base material. This is the material that is going to be used for the landscape in the distance. The three other textures are individual textures that are going to be used by the splatting algorithm (more on that later).

In this particular example we use the ``terrain_fixed_base.xml'` and ``terrain_fixed_splatting.xml'` shaders. This means that we use simple static lighting (needs a ``-relight'`). Other options here are the ``splatting_base.xml'` and related shaders which allow for fully dynamic lighting and bumpmapping.

We need to define four materials. One material for the base material so that one uses the ``terrain_fixed_base'` shader. The three others will be used by the splatting algorithm so they need the ``terrain_fixed_splatting'` shader. Using the ``texture scale'` shader variable you can control the scale of these textures as used on the terrain.

#### Level Setup

Because we need the ``terrain_fixed_base'` shaders we also need the ``std_rloop_terrainfixed.xml'` renderloop. This renderloop works together with the fixed terrain shaders. It also supports rendering of normal software vertex lighted meshes and meshes using lightmaps so you can easily put other objects on the landscape.

#### Heightmap Data

The landscape engine uses a terraformer plugin to get the heightmap data from. Currently there is only one terraformer which loads heightmap data from a normal image. Using the ``crystalspace.terraformer.simple.loader'` terraformer plugin loader we can load the heightmap data (``heightmap_257x257.png'`) and give it the name ``simple'`. Using the ``scale'` keyword we can scale it to the right dimensions as needed for the landscape engine.

#### Mesh Factory

In the mesh factory of the landscape engine we say which terraformer we are going to use (i.e. ``simple'` in this case) and also where we will sample the terraformer. In the terraformer itself we scaled the heightmap data to the right dimensions. But in the factory we decide which region we will actually use for geometry.

#### Mesh Object

Finally we need the actual mesh object representing the landscape. Here we say what the base material is that we will use and we also setup the material palette. In our case we use a palette as follows:

- ``Grass'`: index 0
- ``Marble'`: index 1
- ``Stone'`; index 2

This palette is used in combination with a materialmap (``materialmap.png'`). The materialmap is an indexed image which tells the landscape engine which material should be used on every triangle of the terrain. In addition the following flags are set here:

- ``splatting distance'`: this is the distance at which it stops using splatting and switches to the base material. Making this lower will cause the landscape to be less detailed (less detailed material) but it will run faster.
- ``block resolution'`: this controls the internal resolution of the blocks.
- ``block split distance'`: unknown?
- ``minimum block size'`: unknown?
- ``cd resolution'`: this is a current hack to control the resolution of the triangle mesh used for collision detection. The default is 256 which means that a mesh of 256x256x2 triangles will be used. Larger values will result in more accurate collision detection (no sinking through floor) but slower and more memory usage.
- ``staticlighting'`: enable this if you want to use static lighting (using ``-relight'`).
- ``castshadows'`: enable this if you want to enable shadow casting for other objects on this terrain. This is only used in combination with static lighting.

#### Using From Code

It is also possible to use the landscape mesh from code. Use the state interfaces `iTerrainFactoryState` and `iTerrainObjectState` with the ``terrain'` mesh type using the generic mesh generation code (see Generic Mesh Creation Code).

TODO: add more information here.

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

This document was generated using texi2html 1.76.