Jump to content
Leopard20

Finding the water depth

Recommended Posts

Hello everyone.

Does anyone know a reliable way for getting the water depth measured from the water surface at a given position? The only command I know is:
 

selectBestPlaces [position player, 1, "waterDepth", 1, 1];

Which is a bit slow for my use (around 0.035 ms, IIRC) and not 100% reliable (sometimes it returns empty even on water)

Note that the water may be "inland" (not sea water) so the general conception:

_waterDepth = -(getTerrainHeightASL _somePos);

is wrong.

Share this post


Link to post
Share on other sites
TAG_fnc_returnDepth = {
	params ["_pos"];
	
	_pos = [_pos select 0,_pos select 1,0];
	_inter = lineIntersectsSurfaces [_pos, _pos vectorAdd [0,0,-4999]];
	if (_inter isEqualTo []) exitWith {systemchat "depth error";0};
	_depth =((((_inter) select 0) select 0) select 2);


_depth
};
_waterDepth = [position myDiver] call TAG_fnc_returnDepth;

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

There's a hardcoded limit for lineIntersectsSurfaces so it won't work beyond 5000m bu that should never happen. Also returns wrong results when there's an object between surface and ocean floor, I haven't bothered fixing it yet, works fine otherwise.

Share this post


Link to post
Share on other sites
2 hours ago, Mr H. said:

There's a hardcoded limit for lineIntersectsSurfaces so it won't work beyond 5000m bu that should never happen. Also returns wrong results when there's an object between surface and ocean floor, I haven't bothered fixing it yet, works fine otherwise.

Thanks. I already know this command. But I don't see how this returns the water depth if you don't even know the water level (where the free surface is)

 

Basically, I want to know how deep below the surface a unit is swimming (not how much farther to the bottom). If I know the depth, the swimming depth becomes:

getTerrainHeightASL _pos + _waterDepth - ((getPosASL _unit) select 2)

 

Edit: Oh, sorry. I forgot to mention that I needed the depth from the water surface. 😬

Share this post


Link to post
Share on other sites

((getPosASL _unit) select 2) will return you the depth then.
If you want a positive value just add abs:
abs ((getPosASL _unit) select 2)

Share this post


Link to post
Share on other sites
On 9/3/2019 at 11:26 PM, Mr H. said:

((getPosASL _unit) select 2) will return you the depth then.
If you want a positive value just add abs:
abs ((getPosASL _unit) select 2)

Again, I need the depth from the surface. What you say is only true about open water (sea). Rivers and small bodies of water may have a positive ASL value.

Share this post


Link to post
Share on other sites

I don't think that's possible in arma, AFAIK all water bodies have to be at sea level (don't quote me on that there might be modders that have done otherwise).

Share this post


Link to post
Share on other sites
3 minutes ago, Mr H. said:

I don't think that's possible in arma, AFAIK all water bodies have to be at sea level (don't quote me on that there might be modders that have done otherwise).

I've already seen such surfaces (e.g. the river in Diyala) That's why I'm asking.

Share this post


Link to post
Share on other sites
6 minutes ago, Mr H. said:

The river on diyala is at sea level! The following seems to confirm what I said.

 

No I tested it today! When I was swimming in it my ASL height was positive (so was the terrain height)

 

It may have happened at a specific grid though. I'll post the grid if you want.

Share this post


Link to post
Share on other sites

It is indeed, I was just checking just now

 

Share this post


Link to post
Share on other sites

Seems to me there's no solution for your problem I've tried on Diyalah with https://community.bistudio.com/wiki/getPosASLW
 

the values returned are slightly better (-1 swimming at the surface). But do not seem exact. If you want an "universal solution" then getPosASL select 2 should work on MOST maps, if you want a specific solution for diyala, maybe get an estimate of the ASL pos of the river surface and substract from that.

  • Thanks 1

Share this post


Link to post
Share on other sites

@Mr H.
I just ran my original command:

selectBestPlaces [position player, 1, "waterDepth", 1, 1];

Apparently I forgot that I was using "position", which is the slowest command for getting the position.


I changed it to getPosAsl and the script runs fast enough (less than 0.01 ms). I need to run this code on each frame so speed was important.


It's still a bit iffy in terms of accuracy but I suppose it'll do for now.

Thank you for your help.

Share this post


Link to post
Share on other sites
2 minutes ago, Mr H. said:

Seems to me there's no solution for your problem I've tried on Diyalah with https://community.bistudio.com/wiki/getPosASLW
 

the values returned are slightly better (-1 swimming at the surface). But do not seem exact. If you want an "universal solution" then getPosASL select 2 should work on MOST maps, if you want a specific solution for diyala, maybe get an estimate of the ASL pos of the river surface and substract from that.

Interesting. That's one hell of a wave though! 😉

Share this post


Link to post
Share on other sites

Yup, now the ministry of free time (aka angry girlfriends) is calling me away from the computer but maybe water level is defined somewhere in cfgworlds  too.

  • Like 1
  • Haha 1

Share this post


Link to post
Share on other sites

What you are talking about are "pond" objects, they are 3D models with a water property that just applies a water shader and water effects to them.
They are basically a 3D modelled object that you can swim inside of.

The lineIntersects thing was already a good start, but don't go from current pos to below terrain, but from current pos upwards.
That will cause problems if objects are between you and water surface though.

Other solution is to go from the sky downwards till you hit the water surface, but that again causes issues when there are objects just above the water.

We could go a slightly different route.

 

First find the water body that you are inside of (only works on "fake" water objects, not on open sea)

https://community.bistudio.com/wiki/lineIntersectsObjs

with flag CF_ONLY_WATER will return you only water objects, just let that run between slightly above and slightly below the player, as the line is INSIDE the object, that should detect it.

Then you get the water object itself. We know that it's mooost likely flat on the top so we don't have to really take the model edges or whatever into account.

We can just use a bounding box to get it's total height

https://community.bistudio.com/wiki/boundingBoxReal

with clippingType clipGeometry.

Now we have the total height, now get the water bodies center with a simple getPosASL or modelToWorldWorld

then add onto that half of the bounding box height to get from center, to top. now you have the top ASL position of the water surface.

You can already use modelToWorldWorld and immediately plug in half the bounding box into there to spare one step.

 

  • Like 1
  • Thanks 2

Share this post


Link to post
Share on other sites

So I'm just putting this here for "future generations":
To get the water depth at a position, simply do:

_get_water_depth = {
	params ["_pos"];
	private _testPos = +_pos; 
	_testPos set [2, getTerrainHeightASL _testPos];
	ASLtoAGL _testPos select 2 //water depth
};

_waterDepth = [_myPos] call _get_water_depth;

Supports waves + pond objects. Note that in the case of pond objects, the object must've been loaded in memory (e.g. it must've been within the player's object view distance).

  • Like 1

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

×