void SnowTerrain::initBlendMaps(Terrain* terrain)
	{
		TextureLayerFileList blendImages = mSnowConfig->terrainSettings.textureBlendFileList;

		// load those blendmaps into the layers
		for(int j = 0;j < terrain->getLayerCount();j++)
		{
			// skip first layer
			if(j==0)
				continue;

			// no blend map for this layer
			if(blendImages.size() >= j && blendImages[j].length() == 0)
				continue;

			Ogre::TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(j);
			Ogre::Image img;

			img.load(blendImages[j],"General");
			int blendmapsize = terrain->getLayerBlendMapSize();
			if(img.getWidth() != blendmapsize)
				img.resize(blendmapsize, blendmapsize);

			float *ptr = blendmap->getBlendPointer();
			Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data);

			for(int bp = 0;bp < blendmapsize * blendmapsize;bp++)
				ptr[bp] = static_cast<float>(data[bp]) / 255.0f;

			blendmap->dirty();
			blendmap->update();
		}
	}
Beispiel #2
0
void TerrainManager::EditLayerTerrain(Ogre::Terrain *terrain, const Ogre::Vector3 &centerPos, float timeElapsed)
{
	Ogre::Vector3 tsPos;
	terrain->getTerrainPosition(centerPos, &tsPos);

	Ogre::TerrainLayerBlendMap* layer = terrain->getLayerBlendMap(m_nLayerNum);
	int d(terrain->getLayerBlendMapSize());
	int t(terrain->getLayerCount());
	// we need image coords
	float imgSize = terrain->getLayerBlendMapSize();
	long startx = (tsPos.x - m_fBrushSize) * imgSize;
	long starty = (tsPos.y - m_fBrushSize) * imgSize;
	long endx = (tsPos.x + m_fBrushSize) * imgSize;
	long endy= (tsPos.y + m_fBrushSize) * imgSize;
	startx = std::max(startx, 0L);
	starty = std::max(starty, 0L);
	endx = std::min(endx, (long)imgSize);
	endy = std::min(endy, (long)imgSize);
	for (long y = starty; y <= endy; ++y)
	{
		for (long x = startx; x <= endx; ++x)
		{
			float tsXdist = (x / imgSize) - tsPos.x;
			float tsYdist = (y / imgSize)  - tsPos.y;

			float weight = std::min((float)1.0, 
				Ogre::Math::Sqrt(tsYdist * tsYdist + tsXdist * tsXdist) / float(0.5 * m_fBrushSize));
			weight = 1.0 - (weight * weight);

			float paint = weight * timeElapsed;
			size_t imgY = imgSize - y;
			float val = 0;
			if(GetAsyncKeyState(VK_UP))
				val = layer->getBlendValue(x, imgY) + paint;
			else if(GetAsyncKeyState(VK_DOWN))
				val = layer->getBlendValue(x, imgY) - paint;
			val = Ogre::Math::Clamp(val, 0.0f, 1.0f);
			layer->setBlendValue(x, imgY, val);

		}
	}

	layer->update();
}
void DotSceneLoader::processBlendmaps(rapidxml::xml_node<>* XMLNode)
{
    int pageX = Ogre::StringConverter::parseInt(XMLNode->first_attribute("pageX")->value());
    int pageY = Ogre::StringConverter::parseInt(XMLNode->first_attribute("pageY")->value());

    Ogre::String filename = mTerrainGroup->generateFilename(pageX, pageY);
    // skip this is terrain page has been saved already
    if (!Ogre::ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename))
    {
        rapidxml::xml_node<>* pElement;

        // Process blendmaps (*)
        std::vector<Ogre::String> blendMaps;
        rapidxml::xml_node<>* pBlendmap;
        pElement = XMLNode->first_node("blendMaps");
        pBlendmap = pElement->first_node("blendMap");
        while(pBlendmap)
        {
            blendMaps.push_back(getAttrib(pBlendmap, "texture",""));
            pBlendmap = pBlendmap->next_sibling("blendMap");
        }

        for(int j = 1;j < mTerrainGroup->getTerrain(pageX, pageY)->getLayerCount();j++)
        {
            Ogre::TerrainLayerBlendMap *blendmap = mTerrainGroup->getTerrain(pageX, pageY)->getLayerBlendMap(j);
            Ogre::Image img;
            img.load(blendMaps[j-1],"General");
            int blendmapsize = mTerrainGroup->getTerrain(pageX, pageY)->getLayerBlendMapSize();
            if(img.getWidth() != blendmapsize)
                img.resize(blendmapsize, blendmapsize);

            float *ptr = blendmap->getBlendPointer();
            Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data);

            for(int bp = 0;bp < blendmapsize * blendmapsize;bp++)
                ptr[bp] = static_cast<float>(data[bp]) / 255.0f;

            blendmap->dirty();
            blendmap->update();
        }
    }
}
void TerrainGeometryManager::initBlendMaps(int x, int z, Ogre::Terrain* terrain )
{
	bool debugBlendMaps = BOPT("DebugBlendMaps", false);

	int layerCount = terrain->getLayerCount();
	for (int i = 1; i < layerCount; i++)
	{
		blendLayerInfo_t &bi = blendInfo[i];

		if(bi.blendMapTextureFilename.empty()) continue;

		Ogre::Image img;
		//std::pair<uint8,uint8> textureIndex = terrain->getLayerBlendTextureIndex(i);
		//uint8 bti = terrain->getBlendTextureIndex(i);
		try
		{
			img.load(bi.blendMapTextureFilename, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
		} catch(Exception &e)
		{
			LOG("Error loading blendmap: " + bi.blendMapTextureFilename + " : " + e.getFullDescription());
			continue;
		}

		TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(i);

		// resize that blending map so it will fit
		Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
		if (img.getWidth() != blendmapSize)
			img.resize(blendmapSize, blendmapSize);

		// now to the ugly part
		float* ptr = blendmap->getBlendPointer();
		for (Ogre::uint32 z = 0; z != blendmapSize; z++)
		{
			for (Ogre::uint32 x = 0; x != blendmapSize; x++)
			{
				Ogre::ColourValue c = img.getColourAt(x, z, 0);
				float alpha = bi.alpha;
				if      (bi.blendMode == 'R')
					*ptr++ = c.r * alpha;
				else if (bi.blendMode == 'G')
					*ptr++ = c.g * alpha;
				else if (bi.blendMode == 'B')
					*ptr++ = c.b * alpha;
				else if (bi.blendMode == 'A')
					*ptr++ = c.a * alpha;
			}
		}
		blendmap->dirty();
		blendmap->update();
	}

	if (debugBlendMaps)
	{
		for (int i = 1; i < layerCount; i++)
		{
			Ogre::TerrainLayerBlendMap* blendMap = terrain->getLayerBlendMap(i);
			Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
			Ogre::Image img;
			unsigned short *idata = OGRE_ALLOC_T(unsigned short, blendmapSize * blendmapSize, Ogre::MEMCATEGORY_RESOURCE);
			float scale = 65535.0f;
			for (unsigned int x = 0; x < blendmapSize; x++)
				for (unsigned int z = 0; z < blendmapSize; z++)
					idata[x + z * blendmapSize] = (unsigned short)(blendMap->getBlendValue(x, blendmapSize - z) * scale);
			img.loadDynamicImage((Ogre::uchar*)(idata), blendmapSize, blendmapSize, Ogre::PF_L16);
			std::string fileName = "blendmap_layer_" + Ogre::StringConverter::toString(i) + ".png";
			img.save(fileName);
			OGRE_FREE(idata, Ogre::MEMCATEGORY_RESOURCE);
		}
	}
}
//-----------------------------------------------------------------------------------------
void CTerrainGroupEditor::_splat(CTerrainPageEditor *handle, Ogre::Vector3 &editpos, float timePassed)
{
    Ogre::Rect brushrect, maprect;

    Ogre::Terrain *terrain = static_cast<Ogre::Terrain*>(handle->getHandle());

    int mBlendMapSize = terrain->getLayerBlendMapSize();
    editpos.x *= (float)mBlendMapSize;
    editpos.y = (1.0f - editpos.y) * (float)mBlendMapSize;
    if(!_getEditRect(editpos, brushrect, maprect, mBlendMapSize))
        return;

    int mLayer = 0;

    mLayer = handle->_getLayerID(mTextureDiffuse, mTextureNormal, mEditDirection);

    if(mLayer == -1)
    {
        Ogre::String msg = handle->getName() + " already has the maximum number of supported texture layers.";
        mSystem->DisplayMessageDialog(OTR(msg), DLGTYPE_OK);
        return;
    }
    else if(mLayer == 0)
    {
        Ogre::TerrainLayerBlendMap *mBlendMaps[128];
        float *mBlendDatas[128];
        int mLayerMax = terrain->getLayerCount();

        for(int l = 1;l < mLayerMax;l++)
        {
            mBlendMaps[l] = terrain->getLayerBlendMap(l);
            mBlendDatas[l] = mBlendMaps[l]->getBlendPointer();
        }

        float maxVal;
        int u;
        int num;

        for(u = mLayerMax-1;u > 0;u--)
        {
            mLayer = u;
            maxVal = 0.0f;

            for(int j = maprect.top;j < maprect.bottom;j++)
            {
                int mapPos = (j * mBlendMapSize) + maprect.left;

                for(int i = maprect.left;i < maprect.right;i++)
                {
                    maxVal += mBlendDatas[u][mapPos];
                }
            }

            num = (maprect.top*mBlendMapSize);
            num = (num+maprect.right)-(num+maprect.left);
            if (maxVal > num)
                break;
        }

        if (mLayer == 0)
            return;

        mEditDirection = true;
    }

    handle->_notifyModification(mLayer, maprect);

    int mLayerMax = terrain->getLayerCount();
    Ogre::TerrainLayerBlendMap *mBlendMaps[128];
    float *mBlendDatas[128];

    Ogre::TerrainLayerBlendMap *mCurrentBlendMap = terrain->getLayerBlendMap(mLayer);
    float *mCurrentBlendData = mCurrentBlendMap->getBlendPointer();

    for(int l = mLayer;l < mLayerMax;l++)
    {
        mBlendMaps[l] = terrain->getLayerBlendMap(l);
        mBlendDatas[l] = mBlendMaps[l]->getBlendPointer();
    }

    float mRatio = (float)BRUSH_DATA_SIZE / (float)mBrushSize;
    float brushPos;
    int mapPos;

    int right = brushrect.right;
    brushrect.right = BRUSH_DATA_SIZE - brushrect.left;
    brushrect.left = BRUSH_DATA_SIZE - right;

    float factor = mBrushIntensity * timePassed * 0.2f;
    if(!mEditDirection)
    {
        int u;
        float sum;

        for(int j = maprect.top;j < maprect.bottom;j++)
        {
            brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE;
            brushPos += brushrect.right;

            mapPos = (j * mBlendMapSize) + maprect.left;

            for(int i = maprect.left;i < maprect.right;i++)
            {
                brushPos -= mRatio;

                assert(mapPos < (mBlendMapSize * mBlendMapSize) && mapPos >= 0);
                assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0);

                sum = 0.0f;

                for(u = mLayer + 1;u < mLayerMax;u++)
                    sum += mBlendDatas[u][mapPos];

                float val = mCurrentBlendData[mapPos] + (mBrushData[(int)brushPos] * factor);
                sum += val;

                if(sum > 1.0f)
                {
                    float normfactor = 1.0f / (float)sum;
                    mCurrentBlendData[mapPos] = val * normfactor;
                    for(u = mLayer + 1;u < mLayerMax;u++)
                        mBlendDatas[u][mapPos] *= normfactor;
                }
                else
                    mCurrentBlendData[mapPos] = val;

                ++mapPos;
            }
        }
        for(u = mLayer;u < mLayerMax;u++)
        {
            mBlendMaps[u]->dirtyRect(maprect);
            mBlendMaps[u]->update();
        }
    }
    else
    {
        for(int j = maprect.top;j < maprect.bottom;j++)
        {
            brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE;
            brushPos += brushrect.right;

            mapPos = (j * mBlendMapSize) + maprect.left;

            for(int i = maprect.left;i < maprect.right;i++)
            {
                brushPos -= mRatio;

                assert(mapPos < (mBlendMapSize * mBlendMapSize) && mapPos >= 0);
                assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0);

                float val = mCurrentBlendData[mapPos] - (mBrushData[(int)brushPos] * factor);

                if(val < 0.0f)
                    val = 0.0f;

                mCurrentBlendData[mapPos] = val;
                ++mapPos;
            }
        }
        mCurrentBlendMap->dirtyRect(maprect);
        mCurrentBlendMap->update();
    }
}
Beispiel #6
0
void ManipulatorTerrain::OnEdit( float dt )
{
	assert(m_curEditMode != eTerrainEditMode_None);

	//第0层不能编辑BlendMap,应该从第1层开始
	if(m_curEditMode == eTerrainEditMode_Splat && m_curEditLayer == 0)
		return;

	Ogre::Terrain* pTerrain = ManipulatorSystem.GetScene()->GetTerrain();

	const Vector3 brushPos = m_brush[m_curBrushIndex]->GetPosition();
	Vector3 tsPos;
	pTerrain->getTerrainPosition(brushPos, &tsPos);

	float brushSizeW, brushSizeH;
	m_brush[m_curBrushIndex]->GetDimension(brushSizeW, brushSizeH);
	float worldSize = GetWorldSize();
	brushSizeW /= worldSize;
	brushSizeH /= worldSize;

	int multiplier;
	Ogre::TerrainLayerBlendMap* layer = nullptr;
	if(m_curEditMode == eTerrainEditMode_Deform)
	{
		multiplier = pTerrain->getSize() - 1;
	}
	else
	{
		multiplier = pTerrain->getLayerBlendMapSize();
		layer = pTerrain->getLayerBlendMap(m_curEditLayer);
	}

	long startx = (long)((tsPos.x - brushSizeW / 2) * multiplier);
	long starty = (long)((tsPos.y - brushSizeH / 2) * multiplier);
	long endx = (long)((tsPos.x + brushSizeW / 2) * multiplier);
	long endy= (long)((tsPos.y + brushSizeH / 2) * multiplier);
	startx = max(startx, 0L);
	starty = max(starty, 0L);
	endx = min(endx, (long)multiplier);
	endy = min(endy, (long)multiplier);
	
	for (long y = starty; y <= endy; ++y)
	{
		for (long x = startx; x <= endx; ++x)
		{
			float tsXdist = (x / multiplier) - tsPos.x;
			float tsYdist = (y / multiplier)  - tsPos.y;

			if(m_curEditMode == eTerrainEditMode_Deform)
			{
				float* pData = pTerrain->getHeightData();
				pData[y*GetMapSize()+x] += 100.0f * dt;

			}
			else
			{
				float* pData = layer->getBlendPointer();
				size_t imgY = multiplier - y;
				float newValue = pData[imgY*multiplier+x] + dt;
				newValue = Ogre::Math::Clamp(newValue, 0.0f, 1.0f);
				pData[imgY*multiplier+x] = newValue;
			}
		}
	}
	
	
	if(m_curEditMode == eTerrainEditMode_Deform)
	{
		Ogre::Rect rect(startx, starty, endx, endy);
		pTerrain->dirtyRect(rect);
		pTerrain->update();
	}
	else
	{
		size_t imgStartY = multiplier - starty;
		size_t imgEndY = multiplier - endy;
		Ogre::Rect rect(startx, min(imgStartY,imgEndY), endx, max(imgStartY,imgEndY));

		layer->dirtyRect(rect);
		layer->update();
	}
}
Beispiel #7
0
//-----------------------------------------------------------------------------------------
void CTerrainGroupEditor::_splat(CTerrainPageEditor *handle, Ogre::Vector3 &editpos, float timePassed)
{
    Ogre::Rect brushrect, maprect;

    Ogre::Terrain *terrain = static_cast<Ogre::Terrain*>(handle->getHandle());

    int mBlendMapSize = terrain->getLayerBlendMapSize();
    editpos.x *= (float)mBlendMapSize;
    editpos.y = (1.0f - editpos.y) * (float)mBlendMapSize;
    if(!_getEditRect(editpos, brushrect, maprect, mBlendMapSize))
        return;

    int mLayer = 0;

    mLayer = handle->_getLayerID(mTextureDiffuse, mTextureNormal, mEditDirection);

    if(mLayer < 1)
        return;

    handle->_notifyModification(mLayer, maprect);

    int mLayerMax = terrain->getLayerCount();
    Ogre::TerrainLayerBlendMap *mBlendMaps[128];
    float *mBlendDatas[128];

    Ogre::TerrainLayerBlendMap *mCurrentBlendMap = terrain->getLayerBlendMap(mLayer);
    float *mCurrentBlendData = mCurrentBlendMap->getBlendPointer();

    for(int l = mLayer;l < mLayerMax;l++)
    {
        mBlendMaps[l] = terrain->getLayerBlendMap(l);
        mBlendDatas[l] = mBlendMaps[l]->getBlendPointer();
    }

    float mRatio = (float)BRUSH_DATA_SIZE / (float)mBrushSize;
    float brushPos;
    int mapPos;

    int right = brushrect.right;
    brushrect.right = BRUSH_DATA_SIZE - brushrect.left;
    brushrect.left = BRUSH_DATA_SIZE - right;

    float factor = mBrushIntensity * timePassed * 0.2f;
    if(!mEditDirection)
    {
        int u;
        float sum;

        for(int j = maprect.top;j < maprect.bottom;j++)
        {
            brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE;
            brushPos += brushrect.right;

            mapPos = (j * mBlendMapSize) + maprect.left;

            for(int i = maprect.left;i < maprect.right;i++)
            {
                brushPos -= mRatio;

                assert(mapPos < (mBlendMapSize * mBlendMapSize) && mapPos >= 0);
                assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0);

                sum = 0.0f;

                for(u = mLayer + 1;u < mLayerMax;u++)
                    sum += mBlendDatas[u][mapPos];

                float val = mCurrentBlendData[mapPos] + (mBrushData[(int)brushPos] * factor);
                sum += val;

                if(sum > 1.0f)
                {
                    float normfactor = 1.0f / (float)sum;
                    mCurrentBlendData[mapPos] = val * normfactor;
                    for(u = mLayer + 1;u < mLayerMax;u++)
                        mBlendDatas[u][mapPos] *= normfactor;
                }
                else
                    mCurrentBlendData[mapPos] = val;

                ++mapPos;
            }
        }
        for(u = mLayer;u < mLayerMax;u++)
        {
            mBlendMaps[u]->dirtyRect(maprect);
            mBlendMaps[u]->update();
        }
    }
    else
    {
        for(int j = maprect.top;j < maprect.bottom;j++)
        {
            brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE;
            brushPos += brushrect.right;

            mapPos = (j * mBlendMapSize) + maprect.left;

            for(int i = maprect.left;i < maprect.right;i++)
            {
                brushPos -= mRatio;

                assert(mapPos < (mBlendMapSize * mBlendMapSize) && mapPos >= 0);
                assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0);

                float val = mCurrentBlendData[mapPos] - (mBrushData[(int)brushPos] * factor);

                if(val < 0.0f)
                    val = 0.0f;

                mCurrentBlendData[mapPos] = val;
                ++mapPos;
            }
        }
        mCurrentBlendMap->dirtyRect(maprect);
        mCurrentBlendMap->update();
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
	// ------------------------- Check for command line argument -------------------------------------------

	if (! argv[1])
	{
		printf("\n");
		printf("Missing argument.\nExample: \"Converter.exe job1.cfg\"");		
		return 0;	
	}

	// ------------------------- Basic Ogre Engine initialization -------------------------------------------

	Ogre::Root* root = new Ogre::Root;	
	Ogre::RenderSystem* rendersys = root->getRenderSystemByName("Direct3D9 Rendering Subsystem");
	
	rendersys->setConfigOption("Full Screen", "No");
	rendersys->setConfigOption("Video Mode", "800 x 600 @ 32-bit colour");
	
	root->setRenderSystem(rendersys);		
	
	Ogre::ResourceGroupManager::getSingleton().addResourceLocation("resource", "FileSystem", "General");
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

	root->initialise(false);

	Ogre::RenderWindow* window = root->createRenderWindow("RAW2OGT", 800, 600, false);		
	Ogre::SceneManager* scenemgr = root->createSceneManager(Ogre::SceneType::ST_GENERIC);
	Ogre::Camera* camera = scenemgr->createCamera("camera");
	Ogre::Viewport* viewport = window->addViewport(camera);
	/*Ogre::Vector3 lightdir(0, -0.3, 0.75);
	lightdir.normalise();

	Ogre::Light* l = scenemgr->createLight("tstLight");
	l->setType(Ogre::Light::LT_DIRECTIONAL);
	l->setDirection(lightdir);
	l->setDiffuseColour(Ogre::ColourValue(1.0, 1.0, 1.0));
	l->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));*/

	scenemgr->setAmbientLight(Ogre::ColourValue(0.7, 0.7, 0.7));
	
	// --------------------------------- Start convert ----------------------------------------------------

	// Load job config
	Ogre::ConfigFile* terrainconfig = OGRE_NEW Ogre::ConfigFile();
	terrainconfig->loadDirect(argv[1]);
		
	// Load info from [general] block
	Ogre::String heightmapfile = terrainconfig->getSetting("heightmap", "general");
	Ogre::Real heightmapscale = Ogre::StringConverter::parseReal(terrainconfig->getSetting("heightmapscale", "general"));
	Ogre::Real heightmapoffset = Ogre::StringConverter::parseReal(terrainconfig->getSetting("heightmapoffset", "general"));
	Ogre::uint16 terrainsize = Ogre::StringConverter::parseUnsignedInt(terrainconfig->getSetting("terrainsize", "general"));
	Ogre::Real worldsize = Ogre::StringConverter::parseReal(terrainconfig->getSetting("worldsize", "general"));
	Ogre::uint16 layercount = Ogre::StringConverter::parseUnsignedInt(terrainconfig->getSetting("layercount", "general"));

	// initialise stream to heightmapfile
	Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(heightmapfile, "General");
	size_t size = stream.get()->size();
		
	// verify size
	if(size != terrainsize * terrainsize * 4)
		OGRE_EXCEPT( Ogre::Exception::ERR_INTERNAL_ERROR, "Size of stream does not match terrainsize!", "TerrainPage" );
					
	// load to buffer
	float* buffer = OGRE_ALLOC_T(float, size, Ogre::MEMCATEGORY_GENERAL);
	stream->read(buffer, size);

	// apply scale and offset 
	for(int i=0;i<terrainsize*terrainsize;i++)
	{
		buffer[i]  = (buffer[i] + heightmapoffset) * heightmapscale;
	}

	// Terrain initialization
	Ogre::TerrainGlobalOptions* terrainglobals = OGRE_NEW Ogre::TerrainGlobalOptions();
	terrainglobals->setMaxPixelError(1);
	//terrainglobals->setCompositeMapDistance(30000);
	//terrainglobals->setLightMapDirection(lightdir);
    //terrainglobals->setCompositeMapAmbient(scenemgr->getAmbientLight());
    //terrainglobals->setCompositeMapDiffuse(l->getDiffuseColour());
	
	Ogre::TerrainMaterialGeneratorA::SM2Profile* pMatProfile = 
      static_cast<Ogre::TerrainMaterialGeneratorA::SM2Profile*>(terrainglobals->getDefaultMaterialGenerator()->getActiveProfile());
	
	pMatProfile->setLightmapEnabled(false);
	pMatProfile->setCompositeMapEnabled(false);
	
	Ogre::TerrainGroup* terraingroup = OGRE_NEW Ogre::TerrainGroup(scenemgr, Ogre::Terrain::ALIGN_X_Z, terrainsize, worldsize);
    terraingroup->setFilenameConvention(Ogre::String("terrain"), Ogre::String("ogt"));
    terraingroup->setOrigin(Ogre::Vector3::ZERO);
		
	Ogre::Terrain* terrain = OGRE_NEW Ogre::Terrain(scenemgr);

	// terrainsettings							
	Ogre::Terrain::ImportData& imp = terraingroup->getDefaultImportSettings();	
	imp.terrainSize = terrainsize;
	imp.worldSize = worldsize;
	imp.minBatchSize = 33;
	imp.maxBatchSize = 65;

	// use float RAW heightmap as input
	imp.inputFloat = buffer;
	
	// process texture layers
	imp.layerList.resize(layercount);
	Ogre::StringVector blendmaps(layercount);
	for(int i=0;i<layercount;i++)
	{
		// load layer info
		Ogre::String sectionStr = Ogre::StringConverter::toString(i);
		Ogre::Real layerworldsize = Ogre::StringConverter::parseReal(terrainconfig->getSetting("worldsize", sectionStr));
		
		if (i==0)
		{			
			// no blendmap at layer 0 (baselayer)
			Ogre::String specular = terrainconfig->getSetting("specular", sectionStr);
			Ogre::String normal = terrainconfig->getSetting("normal", sectionStr);

			// add layer		
			imp.layerList[i].textureNames.push_back(specular);
			imp.layerList[i].textureNames.push_back(normal);
			imp.layerList[i].worldSize = layerworldsize;			
		}
		else
		{
			Ogre::String specular = terrainconfig->getSetting("specular", sectionStr);
			Ogre::String normal = terrainconfig->getSetting("normal", sectionStr);
			Ogre::String blend = terrainconfig->getSetting("blend", sectionStr);
		
			// add layer		
			imp.layerList[i].textureNames.push_back(specular);
			imp.layerList[i].textureNames.push_back(normal);	
			imp.layerList[i].worldSize = layerworldsize;

			blendmaps[i] = blend; 
		}
	}

	// load the terrain
	terrain->prepare(imp);
	terrain->load();	
	
	// load those blendmaps into the layers
	for(int j = 1;j < terrain->getLayerCount();j++)
	{
		Ogre::TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(j);
		Ogre::Image img;
		img.load(blendmaps[j],"General");
		int blendmapsize = terrain->getLayerBlendMapSize();
		if(img.getWidth() != blendmapsize)
			img.resize(blendmapsize, blendmapsize);

		float *ptr = blendmap->getBlendPointer();
		Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data);

		for(int bp = 0;bp < blendmapsize * blendmapsize;bp++)
			ptr[bp] = static_cast<float>(data[bp]) / 255.0f;

		blendmap->dirty();
		blendmap->update();
	}

	// create filename for writing
	int pos = heightmapfile.find_last_of('.');
	if (pos < 0)	
		heightmapfile = heightmapfile + ".ogt";
	else	
		heightmapfile = heightmapfile.substr(0, pos) + ".ogt";
			
	// save as Ogre .OGT
	terrain->save(heightmapfile);	
	Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LogMessageLevel::LML_NORMAL, heightmapfile + " successfully written.");
	
	// debug viewing (exit with CTRL+C)
	camera->setPosition(-terrainsize, 7000, -terrainsize);
	camera->lookAt(terrainsize/2,0,terrainsize/2);	
	root->startRendering();

	return 0;
}