void TerrainManager::EditLayerTerrain(Ogre::Terrain *terrain, const Ogre::Vector3 ¢erPos, 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); } } }