Terrain Editing

Involved development of the OpenMW construction set.
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Terrain Editing

Post by unelsson »

So, the terrain texture selection -feature has it's basics done.
PR: https://github.com/OpenMW/openmw/pull/1769
Video showing what it does: https://youtu.be/D7Ya1McDwVw

These related issues (features) are still missing from the current PR.
https://gitlab.com/OpenMW/openmw/issues/3873
https://gitlab.com/OpenMW/openmw/issues/3869

Now thinking about transient change support, I've done a bit of research on how the terrain is drawn, and will post my findings also here. I'm not taking this issue yet, but maybe in the future.

At CSVRender::Cell::updateLand(), in file cell.cpp, mTerrain is used to draw stuff to CellNode, and load cell data, through component TerrainGrid (terraingrid.cpp) which uses component ChunkManager (chunkmanager.cpp) to create a grid of terrain by using component BufferCache (buffercache.cpp) which finally sets the diamond shapes for the vertices. Component ResourceManager is also involved, likely managing also other data than terrain.

Does anyone know if the openmw game engine uses Terrain::ChunkManager (openmw/components/chunkmanager.cpp) to render terrain? I get the feeling that for opencs being able to draw another "altered" terrain layer, the component level (chunkmanager, resourcemanager etc.) might require some changes, but I'd hate to burden the game engine with opencs-stuff. Overloading chunkmanager functions or making separate opencs-functions might do the job.

Another way would be to have two resourcemanagers/chunkmanagers handled by opencs (cell.cpp choosing which to use and when). Calling the new one perhaps TransientChangeResourceManager? One chunk/resourcemanger handling the actual data, another handling the temporary "altered data".
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Terrain Editing

Post by unelsson »

Editor transient change pondering again: By implementing second versions of four or some functions responsible for managing the terrain I'm able to pass alternate height data to cell building. Same method should work for any data type. This method duplicates many functions, for example TerrainGrid::buildTerrain as TerrainGrid::buildAlteredTerrain and similarly ChunkManager::createAlteredChunk and Storage::fillAlteredVertexBuffers, only to pass some floats that override values at the lowermost layer. This method touches many components that are also used by openmw, but doesn't alter any functions used by openmw. It feels kind of ugly way to do it, but technically it works. AnyOldName3 hinted about using cull callback, and somehow changing the terrain data directly, but I can't get my hands on direct terrain drawables. That would most certainly require less hacky code...

In the end storage-code can be changed something like:
void Storage::fillAlteredVertexBuffers (int lodLevel, float size, const osg::Vec2f& center,
osg::ref_ptr<osg::Vec3Array> positions,
osg::ref_ptr<osg::Vec3Array> normals,
osg::ref_ptr<osg::Vec4Array> colours,
float alteredheightdata[])
{
...
height = alteredheightdata[col*ESM::Land::LAND_SIZE + row]; //instead of... heightData->mHeights[col*ESM::Land::LAND_SIZE + row];
...
}
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Terrain Editing

Post by unelsson »

Here is a proof-of-concept -style branch made for testing various things where stuff happens. For testing purposes, it pushes empty heights data to cell visual whenever terrain texture editing is done. While I feel the method is ugly, and there are plenty of debug comments and std::cout -lines, I'm publishing this so I can get feedback for better options for the basic implementation.
https://github.com/unelsson/openmw/tree ... nsienthack

edit: here is my second try, a less intrusive method overriding the land drawing buffer function, and slightly less crap (based on terraintextureselection branch). This line adds "+ mAlteredHeight" to the calculation, similarly all changes could be injected into this function.
https://github.com/unelsson/openmw/tree ... ntransient
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Terrain Editing

Post by unelsson »

Here is a monster of a PR (terrain selection, transient editing, land shape editing)
https://github.com/OpenMW/openmw/pull/2167

edit: This needs feedback, I'm keeping the up-to-date info on the first comment of that PR.
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Terrain Editing

Post by unelsson »

While waiting on reviews and feedback on current PR's, here are thoughts on further development... Feature.. creep...

Vertex painting
- Similar as land shape painting (four brushes: vertex, square, circle, custom).
- Brush settings window includes a color box, and pressing that opens a color choosing window https://doc.qt.io/qt-5/qcolordialog.html
- Holds history of recent colors, alike history of recent textures
- Transient editing via overriding "void TerrainStorage::fillVertexBuffers"

Land scaling
- Function in some menu (Edit? World?). Opens up a window, with origin and target, both defining a box of cellcoordinates.
- Scales land textures, shapes and vertex colors. Calculates new normals for scaled land.
- Option to choose the scaling method from nearest neighbor, bilinear interpolation, nearest + gaussian smooth, or bilinear + gaussian smooth. Nearest neighbor causes pixelation, bilinear interpolation should cause smoother heights. Gaussian smoothing works nicely with land heights, but complicates the system, could also be a separate function with it's own window and settings.

Object painting (object editing, not terrain, but used as a big scale creation tool)
- Under advanced tools editmode, or instancemode, or something...
- Choose up to (three or user-defined number) objects to paint.
- Randomly drop objects inside the given brush.
- User options to choose the density, random height difference and random rotation limits.
- Brushes similar as land shape painting (four brushes: vertex, square, circle, custom).

Landcover
- Grasses etc.. I have no idea how this could be implemented, if it even should. Just dropping this here.
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Terrain Editing

Post by unelsson »

Land scaling in my personal branch looks something like this... https://imgur.com/a/yueL6Og . In the picture I've scaled 16,17 to 17,16, with 1:1 scale, and 16,17 to a box of four cells from 17,18 to 18,19. Obviously I haven't fixed the cell edges yet, the system is working like image scaling with nearest neighbor method now.. but more importantly, it's coded to accommodate bilinear interpolation later. Still, for land heights I find nearest neigbor + gaussian smoothing quite satisfying, but you can't do a gaussian with textures. I don't know if this should be in main branch, or what's the time for that. It's currently depending on only one extra function (CSMWorld::CellCoordinates::generateId) that's not present in current master. It is present in PR of transient land shape editing.
User avatar
AnyOldName3
Posts: 2667
Joined: 26 Nov 2015, 03:25

Re: Terrain Editing

Post by AnyOldName3 »

Do you actually need to do a Gaussian filter on a texture? As modifications to a texture go, that's fairly simple.
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Terrain Editing

Post by unelsson »

AnyOldName3 wrote: 28 Feb 2019, 02:39 Do you actually need to do a Gaussian filter on a texture? As modifications to a texture go, that's fairly simple.
Suitable algorithm depends on the use case, and I'm thinking that a dropdown menu for choosing the algorithm is the best, albeit requires some user knowledge. In many cases nearest neighbor is probably sufficient, and it is likely the fastest method. However when scaling from small to big, it makes the terrain texture grid blocky and pixelated. In worldbuilding, or making big overhaul mods, scaling can be a valuable tool. You can for example, just make one cell with broad features of your landmass, then scale it up (e.g. 5x5 cells), add detail, and scale it up to final size (e.g. 30x30). Lets say you are designing a natural environment, and you want rounded, smoothened or uneven terrain texture edges. You want to get it as good as possible with automatic algorithm. With the nearest neighbor, you'd get heavily pixelated terrain map. However an estimation algorithm could be used to round the edges. Terrain texture grid can't be blended, so gaussian is unsuitable, and I wonder if even linear interpolation does any good. Likely it's better to have something related to pixel graphics scaling or scaling images with limited amount of colors. Height grid is different as values can blend, so linear interpolation, gaussian, and similar techniques can be used.
User avatar
wareya
Posts: 338
Joined: 09 May 2015, 13:07

Re: Terrain Editing

Post by wareya »

You could use most-common-neighbor filtering, breaking ties in a deterministic way. This will get rid of staircasing, like running the median filter in paint.net or gimp.
User avatar
AnyOldName3
Posts: 2667
Joined: 26 Nov 2015, 03:25

Re: Terrain Editing

Post by AnyOldName3 »

My question wasn't really whether you needed to gaussian blur a texture, but instead whether you needed to gaussian blur a texture, as in a 2D buffer in GPU memory.
Post Reply