Beispiel #1
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 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);
		}
	}
}