Discussion area flattening experiment - SUCCESS

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,668
Reaction score
796
Points
128
It seems like Orbiter internally also uses INT16 arrays for the raw elevation data it operates on. This is also the case for the OVP code, so I guess it is best used in both cases with that signature.


Yeah the raw data is in INT16 format but it gets converted to a float at some point later on. When I was working on the surface micro-texturing I got an idea of micro-elevation. The interface function you presented could almost do the trick. The data would need to be returned as floats due to detail requirements. Also, instead of returning 'void' it should return 'int' the maximum level of detail that is available for Orbiter to acquire. Nice idea but might be too much 'forward' looking, I'm afraid.

An other option, more consistent with current implementation, is to let the Orbiter todo the flattening. For an example, Orbiter is already manipulating the data in ElevationGrid() function, so, why not flatten it too for a better consistency. (not in ElevationGrid() of course). Orbiter would need to do the flattening for the inline engine without help from D3D9 anyway.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,734
Reaction score
2,702
Points
203
Location
Dallas, TX
So what do we do, we just hope that martin find the time and the patience to read this or shall we highlight, recapi and forward this to him in any manner? just to know how to do it properly, without making him lose time, or anything he doesn't like.
I would show that it can be done. And if users want it. Then pass on to Martin.
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,403
Reaction score
581
Points
153
Location
Vienna
Yeah the raw data is in INT16 format but it gets converted to a float at some point later on. When I was working on the surface micro-texturing I got an idea of micro-elevation. The interface function you presented could almost do the trick. The data would need to be returned as floats due to detail requirements. Also, instead of returning 'void' it should return 'int' the maximum level of detail that is available for Orbiter to acquire. Nice idea but might be too much 'forward' looking, I'm afraid.

An other option, more consistent with current implementation, is to let the Orbiter todo the flattening. For an example, Orbiter is already manipulating the data in ElevationGrid() function, so, why not flatten it too for a better consistency. (not in ElevationGrid() of course). Orbiter would need to do the flattening for the inline engine without help from D3D9 anyway.

My comment was merely in the context of the current experiment. Here the INT16 comes naturally due to the already defined data-structures within Orbiter's core.

IMHO, there shouldn't be any API at all in the end. Just a definition format that Orbiter reads and uses accordingly. Perhaps the current duality between core reading of the elevation data for OVP collision detection and OVP graphics rendering is sub-optimal. I guess it would be better if Orbiter holds the tile information in whatever detail is necessary (there your floating point proposal would fit), then transfers it to the OVP client for rendering. As it is now, the client has to do the same work as the engine in parallel.
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
I'm monitoring this thread, but I am unlikely to find time to do much on this for a few weeks.

Just to be clear: the idea here is to flatten the terrain on the fly at runtime, rather than an offline tool that performs the flattening by modifying the elevation tiles, correct? And the flattening effect is simply a circular area of given radius around a given centre position, and possibly smoothing out the resulting sharp edges?

What if users at some time decide that a circular area is not sufficient, and they want a more complex shape to include an oddly shaped base layout, or dig out a blast tunnel, or excavate a river bed through the base? Supporting complex shapes in real time might have a performance impact, so for these cases, manual editing of the elevation tiles might be preferable.

What happens if two flattened areas with different elevations overlap? Should there be a defined order in which the requests are applied?

If I do get to implement finer elevation resolution, should this be reflected in the functionality of the flattening function (e.g. allow linear slopes, or defining a spline surface), or is flat and horizontal all that is required? If you take Mojave spaceport for example, which is located on an inclined slope, flattening will always dig into the hillside on one end, and raise the terrain onto a platform on the other. Making this look natural would require some extensive earthworks. That is, the levelled terrain would have to drag the surrounding area with it over a larger distance. Doing that in real time could be a challenge.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,734
Reaction score
2,702
Points
203
Location
Dallas, TX
So it sounds like flatten can be done already, right?

Maybe a how to flatten would be good. I thought this was mentioned before
 

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,667
Reaction score
104
Points
78
Since I had the first move on this (but thanks to the capabilities of Face it is even possible to test this) I'll take the responsability and the pleasure to answer with my view. It can be right or wrong of course, but this is how I saw this possible feature:

Just to be clear: the idea here is to flatten the terrain on the fly at runtime, rather than an offline tool that performs the flattening by modifying the elevation tiles, correct?

precisely this.

And the flattening effect is simply a circular area of given radius around a given centre position, and possibly smoothing out the resulting sharp edges?

the circle was the easiest to code for testing, if I could choose a shape I'd choose a rectangle defined by 2 or 4 couples of longitude-latitude coordinates (2 are enough for grid aligned rectangles, 4 would allow for any rotation).

What if users at some time decide that a circular area is not sufficient, and they want a more complex shape to include an oddly shaped base layout, or dig out a blast tunnel, or excavate a river bed through the base? Supporting complex shapes in real time might have a performance impact, so for these cases, manual editing of the elevation tiles might be preferable.

see above relevant to rectangle. If complexity is down to a small level a combination of rectangles can do the job. if it gets too much the user will always have the option to modify the tiles as you just correctly pointed out.

What happens if two flattened areas with different elevations overlap? Should there be a defined order in which the requests are applied?

I'd say it will be users responsability not to make overlaps, so it would be either undefined behaviour or simply (if possible of course) the last call for that area wins

If I do get to implement finer elevation resolution, should this be reflected in the functionality of the flattening function (e.g. allow linear slopes, or defining a spline surface), or is flat and horizontal all that is required? If you take Mojave spaceport for example, which is located on an inclined slope, flattening will always dig into the hillside on one end, and raise the terrain onto a platform on the other. Making this look natural would require some extensive earthworks. That is, the levelled terrain would have to drag the surrounding area with it over a larger distance. Doing that in real time could be a challenge.

I'd say that this function is 99% about bases creation and it is an option to allow for that in order to save from tiles patching. If users want to have a sloped runway or a particular requirement, tiles patching would anyway be always available. otherwise they can use the option for flattening and enjoy it as it is. maybe the users will decide that for a situation like that they want to make flat a big area so there is no feeling in sight of the uneven terrain. Or maybe they will try to put some rectangles next to each other with small height difference to see if that works. Experimenting would be on the users IMHO, I would just give the option to have a flat leveled terrain and for those who are willing to make complex shapes or different situations the tile patching would always be available.

That's my vision for this.

Thank you very much for your time :tiphat:
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,403
Reaction score
581
Points
153
Location
Vienna
And OBJHANDLE detection is finished as well: https://bitbucket.org/face/ovp/commits/55ac936e81325d2f8ba19def7c7393d6c96bcb98

So with this I will start to implement the following concept:
* On vPlanet creation, load all *.flt files in the folder /Textures/<planet>/Flat - these files can be distributed by developers for each addon.
* In every file, one or more of the following line entries is parsed:
Code:
ELLIPSE <height> <lat> <lng> <major> <minor> <phi> <falloff>
or
RECT <height> <lat> <lng> <width> <length> <phi> <falloff>
* Ellipse is with midpoint <lat>/<lng>, <major> axis radius in meter, <minor> axis radius in meter, <phi> rotation 0-90° tilted major axis, flattened to <height> in meter with <falloff> percent (of full radius seen from edge of shape) gradual transparency merging with actual height. Only the first 4 parameters are necessary, <minor> defaults to <major>, the rest to zero.
* Rectangle is with midpoint <lat>/<lng>, <width> and <length> tilted with <phi> 0-90°, flattened to <height> in meter with <falloff> percent (of full radius seen from edge of shape) gradual transparency merging with actual height. Only the first 4 parameters are necessary, <length> defaults to <width>, the rest to zero.
* Shapes are loaded in order of file and line position, last shapes overriding first.
* Shapes are preprocessed into a cascaded map, creating a GBody->level->ilat->ilng database. Whenever a shape touches a given path (so it has multiple paths due to higher levels), it is within that tile and will be taken into account. If a shape's tile contribution is below pixel size, it will not land in the path.
* The filter function will check the database, then do the drawing algorithm for all shapes in the path's list.

Let's see how that works out.
 
Last edited:

kuddel

Donator
Donator
Joined
Apr 1, 2008
Messages
2,064
Reaction score
508
Points
113
@Face: Would the <height> be "radius" or "height above mean sphere" / MSL?
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,403
Reaction score
581
Points
153
Location
Vienna
@Face: Would the <height> be "radius" or "height above mean sphere" / MSL?

Good question. It will be whatever the INT16 value represents, so I guess mean sphere.
 

Donamy

Addon Developer
Addon Developer
Donator
Beta Tester
Joined
Oct 16, 2007
Messages
6,919
Reaction score
219
Points
138
Location
Cape
...And people think Orbiter is dead. :nono:
 

4throck

Enthusiast !
Joined
Jun 19, 2008
Messages
3,502
Reaction score
1,008
Points
153
Location
Lisbon
Website
orbiterspaceport.blogspot.com
ELLIPSE and RECT seem simple enough for me :thumbup:
Easy to use and good for runways, pads and taxiways.

Also easy to get coordinates off Google Maps, perhaps even converting from KML might be possible.

So thank you Face (and others) for looking into this.:tiphat:
 
Last edited:

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,403
Reaction score
581
Points
153
Location
Vienna
Is it working or just talk of how it would work?

Both the visual and collision detection manipulation is working, see my posted link for a working D3D9Client with demonstration flattening at Cape Canaveral.

The discussion about file format is just talk as of yet, but the ground works have been done.
 

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,667
Reaction score
104
Points
78
Both the visual and collision detection manipulation is working, see my posted link for a working D3D9Client with demonstration flattening at Cape Canaveral.

The discussion about file format is just talk as of yet, but the ground works have been done.

There is one thing is not 100% clear to me about the actual implementation and the eventual final solution.

My understanding is that at the moment you made a "trampoline" to hook into the binary of orbiter_ng.exe so you manage to modify the collision detection function making it loading the values of the elevations loaded by D3D9, is that right?

So what surprises me a bit is about the general system that orbiter uses: the data are loaded and processed twice: one for collision detection and one for graphic representation. Before we stepped into this I always thought that the data were processed just once inside orbiter core and then the client queries the core for making the graphical representation.

So, since it seems that martin is interested in making this a part of final release (so I guess it will be included in the Beta some day?) then D3D9 should be updated in the same way? It does not just query the core for the data and that's it, is that right?
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,403
Reaction score
581
Points
153
Location
Vienna
My understanding is that at the moment you made a "trampoline" to hook into the binary of orbiter_ng.exe so you manage to modify the collision detection function making it loading the values of the elevations loaded by D3D9, is that right?

Close. The trampoline hooks into the exact point where Orbiter_ng loaded the elevation data (and pre-processed it) for collision detection, then calls the FilterElevation function with the tile information. The FilterElevation function can then patch the height array or not. It has to decide if a given shape is on the tile, then "paint" the shape over it.

It is not feeding the elevation values loaded by D3D9 into the collision detection system, it reacts to on-going tile-loading (or pre-processing) operations of the core. In other words: it is passive filtering vs. active overloading.

So what surprises me a bit is about the general system that orbiter uses: the data are loaded and processed twice: one for collision detection and one for graphic representation. Before we stepped into this I always thought that the data were processed just once inside orbiter core and then the client queries the core for making the graphical representation.

So, since it seems that martin is interested in making this a part of final release (so I guess it will be included in the Beta some day?) then D3D9 should be updated in the same way? It does not just query the core for the data and that's it, is that right?

This is my understanding as well. Orbiter_ng.exe loads the elevation data in order to process it for collision detection, and the OVP client (in this case: D3D9Client) also has to load it in order to process it for visual rendering. The code sure is written that way.

If a given OVP client is not interpreting the elevation data the same way the core does, you'll get collision/visual dissonance. This is less elegant IMHO.

BTW: I've implemented the shape drawing function, complete with factor, angle, falloff and "rectangle" support (actually I use the ellipse function with higher orders to simulate a rectangle with slightly rounded corners): https://bitbucket.org/face/ovp/commits/6cd1d01e1fc4574874bd2df14360187d109cb8b2

Next stop: file parsing.
 

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,667
Reaction score
104
Points
78
BTW: I've implemented the shape drawing function, complete with factor, angle, falloff and "rectangle" support (actually I use the ellipse function with higher orders to simulate a rectangle with slightly rounded corners): https://bitbucket.org/face/ovp/commits/6cd1d01e1fc4574874bd2df14360187d109cb8b2

Next stop: file parsing.

May I be of assistance? the trampoline and the relevant hook were surely out of my knowledge, but the rest I am pretty confident I can be helpful with. If you need/want, just let me know

---------- Post added at 17:30 ---------- Previous post was at 17:24 ----------

PS: A curiosity-> I made a test with Cape Canaveral. Of course it works amazingly. What was curious is that I tried to jump from the cliff with the DG, running at full speed on its gear towards the platform edge, but when I got there the vessel tried to follow the terrain under the cliff and did not jump but tried to go down like on a rollercoaster. :lol:
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,403
Reaction score
581
Points
153
Location
Vienna
May I be of assistance? the trampoline and the relevant hook were surely out of my knowledge, but the rest I am pretty confident I can be helpful with. If you need/want, just let me know

Be my guest. The code is there at Bitbucket.

As of now, the FilterElevation function uses the static example for Canaveral, but already puts the relevant shape declaration into a fake vector (which should come out of the cascading unordered map). There is some commented code at the top of FilterElevation that shows how it goes through the map to find the shape definitions for the tile at hand.

My approach would be to get that map filled by the vPlanet class by means of iterating over the appropriate /Texture/<planet>/Flat folder to find *.flt files, then load them, parse them for definitions and create FlatShape objects on the heap. Perhaps first into a vector, then after the complete planet finished, copy them to array for stable pointers and create the map out of it.

The map creation should be so that the tentative tile coverage should be generated, i.e. which tile at which level is touched by the shape. I'd do so by means of calculating lat/lng of the corner points of the shape (this could be a simple worst case guess like e.g. using hypotenuse of the 2 shape dimensions for square coverage). Then follow all corner points up to sub-pixel level of the shape size. At each level, for all tiles between the corner points, generate the map path for the shape.

We should be able to get away with this sloppiness, because the brute-force shape drawing will take care of the finer details. Worst case is that we iterate over all tile pixels for nothing. Still it should sufficiently rule out no-matches pretty fast. This way, even big shape-lists all over a planet will not hamper tile-loading too much.

The shape object holds pre-processed values. E.g. the dimensions are converted to lat/lng via a decimal degrees guess, <phi> is converted to appropriate sin/cos values, falloff is in double fracture (not percent), type is 1 for ellipse, 4 for "rectangle".

---------- Post added at 18:49 ---------- Previous post was at 18:45 ----------

PS: A curiosity-> I made a test with Cape Canaveral. Of course it works amazingly. What was curious is that I tried to jump from the cliff with the DG, running at full speed on its gear towards the platform edge, but when I got there the vessel tried to follow the terrain under the cliff and did not jump but tried to go down like on a rollercoaster. :lol:

Observed that, too! Two idiots, one thought... off the cliff! Yuppeeeeeh :rofl:

I guess it has something to do with the algorithm that calculates collision plane according to elevation data. If it is something with bsplines, it could well overshoot by the sudden elevation jump between two data-points.

---------- Post added at 19:25 ---------- Previous post was at 18:49 ----------

Hmm. Perhaps it is not a good idea to do it in the vPlanet class. AFAIK, those objects are created for visuals only, and could be destroyed if they go out of visibility. I think it is best to stick to the client class itself, then.
 

Donamy

Addon Developer
Addon Developer
Donator
Beta Tester
Joined
Oct 16, 2007
Messages
6,919
Reaction score
219
Points
138
Location
Cape
I assume this could be adapted for the moon, as well. I would love to make a crater base.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,734
Reaction score
2,702
Points
203
Location
Dallas, TX
I think it can be adaptable for any planet. I am not sure how to test it?
I guess for finding lat and Long we just land a vessel there and get the values? MAybe even like a Bulldozer mesh:)
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,403
Reaction score
581
Points
153
Location
Vienna
I assume this could be adapted for the moon, as well. I would love to make a crater base.

It works on any planet with new texture mode.
 
Top