Gradual Terrain Smoothing from a Flat Area (at Runtime)

Hi, I apologise in advanced if the solution to my problem is logic-based rather than code. I’ve been staring at this for some time now, and may be missing something obvious.

I’m working on a game that has a structure placing element, but I’m struggling with the terrain modification. Basically I want to flatten the terrain directly under the structure being placed, but then gradually smooth out the surrounding terrain so I don’t end up with a square platform of terrain sticking out of the ground.

I have the relevant height data in an array called “heights”, and subject it to the following code;

		for (int x = 0; x < size; x++) {

			for (int y =  0; y < size; y++) {

				if ( [various checks to see if current coords are in the area to be flattened] ) {

					heights[x, y] = coord.y;

				} else {

					if (heights[x, y] > coord.y) {

						heights[x, y] -= (heights[x, y] - coord.y) / 2;

					} else {

						heights[x, y] += (coord.y - heights[x, y]) / 2;

					}

				}

			}

		}

If I’m understanding things right, that code should just set any height points within the area to be flattened to coord.y (which it does just fine), and then take the rest of the height points and half the difference between where they are now and the flattened area. The result I get is a little inconsistent, but most commonly modifies the terrain with a flattened square under the object being placed, surrounded by another flattened square around it.

If anyone has any useful links, know of any relevant functions, or can tell from this post what I’m doing wrong, it would be greatly appreciated.

I figured it out, eventually. There’s probably a much cleaner way of doing this but as no one seems to have any other ideas, here’s what I got;

		for (int x = 0; x < size + (smoothZone * 2); x++) {

			for (int y =  0; y < size + (smoothZone * 2); y++) {

				if (x >= smoothZone && y >= smoothZone && x <= (size + smoothZone) && y <= (size + smoothZone)) {

					heights[x, y] = coord.y;

				} else {

					float smoothPercent = new float();

					if (x < smoothZone && x <= y && x <= smoothZone - (y - (smoothZone + size))) {

							smoothPercent = (float) x / (float) smoothZone;

					} else if (x > (smoothZone + size) && x >= y && x >= smoothZone - (y -(smoothZone + size))) {
						
						smoothPercent = 1 - ((float) (x - smoothZone - size) / (float) smoothZone);

					} else if (y < smoothZone && y < x && y <= smoothZone - (x - (smoothZone + size))) {
						
						smoothPercent = ((float) x / (float) smoothZone);
						
					} else if (y > (smoothZone + size) && y > x && y > smoothZone - (x -(smoothZone + size))) {

						smoothPercent = 1 - ((float) (y - smoothZone - size) / (float) smoothZone);

					}

					if (heights[x, y] > coord.y) {

						heights[x, y] -= ((heights[x, y] - coord.y) * smoothPercent);

					} else {

						heights[x, y] += ((coord.y - heights[x, t]) * smoothPercent);

					}

				}

			}

		}

All of which basically works out the a decimal percentage (eg 0.5 = 50%) of the coord (when it’s outside of the flattened area), which then becomes a kind of terrain modification opacity.

So, if the flattened area is 0.01f higher than the current coord height, and the current coord is in the middle of the smoothing zone (50%), then only 0.005f (half) will be added to the height, whereas it would be the full 0.01f would be added if the coord was next to the flattened area, and nothing would be added if it was at the outer edge of the smoothing zone.

If I run this on flat terrain (with the flattened area height artificially set to be higher than the terrain) I get square frustum, but on more natural looking terrain, I get a nice gradual smoothing all around from the flattened area to the surrounding terrain.

Thought I’d post the answer in case anyone else ran into similar problems.