Cuberite Forum
Water physics - Printable Version

+- Cuberite Forum (https://forum.cuberite.org)
+-- Forum: Cuberite (https://forum.cuberite.org/forum-4.html)
+--- Forum: Development (https://forum.cuberite.org/forum-13.html)
+--- Thread: Water physics (/thread-2053.html)



Water physics - link0ln - 07-10-2015

I made some code that releases pseudo real water physics.
I'm not developer, sory for my not so good realization Undecided

For now realized:
  • Water share by 8 levels(by meta field of a block) form 0 to 7. 0 - is a full block of water. 7 - almost empty.
  • Water falling;(if upper block has 4 level, next down block will have 4 level).
  • Water mooving to neigbor block. Current block meta devide by 2. First half will stay, second will flow to neigbor block.
  • If neigbor under block is water and current have 7 meta tag flow it to it.
Need to be realized:
  • Need good algo to allocate water levels in the plane.
  • More good code optimization because require good cpu.
  • Distribute computing by threads.
  • For now i dont understand how to make flow to neigbor chunk.

Code:
void waterbalance(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, int ExtX, int ExtY, int ExtZ){
        BLOCKTYPE CurBl,NextBl,UnderBl,UnderNextBl,NextBl2; NIBBLETYPE CurMet,NextMet,CurNewMet,NextNewMet,UnderMet,UnderNextMet,NextMet2;
        int half,ost;

CurBl = a_Chunk->GetBlock(a_RelX, a_RelY, a_RelZ);
CurMet = a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ);

if (CurBl != 8){
        return;
}

//Flow water down ------------------------
UnderBl = a_Chunk->GetBlock(a_RelX, a_RelY-1, a_RelZ);
if (UnderBl == 0){
        a_Chunk->SetBlock(a_RelX, a_RelY-1, a_RelZ, 8, CurMet);
        a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, 0, 0);
        return;
}
if ( (UnderBl == 9) || (UnderBl == 8)) {
        UnderMet = a_Chunk->GetMeta(a_RelX, a_RelY-1, a_RelZ);
        //LOG("Add flow to %d %d",UnderBl,UnderMet);
        if ((UnderMet > 0) && (CurMet < 7)){
                a_Chunk->SetBlock(a_RelX, a_RelY-1, a_RelZ, 8, UnderMet-1);
                a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, 8, CurMet+1);
                return;
        }
        if ((UnderMet > 0) && (CurMet == 7)){
                a_Chunk->SetBlock(a_RelX, a_RelY-1, a_RelZ, 8, UnderMet-1);
                a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, 0, 0);
                return;
        }
}
//-----------------------------------


if (CurMet == 7) {
        UnderNextBl = a_Chunk->GetBlock(a_RelX+ExtX, a_RelY-1, a_RelZ+ExtZ);
        UnderNextMet = a_Chunk->GetMeta(a_RelX+ExtX, a_RelY-1, a_RelZ+ExtZ);
        if ( (UnderNextBl == 8) && (UnderNextMet > 0) ){
                a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ,0, 0);
                a_Chunk->SetBlock(a_RelX+ExtX, a_RelY-1, a_RelZ+ExtZ,8, UnderNextMet-1);
        }      
}      


NextBl = a_Chunk->GetBlock(a_RelX+ExtX, a_RelY, a_RelZ+ExtZ);
NextMet = a_Chunk->GetMeta(a_RelX+ExtX, a_RelY, a_RelZ+ExtZ);
// Flow to neigbor free block
if  ( (NextBl == 0) && (CurMet < 7) ){
        half = (8-CurMet)/2;
        ost = (8-CurMet)%2;
        CurNewMet = 8-half-ost;
        NextNewMet = 8-half;
        //if (a_RelY>50){
                if ( (a_RelX>0) && (a_RelX<15) && (a_RelZ>0) && (a_RelZ<15) ){
                        a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, 8, CurNewMet);
                        a_Chunk->SetBlock(a_RelX+ExtX, a_RelY, a_RelZ+ExtZ, 8, NextNewMet);
                        //LOG("Add water from xyz: %d %d %d, extx %d, extz %d: curmet %d, nextmet %d, CurNewMet %d, NextNewMet %d", a_RelX, a_RelY, a_RelZ, ExtX, ExtZ, CurMet, NextMet, CurNewMet, NextNewMet);
                }      
        //}    
        return;
}      
//      


//Flow to neigbor water block if have more water.
if ( ((NextBl == 8) || (NextBl == 9)) && (CurMet < NextMet) && (CurMet < 7) && (NextMet > 0)){
                int diff;
                diff = NextMet - CurMet;
                if (diff==1){
                        //LOG("Diff is 1");
                        for (int i=a_RelX+2;i<=a_RelX+7;i++){
                                NextBl2 = a_Chunk->GetBlock(i, a_RelY, a_RelZ);
                                NextMet2 = a_Chunk->GetMeta(i, a_RelY, a_RelZ);
                                //LOG("Switch to block %d %d %d CurMet %d, NextBl2 %d, NextMet2 %d",i, a_RelY, a_RelZ,CurMet,NextBl2,NextMet2);
                                if ( (NextBl2 != 8) && (NextBl2 != 0) ){
                                        //LOG("End block...");
                                        return;
                                }      
                                if ( (NextBl2 == 8) && (NextBl2 > CurMet)){
                                        //a_Chunk->SetBlock(i, a_RelY, a_RelZ, 8, NextMet2-1);
                                        //a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, 8, CurMet+1);
                                        return;
                                }      
                                if (NextBl2 == 0){
                                        //a_Chunk->SetBlock(i, a_RelY, a_RelZ, 8, 7);
                                        //a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, 8, CurMet+1);
                                        return;
                                }      
                        }      
                        
                }      
                
                //LOG("Move water xyz %d %d %d, extx %d, extz %d: curmet %d, nextmet %d", a_RelX, a_RelY, a_RelZ, ExtX, ExtZ, CurMet+1, NextMet-1);
                a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, 8, CurMet+1);
                a_Chunk->SetBlock(a_RelX+ExtX, a_RelY, a_RelZ+ExtZ, 8, NextMet-1);
        return;
}      


}


It called from cFloodyFluidSimulator::SimulateBlock as example:

Code:
waterbalance(a_Chunk,a_RelX,a_RelY,a_RelZ,1,0,0);
waterbalance(a_Chunk,a_RelX,a_RelY,a_RelZ,-1,0,0);
waterbalance(a_Chunk,a_RelX,a_RelY,a_RelZ,0,0,1);
waterbalance(a_Chunk,a_RelX,a_RelY,a_RelZ,0,0,-1);
return;

return is to disable other water simulation.

Maybe anybody can help to release other functions and optimizations.
Questions and proposal - contact to me. Skype: link0ln
Thks.


RE: Water physics - Hax52 - 07-11-2015

Not sure what your getting at.
The current (no pun intended) water simulator seems to work great.


RE: Water physics - tigerw - 07-12-2015

It is a prototype for simulating real water physics, as opposed to the simplified Minecraft version. Sounds interesting!