voxel / ideas

issue tracker for new voxel.js plugin ideas
4 stars 1 forks source link

Water (fluids/liquids) #1

Open deathcap opened 10 years ago

deathcap commented 10 years ago

Flowing water and/or other liquids or fluids

deathcap commented 10 years ago

Cool demo of WebGL water: http://madebyevan.com/webgl-water/ (discussion)

deathcap commented 10 years ago

Also some discussion of water in voxel-based worlds: http://www.dwarfcorp.com/site/2013/06/19/how-water-works-in-dwarfcorp/ http://reddit.com/r/VoxelGameDev/comments/1v4mvy/flowing_water_a_minecraftlike_game/ http://www.djoslin.info/finiteliquid.php

deathcap commented 10 years ago

Implemented buckets (items to pickup/place fluids) in: https://github.com/deathcap/voxel-bucket - but it is only using static opaque blocks for the 'water' voxels, for now. More and important (and difficult):

deathcap commented 10 years ago

Relevant to spreading/flowing: https://github.com/shama/voxel-virus

deathcap commented 10 years ago

voxel-virus has a pretty good water implementation (demo):

screen shot 2014-02-25 at 8 00 17 pm

will have to see how it can be wired up to voxel-fluid/bucket; want at least separate 'source' (still) and 'flowing' blocks, so only source blocks can be bucketed, and the 'flow' blocks could be rendered at varying heights (may require GH-3 custom block models)

deathcap commented 10 years ago

Made some changes to voxel-virus at https://github.com/deathcap/voxel-virus - works well with voxel-fluid and voxel-bucket; it now starts spreading from a Water Source block (which can be picked up or placed with a bucket):

screen shot 2014-03-08 at 8 28 29 pm

and creates Water Flow blocks as it spreads, starting the 'infection' when placed (setBlock event):

screen shot 2014-03-08 at 8 27 48 pm

The flow algorithm may require some refinement, but it is able to fill the bottom of a hole fairly well:

screen shot 2014-03-08 at 8 28 02 pm

deathcap commented 10 years ago

voxel-virus spreads by listening to the voxel-engine tick event, then traversing an internal this.infected data structure. This design introduces several complexities, since the state is stored outside of the voxels themselves. When placing a water source block (with a bucket, or the source block directly), infect has to be called to update the infected list (using a setBlock listener, but also considered an onUse callback via voxel-use). If the voxels are loaded elsewhere (e.g. from a world save) the spreading won't apply, and if the world changes unexpectedly it may get out of sync with the infected list (not observed, but could happen). Also may complicate implementing water 'drying up' mechanics (when the source block is taken away, removing the flowed water).

Another approach: store the state in the voxels themselves. If only a few states are needed (presumably corresponding to the level or water depth), could register multiple blocks as needed (voxel-registry registerBlocks() - provides easy access to the extra blocks as 'metadata'), then compute the spreading when the neighboring blocks change (setBlock vs tick).

edit: how dwarf fortress simulates fluids (water and magma): http://dwarffortresswiki.org/index.php/DF2012:Flow