Problems trying to paint dynamically


27-01-2008 18:13:25

I have integrated ETM (awesome add-on, by the way!) to our game framework and use it to load our map. It works great. I have 6 textures (512) onto 2 coverage maps (128), one lightmap (128), and one height map (513) that extends to 4096x853x4096.
I am currently making a map editor for our project. Now, editing the height works fine, with multiple brushes and everything. I am having problems painting on it with the splatting manager. I really can't figure out what I'm doing wrong, as I followed the sample very closely. It just doesn't paint anything :(
Here's some pieces of my map editor, which I hope, will make the problem pop out :)

gpTerrainManager = new ET::TerrainManager( gpSceneManager );
gpTerrainManager->setLODErrorMargin( 2, aiHeight );
gpTerrainManager->setUseLODMorphing( true, 0.25, "morphFactor" );
gpSplatManager = new ET::SplattingManager( "ETSplatting", "General", 128, 128, 3 );
gpSplatManager->setNumTextures( 6 );

Map loading

Ogre::Image image;
image.load( Ogre::String( "Level" ) + aszLevelNumber + "_HM.png", "General");
ET::TerrainInfo info;
ET::loadHeightmapFromImage(info, image);
info.setExtents(Ogre::AxisAlignedBox(0, 0, 0, MAP_SIZE, MAP_HEIGHT, MAP_SIZE));
gpTerrainInfo = & gpTerrainManager->getTerrainInfo();
image.load(Ogre::String( "Level" ) + aszLevelNumber + "_C1.png", "General");
gpSplatManager->loadMapFromImage(0, image);
image.load(Ogre::String( "Level" ) + aszLevelNumber + "_C2.png", "General");
gpSplatManager->loadMapFromImage(1, image);
Ogre::MaterialPtr material (Ogre::MaterialManager::getSingleton().getByName(Ogre::String( "Level" ) + aszLevelNumber));
Ogre::TexturePtr lightmapTex = Ogre::TextureManager::getSingleton().createManual("ETLightmap", "General", Ogre::TEX_TYPE_2D, 128, 128, 1, Ogre::PF_BYTE_RGB);
image.load( Ogre::String( "Level" ) + aszLevelNumber + "_LM.png", "General");
lightmapTex->getBuffer(0, 0)->blitFromMemory(image.getPixelBox(0, 0));

Painting the terrain

Ogre::Ray oRay = camDefault.GetOgreCamera()->getCameraToViewportRay( (float)gpMouse->getMouseState().X.abs / (float)gpMouse->getMouseState().width, (float)gpMouse->getMouseState().Y.abs / (float)gpMouse->getMouseState().height );
std::pair<bool, Ogre::Vector3> oResult = gpTerrainInfo->rayIntersects( oRay );
int iX = gpTerrainInfo->posToVertexX( oResult.second.x );
int iZ = gpTerrainInfo->posToVertexZ( oResult.second.z );
stBrush oBrush = mapBrushes[(CEGUI::ListboxTextItem*)gpCurrentBrush];
gpSplatManager->paint( guiCurrentTexture, iX, iZ, oBrush.oBrush, 10.0f * GetDeltaTime() * ( gpBrushIntensity->getScrollPosition() - 1.0f ) );

Thanks to anyone who tries to help me out on this one!


27-01-2008 23:11:15

The problem is that your coverage maps are of smaller size than your terrain. The posToVertex commands, however, will give you vertex positions, i. e. a position in the range [0, 512]. Quite obviously, you need to map that to your coverage maps' size [0, 127]. You'll need to subtract one and divide by 4 :)


28-01-2008 01:59:11

Thanks a lot! Worked like a charm!
This was really tourmenting me XD Our map designer will be happy now!

Again, congrats on a sweet lib ;)


29-01-2008 12:11:55

Thanks a lot! Worked like a charm!
This was really tourmenting me XD Our map designer will be happy now!

Again, congrats on a sweet lib ;)

Unless the size mismatches were strongly intended I'd recommend making your coveragemaps and lightmaps larger so that they match the size of your heightmap. That way you have greater resolution of splatting coverage and lightmap..ness.

Heh, IMO the obvious answer is "Some of your maps are too small, make them bigger so they all match."

Mapping the smaller coveragemaps and lightmap onto the larger heightmap is a strange solution!

Of course, if there was a strong reason you really MEANT to have them smaller it's the right solution but I'm guessing the mistake is not changing the sizes after copy/paste from the example rather than forgetting to map the images to the larger subdomain.


29-01-2008 12:23:01

Nope, not due to copy-paste.

What I did is create heightmaps until I find a size which will fit our game, basically 512 had the right feel.
Then, I tried coverage maps, and at 128 I had enough resolution for what we needed. So, why go larger and possibly impact performance (especially on weaker machines), when I attained the visual effect needed with something lighter?