# Discussionarea flattening experiment - SUCCESS

#### fred18

Donator
Hi guys,
I'm just moving the post here in a new thread since I believe that it is worth to have a bit of highlight.

As anticipated I compiled a custom D3D9 with a simple function to flatten a circular area around a defined coordinate at a given altitude. A big help came from Face for both compiling and for the function setup.

The result is the following.

Here is the potential, of this which I find huge:

Note: I change the radius on the go (se debug string on bottom left for value) and then zoom out and in to make it reload the tile.

If this could affect also collision detection I would want it immediately....Bases, runways and pads would not be an issue anymore, it would take minutes to configure them without complicated patches to the textures and the original terrain data would always be preserved.

Please someone from up give a look at this :hail:

#### Face

Beta Tester
If this could affect also collision detection I would want it immediately....Bases, runways and pads would not be an issue anymore, it would take minutes to configure them without complicated patches to the textures and the original terrain data would always be preserved.

I'm already reverse-engineering the elevation loading functions in orbiter_ng.exe . Perhaps we can hook into it to also demonstrate the collision detection impact of the flattening algorithm.

#### jangofett287

##### Heat shield 'tester'
I imagine you have a bit of code in there similar to this:
Code:
if (distance_from_center < radius)
height = target_height
else
height = original_height
might I suggest the following:
Code:
if (distance_from_center < radius)
height = target_height
else if (distance_from_center < (radius + falloff_distance))
float fac = (distance_from_center - radius) / falloff_distance
height = original_height + (fac / (target_height - orignal_height))
else
height = original_height
That will give linear falloff. Other falloff types can be obtained by modifying the fac calculation.

#### 4throck

##### Enthusiast !
Looks good!

How about doing it based on landed vessel coordinates ?

» Have a landed vessel define a flat area radius and the desired altitude.

Also it would allow something like the Soyuz pads, where you have the trench with negative altitude. And if base objects go away on future orbiter versions it would still work.

#### fred18

Donator
I imagine you have a bit of code in there similar to this:
Code:
if (distance_from_center < radius)
height = target_height
else
height = original_height
might I suggest the following:
Code:
if (distance_from_center < radius)
height = target_height
else if (distance_from_center < (radius + falloff_distance))
float fac = (distance_from_center - radius) / falloff_distance
height = original_height + (fac / (target_height - orignal_height))
else
height = original_height
That will give linear falloff. Other falloff types can be obtained by modifying the fac calculation.

Looks good!

How about doing it based on landed vessel coordinates ?

» Have a landed vessel define a flat area radius and the desired altitude.

Also it would allow something like the Soyuz pads, where you have the trench with negative altitude. And if base objects go away on future orbiter versions it would still work.

Thanks guys, I am very happy that the idea is welcome. Anyway the full development it is not much about us (I add Face to this party, since it seems to me that he likes the idea as well and is helping a lot about it).

What we are trying to do is to demonstrate that flattening of easily defined local areas is possible, without performance impact and that produces good results.

It seems to me that this has already a confirmation from the video above.

The issue is that the example is just about "graphics" since we are playing with the code of D3D9, so the collision detection system of Orbiter Core actually uses the original terrain instead of the flattened one. That means that it can be basically just a demonstration of the potential and of the absence of performance impact.

I think that what Face is trying to do is to hack the collision detection directly through the binaries, but this becomes a bit of reading chinese for me so I can't be much of assistance and anyway still is just about demonstration.

If Martin (or anybody who has the idea on how to do it) would take this in consideration, I'd simply suggest to have the possibility of having flat areas defined in dedicated cfg files, and each one will state:
- planet
- center point coordinates
- type of shape (rectangle, circle, other options)
- shape factor (for rectangle to deform the square and for circle to make ellipsis)
- altitude
- optionally falloff distance and degree (for smoothing the edges if necessary)

when Martin said that base objects are going to be removed at first I thought that it was a show stop for this, but actually it could be the opposite, that it is even more needed.

as said, it would allow to have objects on ground like pads, runways, buildings etc with just a few minutes, without having to do complicated patches to the elevation files. Basically suddenly it would be possible to create inifnite number of places to land on or to take off from, with just a few parameters, and that everything will be removable, transferrable etc very very easily.

It seems to me that it would be a big addition because it would be so easy to populate planets with custom objects and "sight seeing" points and more important landing locations

---------- Post added at 18:05 ---------- Previous post was at 17:55 ----------

Actually if there would be an interface/access to the elevation data manager also to set the data and not just to get the data, it would be very easy to implement the plugin that does what said above, I would candidate to do it. The issue I see is that at the moment we just have one way access to the data, so we can get them and eventually use them but cannot set them if not via elev files.

Last edited:

#### Urwumpe

##### Not funny anymore
Donator
How is the performance impact with 20 or 100 such flattened zones? (bases or LPADS)

#### fred18

Donator
How is the performance impact with 20 or 100 such flattened zones? (bases or LPADS)

right now 0 even with 20000 of those: if the zone is not visible in detail the function is not even called... if you watch the video it took me just to zoom out a bit to make it reset.

And anyway, the principle itself does not add performance requirement: we are not adding data to process, the elevation shall be processed anyway, being the area flat or not. We are just saying that in defined areas instead of querying the planet elevation, the system can use a constant value. it seems to me that it is a performance increaser.

---------- Post added at 18:37 ---------- Previous post was at 18:21 ----------

Let me also add that the performance is mainly due to graphics, since the rest can be handled very easily by the actual computing power. And the graphics here has 2 advantages:
1) is called just when you see it, so 1 or 1000 flat areas is not important since it would not cause any issue
2) I'm not a D3D9 developer, but it seems to me that a flat area is faster than a mesh with some hundreds vertices to render. If you increase the size of the flat area to planet size you'll get a flat planet which I believe is much faster to be rendered instead of a complex surface, so I really do not see why there is so much concern for this.

let see this on another point of view: if you patch the planet texture to have 10 flat areas for the pads wouldn't that be the same performance wise? I think so. I am not adding anything, I just choose to use a constant value instead of the elevation file one.

#### Urwumpe

##### Not funny anymore
Donator
But increasing the height resolution temporarily would not be possible that way? :hmm:

e.g. Describe the LC-39 base pad structure as terrain. Or have smoother runways despite being not flat, but inclined.

#### Face

Beta Tester
I think that what Face is trying to do is to hack the collision detection directly through the binaries

Well, "hack" is a bit too much. I've analyzed the Orbiter binary to narrow down the point where elevation information is loaded and used for collision detection.

I think it is at 0x4185fc, which has 8 bytes reloading a lat/lng "query" set to determine the collision plane of the tile at the given coordinates. So far, I think at that point the stack pointer offset 0x2c is giving the "ilat" and 0x54 the "ilng" indices. The appropriate level is stored in the extended source index register, and the 259x259 height data is stored in the extended destination index pointer.

I guess if I can make a trampoline there to call a static filter function, we could make a complete demonstration of the flattening system.

Last edited:

#### fred18

Donator
But increasing the height resolution temporarily would not be possible that way? :hmm:

e.g. Describe the LC-39 base pad structure as terrain. Or have smoother runways despite being not flat, but inclined.

I think that at the moment it would not be possible, martin said:

Regarding terrain flattening, a few things to consider:

* currently, the vertical elevation resolution is quite low (1 meter in 2016, potentially finer in the beta, but only globally, and only if the total global elevation range can be encoded in 16bits).

This means that smooth gradients can't be implemented yet and always come out as a staircase effect, in particular for the high (horizontal) resolution tiles. This means that terrain flattening at the moment always means constant elevation (0-th order flattening, if you like)

In the future I want to implement support for local variations for the vertical resolution that would allow much finer elevation steps locally. This should allow to implement smooth gradients, and thus 1-st order flattening. I can't promise when and how this will happen, but maybe something to keep in mind for elevation flattening tools being developed.

Anyway for a "base case" it would not be needed IMO. if someone is willing to go that deep he can always patch the elevation files. All I'm asking is a simple system to flatten small portions of terrains so I can put down a base with a runway rapidly and also import bases from 2010 to have fun around. Maybe build something on mars or moon etc. Then if one day I will want to build a super detailed Lukla airport I would just sit down and patch the elevation files. That's my idea, I could be wrong of course but it seems to me that it would be a big step towards a much "friendlier" system.

---------- Post added at 21:21 ---------- Previous post was at 21:19 ----------

Well, "hack" is a bit too much.

yep sorry, that wasn't proper.

I guess if I can make a trampoline there to call a static filter function, we could make a complete demonstration of the flattening system.

that would be super! if that works and it will not be implemented at higher level I will keep it for my usage :lol:

#### kuddel

##### Donator
Donator
I guess if I can make a trampoline there to call a static filter function, we could make a complete demonstration of the flattening system.
Couldn't we just ask martin to provide a "do-not-use-in-production" callback for that in the beta?
The GC[*] could provide that callback for the time this feature is evaluated.
Once this has been proven to be working it cold be removed (or just not be called ever again...)

[*] Basic (template) could be supposed in the orbitervis reference implementation (D3D7Client repository: svn://svn.code.sf.net/p/orbitervis/code/D3D7Client)

#### Face

Beta Tester
Couldn't we just ask martin to provide a "do-not-use-in-production" callback for that in the beta?
The GC[*] could provide that callback for the time this feature is evaluated.
Once this has been proven to be working it cold be removed (or just not be called ever again...)

Yes, this could be a second step, and of course having a callback is the preferred way of implementation.

However, it would only work with the beta, and then the demonstration is not easily experienced by others. They would have to have everything in place for the beta, while here they just need the slightly modded D3D9Client.

In addition, I wouldn't want to put pressure on Martin to add a callback just for an experiment. Especially not as long as I don't know to a sufficient degree that it would even work that way.

#### fred18

Donator
In addition, I wouldn't want to put pressure on Martin to add a callback just for an experiment. Especially not as long as I don't know to a sufficient degree that it would even work that way.

I think the point is to demonstrate that it could work well, so well that we go to him with the hat in our hand asking if he can please add that function to the core.

one question: was what I said above correct? would it be sufficient to have a oapiSetSurfaceElevation(OBJHANDLE hPlanet, double lng, double lat, double Elevation) as counterpart of oapiSurfaceElevation function to make this work?

#### Face

Beta Tester
one question: was what I said above correct? would it be sufficient to have a oapiSetSurfaceElevation(OBJHANDLE hPlanet, double lng, double lat, double Elevation) as counterpart of oapiSurfaceElevation function to make this work?

Sorry, missed that part in your posts somehow.

No, I think it should work similar to the current visual filtering, i.e. getting the tile data before usage, then manipulate it.

On that note, my current skeleton callback is like so:
Code:
void FilterElevation(OBJHANDLE hPlanet, int lvl, int ilat, int ilng, INT16 *elev);

Within it, you just do the same that you do at our experiment point in the D3D9Client (provided you use the same that I had posted in the dev thread before). This way, you have only one algorithm for both sides: visual and collision detection.

The oapiSurfaceElevation() function actually uses some internal function I've called "GetSurfacePlane" - that takes a boatload of arguments - with many arguments nulled in order to just get the height value at the given lat/lng point. But this internal function does the whole loading dance with calling something like "GetElevation" and "GetElevMod" to load data from disk. If there is none (or the "Archive only" flag is set), it apparently memcpys from a buffer (presumably the preloaded archive). The point I've described previously is within that "GetSurfacePlane" function, after the elevation data was gathered, but before it is used to calculate the plane.
There I'll put in the trampoline and call the filter function described above.

An oapiSetSurfaceElevation() that works as counterpart to oapiSurfaceElevation() would only set the elevation at one specific point, not on a complete plane defined by e.g. a circle.

#### jarmonik

Beta Tester
I think the point is to demonstrate that it could work well, so well that we go to him with the hat in our hand asking if he can please add that function to the core.

I think that the consept is already demonstrated well enough and I am pretty conffident that it works, looks good on a paper and how many applications have already done this ? Right now it looks like there might be just enough forward momentum that Martin might actually implement this. Unless he already has. :thumbup:

Right now the operation of surface collision relies that these two models one in the Orbiter and the other in the D3D9 are in a perfect sync, otherwise the collision would not happen at the level of visible surface.

Are we happy with a mere circular flattening of terrain around a surface bases, where the flattening could be defined in a base configuration file, if the base requires a flattening. This would not require any callbacks or functions other than passing flattening info (EDIT: From Orbiter to Client) and predefined flattening function on both sides. Not a good approach but easiest one.

Or would we need more genaral purpose approach to deal with more complex cases like micro elevation ? It could look nice on screen but I don't think that the community would require more complexity right now. If done, there are multiple options available and it's hard to say which one would be the one to go with.

Last edited:

#### fred18

Donator
Are we happy with a mere circular flattening of terrain around a surface bases, where the flattening could be defined in a base configuration file, if the base requires a flattening. This would not require any callbacks or functions other than flattening info and predefined flattening function on both sides. Not a good approach but easiest one.

Or would we need more genaral purpose approach to deal with more complex cases like micro elevation ? It could look nice on screen but I don't think that the community would require more complexity right now. If done, there are multiple options available and it's hard to say which one would be the one to go with.

I don't know if I would add that info to bases cfg anymore if bases files are going to disappear in the future. Maybe I'd add separate cfg for flat areas. There could also be a "transition phase" where those info works both if inserted in bases files and if they simply define flat areas. Maybe that would be the best approach.

I agree that no more complexity is required. I strongly support a very simple approach which defines a basic shape (circle or rectangle) which is simply flat and that's it. That would be enought to support an easy way for base creations. The rest like microelevation and everything can be left to future implementations.

#### 4throck

##### Enthusiast !
I suggest flattening by landed objects, defined by scenario.

Example:

STATUS Landed Earth
POS -120.6102030 34.6324760
ALT 5
AROT -115.819 25.717 -152.249
...
FLATTENING 120 5
END

#### fred18

Donator
I suggest flattening by landed objects, defined by scenario.

Example:

STATUS Landed Earth
POS -120.6102030 34.6324760
ALT 5
AROT -115.819 25.717 -152.249
...
FLATTENING 120 5
END

Sorry but i strongly disagree.

Vessels are supposed to fly, not to be ghost on ground just to get their coordinates. If an oapi function comes out from this then anybody can code a special vessel that does what you ask, but i think that that kind of trick should not be part of the core.

What if you have 100 bases on earth, 50 on moon and 50 on mars? Each scenario should add 200 vessels? That is definitely not what i call friendly and what i had in mind for this.
If the problem is add cfg file for flattening you can just patch elev files...

#### GLS

Forgive me for "throwing a spanner in the works", but how does this handle "flattening in a plane" vs "flattening following the curvature of the planet"?