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
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!
|