Skip to main content

History: SoC2012 Improve and Demo the Terrain System

Preview of version: 60

Project Information

Proposal and discussion thread: http://www.ogre3d.org/forums/viewtopic.php?f=13&t=69553
Mercurial repository: https://bitbucket.org/xiaoxq/ogre_soc_tpi/overview
The basement project: SoC2011 Terrain Paging Improvements

Known Issues

Hiccups when loading page

Implementation Design

New Terrain File Format

To be able to load LOD asynchronously, we should save height/delta data separately according to the lowest level it belongs to. So the terrain file format has been adjusted as follows:

<pre> &lt;TERRAIN_CHUNK> &lt;TERRAINGENERALINFO_CHUNK> uint8 align; uint16 Size; Real WorldSize; uint16 MaxBatchSize; uint16 MinBatchSize; Vector3 Pos; &lt;/TERRAINGENERALINFO_CHUNK> &lt;TERRAINLODDATA_CHUNK>zip( LOD{n-1} HeightData, DeltaData; )&lt;/TERRAINLODDATA_CHUNK> ... &lt;TERRAINLODDATA_CHUNK>zip( LOD{0} HeightData, DeltaData; )&lt;/TERRAINLODDATA_CHUNK> zip( LayerInstanceList Layers; LayerBlendData; &lt;TERRAINDERIVEDDATA_CHUNK> NormalData; &lt;/TERRAINDERIVEDDATA_CHUNK> &lt;TERRAINDERIVEDDATA_CHUNK> ColourMap; &lt;/TERRAINDERIVEDDATA_CHUNK> &lt;TERRAINDERIVEDDATA_CHUNK> LightMap; &lt;/TERRAINDERIVEDDATA_CHUNK> &lt;TERRAINDERIVEDDATA_CHUNK> CompositeMap; &lt;/TERRAINDERIVEDDATA_CHUNK> QuadTree; )

&lt;/TERRAIN_CHUNK></pre>

The new TERRAIN_CHUNK_ID has been upgraded to 2.
The LOD saving process happens at TerrainLodManager::saveLodData(); When a LOD is requested, the TerrainLodManager just open the file, skip the TERRAINGENERALINFO_CHUNK chunk, and skip the unmatched TERRAINLODDATA_CHUNK chunk, then read the height/delta data into memory. These are done at TerrainLodManager::readLodData();

LOD State Machine

Previously, the terrain has only 3 states: Not Prepared, Fully Prepared, Fully Loaded. But now LODs are loaded asynchronously, so the terrain may be only partially prepared/loaded. Every LOD gets its own 3-states, as shown below:
tpi_lod_states.png

LOD Requests Interface and Implementation

The state machine looks somewhat complicated. Luckily we'll hide the details in TerrainLodManager. The interface for users is very simple:

Copy to clipboard
class Terrain { ... void load(int lodLevel, bool synchronous); //request a specified LOD void increaseLodLevel(bool synchronous); //increase the current LOD by 1 void decreaseLodLevel(); //decrease the current LOD by 1 ... }

In fact, they are just proxies for TerrainLodManager, which holds three LOD status: HighestLodPrepared, HighestLodLoaded, TargetLodLevel.
Every LOD request will finally call the updateToLodLevel(int lodLevel, bool synchronous). It acts like:

  • Update the TargetLodLevel.
  • If TargetLodLevel is higher than HighestLodPrepared, prepare it/them
  • If TargetLodLevel is higher than HighestLodLoaded, load it/them
  • If TargetLodLevel is lower than HighestLodLoaded, unload it/them

Currently we won't unprepare LODs. If wanted, the rule is:

  • If TargetLodLevel is lower than HighestLodPrepared, unprepare it/them

Asynchronous LOD Loading

Asynchronously-loading of LOD data is the core feature of this project, the logic is very simple, as shown below.
new_sequence_dia.png
It's also the biggest source of bugs. My work is to make it safe and stable.

Guide for Users

How to make use of the Asynchronous-Loading feature

The simplest way is to manipulate the terrain LOD manually, I mean, calling the APIs above directly. As an example, you can run the EndlessWorld sample, and use PAGE-UP/PAGE-DOWN to increase/decrease terrains' LOD manually.
Another way is to ask an Auto-Update-Lod strategy to call those APIs for you. To support this, the TerrainGroup supplies APIs:
class TerrainGroup
{

...

/// Loads terrain's next LOD level.

void increaseLodLevel(long x, long y, bool synchronous = false);

/// Removes terrain's highest LOD level.

void decreaseLodLevel(long x, long y);

void setAutoUpdateLodStrategy(uint32 strategy);

/// Automatically checks if terrain's LOD level needs to be updated.

void autoUpdateLod(long x, long y, bool synchronous, const Any &data);

void autoUpdateLodAll(bool synchronous, const Any &data);

...
}

How to add my own strategy of Auto-Update-Lod

Weekly Progress

2012-04-29

  • Create repository by importing from kuxv's, and create this wiki page.
  • A small fix to make it compilable on my x64 system. Then it runs quite well.
  • Merge new changesets from trunk.
  • Confirm my development environment: Thinkpad T410s( Intel i5, Nvidia NVS 3100M, 8G memory ), Ubuntu 12.04 64bit. I also have a Win7 64bit, but only for testing.

2012-05-06

  • Some code cleanup.

2012-05-14

  • Keep on warming up with the code.
  • Start drawing a sequence diagram to show the work flow of LOD and paging.

2012-05-20

  • Finish the sequence diagram, and get to understand most of the previous implementation ideas.
  • Have found some possible buggy point. See them above for detail.

2012-05-27

  • Start reviewing the code, I think I have understood the idea deeply.
  • Small refactoring, extract out a TerrainLodManager, which makes the Terrain component as clear as the original.(80% completed)

2012-06-03

  • Almost finish extracting the LodManager from Terrain.
  • Going to read height/delta once for all.

2012-06-10

  • Alpha release.

2012-06-25

  • Write some wiki.

2012-07-02

  • Almost finished the Implementation Design section of the wiki.
  • Use LodManager though no file bound.
  • Fix an "Empty CPU Buffer" exception.

2012-07-10

  • After 2 big fixes, it works quite better, now.
  • But if set paging ON, it still has some bugs.

History

Information Version
Mon 24 of Sep, 2012 12:10 GMT-0000 xiaoxiangquan 84
Sun 19 of Aug, 2012 06:13 GMT-0000 xiaoxiangquan 83
Sun 19 of Aug, 2012 05:59 GMT-0000 xiaoxiangquan 82
Sun 19 of Aug, 2012 05:29 GMT-0000 xiaoxiangquan 81
Sun 19 of Aug, 2012 05:19 GMT-0000 xiaoxiangquan 80
Sun 19 of Aug, 2012 05:16 GMT-0000 xiaoxiangquan 79
Sun 19 of Aug, 2012 05:14 GMT-0000 xiaoxiangquan 78
Sun 19 of Aug, 2012 04:56 GMT-0000 xiaoxiangquan 77
Sun 19 of Aug, 2012 04:45 GMT-0000 xiaoxiangquan 76
Sun 19 of Aug, 2012 04:21 GMT-0000 xiaoxiangquan 75
Sun 19 of Aug, 2012 04:19 GMT-0000 xiaoxiangquan 74
Sun 19 of Aug, 2012 03:02 GMT-0000 xiaoxiangquan 73
Mon 13 of Aug, 2012 16:15 GMT-0000 xiaoxiangquan 72
Tue 07 of Aug, 2012 05:12 GMT-0000 masterfalcon 71
Sun 05 of Aug, 2012 16:15 GMT-0000 xiaoxiangquan 70
Sun 05 of Aug, 2012 16:11 GMT-0000 xiaoxiangquan 69
Sun 05 of Aug, 2012 16:07 GMT-0000 xiaoxiangquan 68
Sun 05 of Aug, 2012 16:04 GMT-0000 xiaoxiangquan 67
Mon 23 of Jul, 2012 04:00 GMT-0000 xiaoxiangquan 66
Mon 23 of Jul, 2012 03:45 GMT-0000 xiaoxiangquan 65
Mon 23 of Jul, 2012 03:25 GMT-0000 xiaoxiangquan 64
Mon 23 of Jul, 2012 02:54 GMT-0000 xiaoxiangquan 63
Mon 23 of Jul, 2012 02:46 GMT-0000 xiaoxiangquan 62
Mon 23 of Jul, 2012 02:35 GMT-0000 xiaoxiangquan 61
Mon 23 of Jul, 2012 02:33 GMT-0000 xiaoxiangquan 60