## How to get the *exact* liquid flowing direction? Wuzzy
Member

Posts: 3728
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

### How to get the *exact* liquid flowing direction?

Is there any easy/standard (!) way to get the flowing direction of a flowing liquid node? And how do I get it?
If you look on a flowing liquid like water, you notice a flowing animation. This flowing animation has a direction. What I want is this dircection of the animation.

Ideally I wish I could get the direction as an unit vector (x,y,z).

My current code basically just hacks around the fact that I haven't found a clean standard way yet. It only is able to distinguish between the 4 cardinal directions, it doesn't recognize it if the liquid flows diagonally.

This is the code which is supposed to do this (return value is an unit vector, possible are the 4 cardinal directions only):
Code: Select all
`         local get_flowing_dir = function(self)            local pos = self.object:getpos()            local param2 = minetest.get_node(pos).param2            -- Search for a liquid source, or a flowing liquid node higher than            -- the item's position in the 4 cardinal directions            local posses = {               {x=-1, y=0, z=0},               {x=1, y=0, z=0},               {x=0, y=0, z=-1},               {x=0, y=0, z=1},            }            for _, p in pairs(posses) do               local realpos = vector.add(pos, p)               local name = minetest.get_node(realpos).name               local def = minetest.registered_nodes[name]               local par2 = minetest.get_node(realpos).param2               if def.liquidtype == "source" or (def.liquidtype == "flowing" and par2 > param2) then                  -- Node found! Since we looked upwards, the flowing                  -- direction is the *opposite* of what we've found                  return vector.multiply(p, -1)               end            end         end`

http://repo.or.cz/MineClone/MineClone2. ... t.lua#l376

If someone knows a standard way to get the flowing direction, that would be great, as I could get rid of some code.
My creations. I gladly accept bitcoins: 17fsUywHxeMHKG41UFfu34F1rAxZcrVoqH stu
Member

Posts: 923
Joined: Sat Feb 02, 2013 02:51
Location: United Kingdom
GitHub: stujones11

### Re: How to get the *exact* liquid flowing direction?

I am not sure if this will help but it's the closest thing i've seen. Unfortunately the videos are no longer available. https://forum.minetest.net/viewtopic.php?f=9&t=12442 qwertymine3
Member

Posts: 202
Joined: Wed Jun 03, 2015 14:33
GitHub: Qwertymine
In-game: qwertymine3

### Re: How to get the *exact* liquid flowing direction?

stu wrote:I am not sure if this will help but it's the closest thing i've seen. Unfortunately the videos are no longer available. https://forum.minetest.net/viewtopic.php?f=9&t=12442

I made improvements to that mod to make my first mod - in the process I re-wrote the flow direction code to be clearer and only need 5 nodes to determine the direction (all 16 directions). The flow is the logical one - sometimes the way minetest renders liquid flow is different - but is logically incorrect (e.g. minetest renders a sideways flow between two source nodes, rather than it being still). Code is WTFPL.
https://github.com/Qwertymine/water_physics/blob/master/flowlib/init.lua#L102.
TenPlus1 has this code in his version of the builtin_item mod - which may or may not be better maintained than my original code. This code is MIT.
https://github.com/tenplus1/builtin_item/blob/master/init.lua
Avatar by :devnko-ennekappao: Wuzzy
Member

Posts: 3728
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

### Re: How to get the *exact* liquid flowing direction?

qwertymine3: Does quick_flow give me the liquid flow direction which corresponds exactly to the liquid appearance, or it it just an estimate?

Anyway, I think if it is able to support 16 directions, this is already much better than my current code which only supports 4 directions. Thank you. :-)

I wish some “liquid flow direction” code would be added straight into Minetest's builtin because I think this is a pretty useful utility function, there are many reasons why one wants to know the liquid flow direction. It would also be more standard.
My creations. I gladly accept bitcoins: 17fsUywHxeMHKG41UFfu34F1rAxZcrVoqH qwertymine3
Member

Posts: 202
Joined: Wed Jun 03, 2015 14:33
GitHub: Qwertymine
In-game: qwertymine3

### Re: How to get the *exact* liquid flowing direction?

It is almost accurate, but not completely. There are some parts of the rendering which are directional behaviours, and
make no sense as the actual direction of the liquid flow - e.g.
Code: Select all
`S - sourceX - flowingSXS`

The engine will always render the flowing liquid as flowing towards +X (as it doesn't have a still image to use for the flowing node). My mod will always say that the flowing liquid is still.

Also my mod treats liquids flowing into vertical colomns of liquid differently to the engine - the engine renders the final liquid node of the stream as flowing away from the colomn, while this mod says that the liquid is flowing into the vertical colomn. (you may remove this when fixing my mod though - making it more accurate). e.g
Code: Select all
`y   S|   X|   X v|   X X X X S|   XThe flow at v would be rendered as >, my mod returns <. This is the direction which I think makes more sense, and made the mod I was making with it more fun. This can't be done in general for all liquid_ranges though - so the code will have to be changed to make it more like the way it is rendered. (See below)`

That said - I wrote this code quite a long time ago, and it was before river sources were added - so I don't think that the code is designed to handle anything other than liquid range 7, so it may not be adequate for your use in it's current form.
The code which is affected are lines 91 and 85 - which (I think) determine whether the stream is flowing into a vertical colomn which should not affect it (although the engine thinks it does - see above).

Just remove the if branch of these to conditionals and leave the else branch, and that should make the flow direction more accurate to minetest and not reliant on the liquid_range.

After this I think the only difference to minetest will be the as stated in the first example.
Avatar by :devnko-ennekappao: Wuzzy
Member

Posts: 3728
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

### Re: How to get the *exact* liquid flowing direction?

Awesome! This flowlib looks like it is exactly what I needed.
For MineClone 2, I needed to know the flowing direction so I can make items flow around on water.
Luckily, the only liquid I need to care about here is water, which has a flowing distance of 7. :-)

It works pretty good already! I actually was able to include flowlib and call flowlib.quick_flow in my item entity code to get the direction. Now dropped items flow on water around in a much more precise manner. Great!

If the flowing of the items does not 100% match the graphics, this is probably okay for my purposes. Item flowing is not perfect yet, so I still have to do some work here on my own. But it was an important step nonetheless.

If you should ever improve your flowlib in future, please let me know.

Please document the API functions (a short explanation of purpose, return value and parameters is enough).
And a hint: You don't need to_unit_vector. You can replace it with vector.normalize, this function is in the Lua API and apparently it does exactly the same thing.
My creations. I gladly accept bitcoins: 17fsUywHxeMHKG41UFfu34F1rAxZcrVoqH qwertymine3
Member

Posts: 202
Joined: Wed Jun 03, 2015 14:33
GitHub: Qwertymine
In-game: qwertymine3

### Re: How to get the *exact* liquid flowing direction?

Please document the API functions (a short explanation of purpose, return value and parameters is enough).

Tell me from 2 years ago that API documentaion is a good idea ; ).
I'll probably do so if I get around to re-working my boat_test mod. Works quite well singleplayer, but is a glitchy mess on servers.
Currrently working on a few other mods, so this may take a while.
Wuzzy wrote:And a hint: You don't need to_unit_vector. You can replace it with vector.normalize, this function is in the Lua API and apparently it does exactly the same thing.

Pointless micro-optimisation indeed. That said, I'll try to profile it to see if my inexperienced self was onto something (before almost certainly removing it).
Avatar by :devnko-ennekappao:

neoh4x0r
Member

Posts: 69
Joined: Wed Aug 29, 2018 20:16
GitHub: neoh4x0r

### Re: How to get the *exact* liquid flowing direction?

qwertymine3 wrote:
Please document the API functions (a short explanation of purpose, return value and parameters is enough).

Tell me from 2 years ago that API documentaion is a good idea ; ).
I'll probably do so if I get around to re-working my boat_test mod. Works quite well singleplayer, but is a glitchy mess on servers.
Currrently working on a few other mods, so this may take a while.
Wuzzy wrote:And a hint: You don't need to_unit_vector. You can replace it with vector.normalize, this function is in the Lua API and apparently it does exactly the same thing.

Pointless micro-optimisation indeed. That said, I'll try to profile it to see if my inexperienced self was onto something (before almost certainly removing it).

Actually, the function to_unit_vector, is ...well... a lie.

It is not actually returning a unit vector, but, rather a scaled vector in a given direction.

A unit vector is vector where each component has been divided by the length of the vector -- in other words, the components are converted into percentage ratios.

EG (1,2,3) : len=sqrt(x^2+y^2+z^2)=sqrt(1+4+9)=sqrt(14)=3.74165
||(1,2,3)|| = (1/3.74, 2/3.74,3/3.74) = ~ (0.267, 0.535, 0.802)

That being said, it seems that inv_roots is being used a constant scalar and selected by x^2+z^2 (noting that x and z are left/right, forward/backward (ie 2-d).

EG: when you have a direction vector (which must be normalized to work) and then multiple it by a scalar -- you are actually generating a point that lies on a line in the given direction.
That is the vector equation of a line is: point = origin + scale * direction ; y = b+ mx

As I stated, to_unit_vector does not really describe what this function actually does, because it isn't generating a normalized unit vector -- and as such it cannot be replaced with vector.normalize.

Code: Select all
`--sum of direction vectors must match an array indexlocal function to_unit_vector(dir_vector)   --(sum,root)   -- (0,1), (1,1+0=1), (2,1+1=2), (3,1+2^2=5), (4,2^2+2^2=8)   local inv_roots = { = 1,  = 1,  = 0.70710678118655,  = 0.5      ,  = 0.44721359549996,  = 0.35355339059327}   local sum = dir_vector.x*dir_vector.x + dir_vector.z*dir_vector.z   return {x=dir_vector.x*inv_roots[sum],y=dir_vector.y      ,z=dir_vector.z*inv_roots[sum]}endfunction vector.normalize(v)   local len = vector.length(v)   if len == 0 then      return {x=0, y=0, z=0}   else      return vector.divide(v, len)   endend`