<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.python-ogre.org/skins/common/feed.css?270"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.python-ogre.org/index.php?title=Special:NewPages&amp;feed=atom&amp;hideliu=&amp;hidepatrolled=&amp;hidebots=&amp;hideredirs=1&amp;limit=50&amp;namespace=0</id>
		<title>PyWiki - New pages [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.python-ogre.org/index.php?title=Special:NewPages&amp;feed=atom&amp;hideliu=&amp;hidepatrolled=&amp;hidebots=&amp;hideredirs=1&amp;limit=50&amp;namespace=0"/>
		<link rel="alternate" type="text/html" href="http://wiki.python-ogre.org/index.php/Special:NewPages"/>
		<updated>2012-05-18T09:03:56Z</updated>
		<subtitle>From PyWiki</subtitle>
		<generator>MediaWiki 1.16.2</generator>

	<entry>
		<id>http://wiki.python-ogre.org/index.php/CodeSnippets_Using_ogreterrain</id>
		<title>CodeSnippets Using ogreterrain</title>
		<link rel="alternate" type="text/html" href="http://wiki.python-ogre.org/index.php/CodeSnippets_Using_ogreterrain"/>
				<updated>2011-02-22T21:10:21Z</updated>
		
		<summary type="html">&lt;p&gt;Andrewmac: /* Our First Terrain */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Installation =&lt;br /&gt;
You can install the ogreterrain module as you would any module via the instructions however if you encounter any errors from the installation this patch [http://sourceforge.net/tracker/download.php?group_id=186291&amp;amp;atid=916690&amp;amp;file_id=380680&amp;amp;aid=3032565] may resolve them.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Simple Terrain =&lt;br /&gt;
== Dealing with the camera ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# setting up the camera.&lt;br /&gt;
camera = self.camera&lt;br /&gt;
camera.setPosition(1683, 100, 2116)&lt;br /&gt;
camera.lookAt(1963, 50, 1660)&lt;br /&gt;
camera.setNearClipDistance(0.1)&lt;br /&gt;
camera.setFarClipDistance(50000)&lt;br /&gt;
	&lt;br /&gt;
if (self.root.getRenderSystem().getCapabilities().hasCapability(ogre.RSC_INFINITE_FAR_PLANE)):&lt;br /&gt;
	camera.setFarClipDistance(0)&lt;br /&gt;
&lt;br /&gt;
self.materialManager = ogre.MaterialManager.getSingleton()&lt;br /&gt;
self.materialManager.setDefaultTextureFiltering(ogre.TFO_ANISOTROPIC)&lt;br /&gt;
self.materialManager.setDefaultAnisotropy(7)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
What it does, besides setting the position and orientation of the camera, is adjust the near and far clip distances. &lt;br /&gt;
A terrain is often fairly big, and we want our camera to be able to see far into the distance. &lt;br /&gt;
If the RenderSystem supports it, make it infinite. We also set some defaults on the material manager.&lt;br /&gt;
&lt;br /&gt;
== Setting up directional and ambient light == &lt;br /&gt;
&lt;br /&gt;
The Terrain component uses a directional light to compute the terrain lightmap, so let's put a directional light into our scene:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
lightdir = ogre.Vector3(0.55, -0.3, 0.75)&lt;br /&gt;
lightdir.normalise()&lt;br /&gt;
        &lt;br /&gt;
light = self.sceneManager.createLight(&amp;quot;tstLight&amp;quot;)&lt;br /&gt;
light.setType(ogre.Light.LT_DIRECTIONAL)&lt;br /&gt;
light.setDirection(lightdir)&lt;br /&gt;
light.setDiffuseColour(ogre.ColourValue(1.0, 1.0, 1.0))&lt;br /&gt;
light.setSpecularColour(ogre.ColourValue(0.4, 0.4, 0.4))&lt;br /&gt;
 &lt;br /&gt;
sceneManager.AmbientLight = 0.2, 0.2, 0.2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
We also set some ambient light to smooth out the lighting.&lt;br /&gt;
&lt;br /&gt;
== Setting up the terrain ==&lt;br /&gt;
&lt;br /&gt;
First we need to define an instance of TerrainGlobalOptions(), we will need this later on:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
self.terrainGlobals = ogreterrain.TerrainGlobalOptions()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we construct our TerrainGroup object, which is managing our Terrain instances:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
self.terrainGroup = ogreterrain.TerrainGroup(self.sceneManager, ogreterrain.Terrain.ALIGN_X_Z, 513, 12000)&lt;br /&gt;
self.terrainGroup.setFilenameConvention(&amp;quot;BasicTutorial3Terrain&amp;quot;, &amp;quot;dat&amp;quot;)&lt;br /&gt;
self.terrainGroup.setOrigin(ogre.Vector3(0, 0, 0))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The TerrainGroup class constructor takes our SceneManager instance, terrain alignment option, terrain size and terrain world size as parameters. &lt;br /&gt;
Then we tell the TerrainGroup what name we would like it to use when saving our terrain, using the setFilenameConvention function. &lt;br /&gt;
And lastly we set the origin of the terrain group.&lt;br /&gt;
&lt;br /&gt;
Now it's time to configure our terrain: &lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
self.configureTerrainDefaults(light)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
We will define and explain this function later in the tutorial. Notice that we're passing our directional light to the function.&lt;br /&gt;
&lt;br /&gt;
Next we define our terrain and instruct the TerrainGroup to load it:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
self.defineTerrain(0, 0)&lt;br /&gt;
        &lt;br /&gt;
self.terrainGroup.loadAllTerrains(True)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Since we only have one terrain, we'll only be calling the defineTerrain function once. &lt;br /&gt;
If we had multiple, this is where we would load each of them.&lt;br /&gt;
&lt;br /&gt;
Now we loop through each of our imported terrains and generate the blend maps for them:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
if (self.terrainsImported):&lt;br /&gt;
	it = self.terrainGroup.getTerrainIterator()&lt;br /&gt;
	for t in self.terrainGroup.getTerrainIterator():&lt;br /&gt;
		self.initBlendMaps(t.instance)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally we cleanup the creation of the terrains by freeing resources used in the process:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
self.terrainGroup.freeTemporaryResources()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== configureTerrainDefaults ==&lt;br /&gt;
Now define a configureTerrainDefaults function with a light parameter and place the following inside it:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
self.terrainGlobals.setMaxPixelError(8)&lt;br /&gt;
self.terrainGlobals.setCompositeMapDistance(3000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
MaxPixelError decides how precise our terrain is going to be. A lower number will mean a more accurate terrain, at the cost of performance (because of more vertices). &lt;br /&gt;
CompositeMapDistance decides how far the Ogre terrain will render the lightmapped terrain.&lt;br /&gt;
&lt;br /&gt;
Next, let's deal with the lightmapping, using our directional light: &lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
self.terrainGlobals.setLightMapDirection(light.getDerivedDirection())&lt;br /&gt;
self.terrainGlobals.setCompositeMapAmbient(self.sceneManager.getAmbientLight())&lt;br /&gt;
self.terrainGlobals.setCompositeMapDiffuse(light.getDiffuseColour())&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
It uses our light to set direction and diffuse colour and sets the diffuse colour to match our scene manager's ambient light.&lt;br /&gt;
&lt;br /&gt;
Now we configure the import settings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Configure default import settings for if we use imported image&lt;br /&gt;
defaultimp = self.terrainGroup.getDefaultImportSettings()&lt;br /&gt;
defaultimp.terrainSize = 513&lt;br /&gt;
defaultimp.worldSize = 12000&lt;br /&gt;
defaultimp.inputScale = 600&lt;br /&gt;
defaultimp.minBatchSize = 33&lt;br /&gt;
defaultimp.maxBatchSize = 65&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
We won't cover the what and how of those values in this tutorial, but terrainSize and worldSize are set to match our global sizes (what we told our TerrainGroup), and inputScale decides how the heightmap image is scaled up. We are using a scale here because images have limited precision. &lt;br /&gt;
A raw heightmap, for instance, doesn't normally need scaling because the values are stored as an array of unscaled floats.&lt;br /&gt;
&lt;br /&gt;
The last bit is our textures:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# textures&lt;br /&gt;
layer0 = ogreterrain.Terrain.LayerInstance()&lt;br /&gt;
layer0.worldSize = 100&lt;br /&gt;
layer0.textureNames.append(&amp;quot;dirt_grayrocky_diffusespecular.dds&amp;quot;)&lt;br /&gt;
layer0.textureNames.append(&amp;quot;dirt_grayrocky_normalheight.dds&amp;quot;)&lt;br /&gt;
defaultimp.layerList.append(layer0)&lt;br /&gt;
&lt;br /&gt;
layer1 = ogreterrain.Terrain.LayerInstance()&lt;br /&gt;
layer1.worldSize = 30&lt;br /&gt;
layer1.textureNames.append(&amp;quot;grass_green-01_diffusespecular.dds&amp;quot;)&lt;br /&gt;
layer1.textureNames.append(&amp;quot;grass_green-01_normalheight.dds&amp;quot;)&lt;br /&gt;
defaultimp.layerList.append(layer1)&lt;br /&gt;
&lt;br /&gt;
layer2 = ogreterrain.Terrain.LayerInstance()&lt;br /&gt;
layer2.worldSize = 200&lt;br /&gt;
layer2.textureNames.append(&amp;quot;growth_weirdfungus-03_diffusespecular.dds&amp;quot;)&lt;br /&gt;
layer2.textureNames.append(&amp;quot;growth_weirdfungus-03_normalheight.dds&amp;quot;)&lt;br /&gt;
defaultimp.layerList.append(layer2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
We initialise each layer by setting the 'worldSize' and by specifying the texture names. &lt;br /&gt;
'worldSize' decides how big each splat of textures is going to be. A smaller value will increase the resolution of the rendered texture layer.&lt;br /&gt;
The default material generator takes two textures per layer:&lt;br /&gt;
* diffuse_specular - diffuse texture with a specular map in the alpha channel&lt;br /&gt;
* normal_height - normal map with a height map in the alpha channel&lt;br /&gt;
&lt;br /&gt;
== defineTerrain ==&lt;br /&gt;
This is our defineTerrain function:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def defineTerrain(self, x, y):&lt;br /&gt;
	filename = self.terrainGroup.generateFilename(x, y)&lt;br /&gt;
		RGM = ogre.ResourceGroupManager.getSingleton()&lt;br /&gt;
		if ( RGM.resourceExists(self.terrainGroup.getResourceGroup(), filename) ):&lt;br /&gt;
			self.terrainGroup.defineTerrain(x, y)&lt;br /&gt;
		else :&lt;br /&gt;
			img = self.getTerrainImage((x % 2) != 0, (y%2) != 0)&lt;br /&gt;
			self.terrainGroup.defineTerrain(x, y, img)&lt;br /&gt;
			self.terrainsImported = True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This function is simple, but clever: &lt;br /&gt;
First, it asks our TerrainGroup what file name it would use to generate the terrain. &lt;br /&gt;
Then if checks if there is a file by that name in our resource group. &lt;br /&gt;
If there is, it means that we generated a binary terrain data file already, and thus there is no need to import it from an image. &lt;br /&gt;
If there isn't a data file present, it means we have to generate our terrain, and we load the image and use that to define it.&lt;br /&gt;
&lt;br /&gt;
The function uses a small utility function called getTerrainImage defined below:&lt;br /&gt;
&lt;br /&gt;
== getTerrainImage ==&lt;br /&gt;
This function loads 'terrain.png' from our resource locations, and flips it if necessary.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def getTerrainImage(self, flipX, flipY):&lt;br /&gt;
	img = ogre.Image()&lt;br /&gt;
	img.load(&amp;quot;terrain.png&amp;quot;, ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME)&lt;br /&gt;
	if flipX:&lt;br /&gt;
		img.flipAroundY()&lt;br /&gt;
	if flipY:&lt;br /&gt;
		img.flipAroundX() &lt;br /&gt;
	return img&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== initBlendMaps ==&lt;br /&gt;
This is the initBlendMaps function in its entirety: &lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def initBlendMaps(self, terrain):&lt;br /&gt;
	blendMap0 = terrain.getLayerBlendMap(1)&lt;br /&gt;
	blendMap1 = terrain.getLayerBlendMap(2)&lt;br /&gt;
	minHeight0 = 70&lt;br /&gt;
	fadeDist0 = 40.0&lt;br /&gt;
	minHeight1 = 70&lt;br /&gt;
	fadeDist1 = 15.0&lt;br /&gt;
&lt;br /&gt;
	pBlend1 = blendMap1.getBlendPointer()    # returns the address of the buffer&lt;br /&gt;
	size = terrain.getLayerBlendMapSize() * terrain.getLayerBlendMapSize()&lt;br /&gt;
	blend_data=(ctypes.c_float * size).from_address(pBlend1)&lt;br /&gt;
	index = 0&lt;br /&gt;
	for y in range(terrain.getLayerBlendMapSize()):&lt;br /&gt;
		for x in range( terrain.getLayerBlendMapSize() ):&lt;br /&gt;
			# using ctypes&lt;br /&gt;
			tx = ctypes.c_float(0.0)&lt;br /&gt;
			ty = ctypes.c_float(0.0)&lt;br /&gt;
                &lt;br /&gt;
			blendMap0.convertImageToTerrainSpace(x, y, ctypes.addressof(tx), ctypes.addressof(ty))&lt;br /&gt;
			height = terrain.getHeightAtTerrainPosition(tx.value, ty.value)&lt;br /&gt;
			val = (height - minHeight0) / fadeDist0&lt;br /&gt;
			val = Clamp(val, 0, 1)&lt;br /&gt;
&lt;br /&gt;
			val = (height - minHeight1) / fadeDist1&lt;br /&gt;
			val = Clamp(val, 0, 1)&lt;br /&gt;
			blend_data [index] = val&lt;br /&gt;
			index += 1&lt;br /&gt;
                &lt;br /&gt;
	blendMap0.dirty()&lt;br /&gt;
	blendMap1.dirty()&lt;br /&gt;
	blendMap0.update()&lt;br /&gt;
	blendMap1.update() &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We won't go into the gritty details of how it works in this tutorial. &lt;br /&gt;
Let's just say that it uses the terrain height to splat the three layers on the terrain. &lt;br /&gt;
Notice the use of getLayerBlendMap and getBlendPointer. &lt;br /&gt;
'Nuff said.&lt;br /&gt;
&lt;br /&gt;
== Compile and Run == &lt;br /&gt;
You can save this in the python-ogre folder under demos/ogre so it can run using the same plugins.cfg/resources.cfg as the other python-ogre demos, however you do need to add the following two resources to resources.cfg:&lt;br /&gt;
 FileSystem=../media/materials/textures/nvidia&lt;br /&gt;
 FileSystem=../media/PCZAppMedia&lt;br /&gt;
&lt;br /&gt;
Here is the source code in its entirety:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
sys.path.insert(0,'..')&lt;br /&gt;
import PythonOgreConfig&lt;br /&gt;
&lt;br /&gt;
import ogre.renderer.OGRE as ogre&lt;br /&gt;
import ogre.renderer.ogreterrain as ogreterrain&lt;br /&gt;
import SampleFramework as sf&lt;br /&gt;
import ctypes as ctypes&lt;br /&gt;
&lt;br /&gt;
def Clamp ( val, low, high ):&lt;br /&gt;
    	if val &amp;lt; low: return low&lt;br /&gt;
    	if val &amp;gt; high: return high&lt;br /&gt;
    	return val&lt;br /&gt;
&lt;br /&gt;
class TerrainApplication(sf.Application):&lt;br /&gt;
&lt;br /&gt;
	def _chooseSceneManager(self):&lt;br /&gt;
		# self.sceneManager = self.root.createSceneManager(&amp;quot;TerrainSceneManager&amp;quot;)&lt;br /&gt;
		self.sceneManager = self.root.createSceneManager(ogre.ST_GENERIC)&lt;br /&gt;
&lt;br /&gt;
	def _createScene(self):&lt;br /&gt;
		sceneManager = self.sceneManager&lt;br /&gt;
        &lt;br /&gt;
		# setting up the camera.&lt;br /&gt;
		camera = self.camera&lt;br /&gt;
		camera.setPosition(1683, 100, 2116)&lt;br /&gt;
		camera.lookAt(1963, 50, 1660)&lt;br /&gt;
		camera.setNearClipDistance(0.1)&lt;br /&gt;
		camera.setFarClipDistance(50000)&lt;br /&gt;
	&lt;br /&gt;
		if (self.root.getRenderSystem().getCapabilities().hasCapability(ogre.RSC_INFINITE_FAR_PLANE)):&lt;br /&gt;
			camera.setFarClipDistance(0)&lt;br /&gt;
 &lt;br /&gt;
		self.materialManager = ogre.MaterialManager.getSingleton()&lt;br /&gt;
		self.materialManager.setDefaultTextureFiltering(ogre.TFO_ANISOTROPIC)&lt;br /&gt;
		self.materialManager.setDefaultAnisotropy(7)&lt;br /&gt;
 &lt;br /&gt;
		lightdir = ogre.Vector3(0.55, -0.3, 0.75)&lt;br /&gt;
		lightdir.normalise()&lt;br /&gt;
        &lt;br /&gt;
		light = self.sceneManager.createLight(&amp;quot;tstLight&amp;quot;)&lt;br /&gt;
		light.setType(ogre.Light.LT_DIRECTIONAL)&lt;br /&gt;
		light.setDirection(lightdir)&lt;br /&gt;
		light.setDiffuseColour(ogre.ColourValue(1.0, 1.0, 1.0))&lt;br /&gt;
		light.setSpecularColour(ogre.ColourValue(0.4, 0.4, 0.4))&lt;br /&gt;
 &lt;br /&gt;
		sceneManager.AmbientLight = 0.2, 0.2, 0.2&lt;br /&gt;
        	&lt;br /&gt;
		self.terrainGlobals = ogreterrain.TerrainGlobalOptions()&lt;br /&gt;
		self.terrainGroup = ogreterrain.TerrainGroup(self.sceneManager, ogreterrain.Terrain.ALIGN_X_Z, 513, 12000)&lt;br /&gt;
		self.terrainGroup.setFilenameConvention(&amp;quot;BasicTutorial3Terrain&amp;quot;, &amp;quot;dat&amp;quot;)&lt;br /&gt;
		self.terrainGroup.setOrigin(ogre.Vector3(0, 0, 0))&lt;br /&gt;
        &lt;br /&gt;
		self.configureTerrainDefaults(light)&lt;br /&gt;
        &lt;br /&gt;
		self.defineTerrain(0, 0)&lt;br /&gt;
        &lt;br /&gt;
		self.terrainGroup.loadAllTerrains(True)&lt;br /&gt;
&lt;br /&gt;
		if (self.terrainsImported):&lt;br /&gt;
			it = self.terrainGroup.getTerrainIterator()&lt;br /&gt;
			for t in self.terrainGroup.getTerrainIterator():&lt;br /&gt;
				self.initBlendMaps(t.instance)&lt;br /&gt;
&lt;br /&gt;
		self.terrainGroup.freeTemporaryResources()&lt;br /&gt;
        &lt;br /&gt;
	def configureTerrainDefaults(self, light):&lt;br /&gt;
		self.terrainGlobals.setMaxPixelError(8)&lt;br /&gt;
		self.terrainGlobals.setCompositeMapDistance(3000)&lt;br /&gt;
		self.terrainGlobals.setLightMapDirection(light.getDerivedDirection())&lt;br /&gt;
		self.terrainGlobals.setCompositeMapAmbient(self.sceneManager.getAmbientLight())&lt;br /&gt;
		self.terrainGlobals.setCompositeMapDiffuse(light.getDiffuseColour())&lt;br /&gt;
	&lt;br /&gt;
		# Configure default import settings for if we use imported image&lt;br /&gt;
		defaultimp = self.terrainGroup.getDefaultImportSettings()&lt;br /&gt;
		defaultimp.terrainSize = 513&lt;br /&gt;
		defaultimp.worldSize = 12000&lt;br /&gt;
		defaultimp.inputScale = 600&lt;br /&gt;
		defaultimp.minBatchSize = 33&lt;br /&gt;
		defaultimp.maxBatchSize = 65&lt;br /&gt;
&lt;br /&gt;
		# textures&lt;br /&gt;
		layer0 = ogreterrain.Terrain.LayerInstance()&lt;br /&gt;
		layer0.worldSize = 100&lt;br /&gt;
		layer0.textureNames.append(&amp;quot;dirt_grayrocky_diffusespecular.dds&amp;quot;)&lt;br /&gt;
		layer0.textureNames.append(&amp;quot;dirt_grayrocky_normalheight.dds&amp;quot;)&lt;br /&gt;
		defaultimp.layerList.append(layer0)&lt;br /&gt;
&lt;br /&gt;
		layer1 = ogreterrain.Terrain.LayerInstance()&lt;br /&gt;
		layer1.worldSize = 30&lt;br /&gt;
		layer1.textureNames.append(&amp;quot;grass_green-01_diffusespecular.dds&amp;quot;)&lt;br /&gt;
		layer1.textureNames.append(&amp;quot;grass_green-01_normalheight.dds&amp;quot;)&lt;br /&gt;
		defaultimp.layerList.append(layer1)&lt;br /&gt;
&lt;br /&gt;
		layer2 = ogreterrain.Terrain.LayerInstance()&lt;br /&gt;
		layer2.worldSize = 200&lt;br /&gt;
		layer2.textureNames.append(&amp;quot;growth_weirdfungus-03_diffusespecular.dds&amp;quot;)&lt;br /&gt;
		layer2.textureNames.append(&amp;quot;growth_weirdfungus-03_normalheight.dds&amp;quot;)&lt;br /&gt;
		defaultimp.layerList.append(layer2)&lt;br /&gt;
        &lt;br /&gt;
	def defineTerrain(self, x, y):&lt;br /&gt;
		filename = self.terrainGroup.generateFilename(x, y)&lt;br /&gt;
		RGM = ogre.ResourceGroupManager.getSingleton()&lt;br /&gt;
		if ( RGM.resourceExists(self.terrainGroup.getResourceGroup(), filename) ):&lt;br /&gt;
			self.terrainGroup.defineTerrain(x, y)&lt;br /&gt;
		else :&lt;br /&gt;
			img = self.getTerrainImage((x % 2) != 0, (y%2) != 0)&lt;br /&gt;
			self.terrainGroup.defineTerrain(x, y, img)&lt;br /&gt;
			self.terrainsImported = True&lt;br /&gt;
                &lt;br /&gt;
	def getTerrainImage(self, flipX, flipY):&lt;br /&gt;
		img = ogre.Image()&lt;br /&gt;
		img.load(&amp;quot;terrain.png&amp;quot;, ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME)&lt;br /&gt;
		if flipX:&lt;br /&gt;
			img.flipAroundY()&lt;br /&gt;
		if flipY:&lt;br /&gt;
			img.flipAroundX() &lt;br /&gt;
		return img&lt;br /&gt;
            &lt;br /&gt;
	def initBlendMaps(self, terrain):&lt;br /&gt;
		blendMap0 = terrain.getLayerBlendMap(1)&lt;br /&gt;
		blendMap1 = terrain.getLayerBlendMap(2)&lt;br /&gt;
		minHeight0 = 70&lt;br /&gt;
		fadeDist0 = 40.0&lt;br /&gt;
		minHeight1 = 70&lt;br /&gt;
		fadeDist1 = 15.0&lt;br /&gt;
&lt;br /&gt;
		pBlend1 = blendMap1.getBlendPointer()    # returns the address of the buffer&lt;br /&gt;
		size = terrain.getLayerBlendMapSize() * terrain.getLayerBlendMapSize()&lt;br /&gt;
		blend_data=(ctypes.c_float * size).from_address(pBlend1)&lt;br /&gt;
		index = 0&lt;br /&gt;
		for y in range(terrain.getLayerBlendMapSize()):&lt;br /&gt;
			for x in range( terrain.getLayerBlendMapSize() ):&lt;br /&gt;
				# using ctypes&lt;br /&gt;
				tx = ctypes.c_float(0.0)&lt;br /&gt;
				ty = ctypes.c_float(0.0)&lt;br /&gt;
                &lt;br /&gt;
				blendMap0.convertImageToTerrainSpace(x, y, ctypes.addressof(tx), ctypes.addressof(ty))&lt;br /&gt;
				height = terrain.getHeightAtTerrainPosition(tx.value, ty.value)&lt;br /&gt;
				val = (height - minHeight0) / fadeDist0&lt;br /&gt;
				val = Clamp(val, 0, 1)&lt;br /&gt;
&lt;br /&gt;
				val = (height - minHeight1) / fadeDist1&lt;br /&gt;
				val = Clamp(val, 0, 1)&lt;br /&gt;
				blend_data [index] = val&lt;br /&gt;
				index += 1&lt;br /&gt;
                &lt;br /&gt;
		blendMap0.dirty()&lt;br /&gt;
		blendMap1.dirty()&lt;br /&gt;
		blendMap0.update()&lt;br /&gt;
		blendMap1.update()        &lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
	try:&lt;br /&gt;
		application = TerrainApplication()&lt;br /&gt;
		application.go()&lt;br /&gt;
	except ogre.OgreException, e:&lt;br /&gt;
		print e&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Andrewmac</name></author>	</entry>

	</feed>
