Blame simple/world-gen/water.inc.c

878d83
878d83
878d83
typedef struct {
878d83
  HMap *hmap;
878d83
  HMap *wmap;
878d83
} Water;
878d83
878d83
878d83
878d83
void waterInit(Water *w, HMap *hmap, HMap *wmap) {
878d83
  w->hmap = hmap;
878d83
  w->wmap = wmap;
878d83
  for(int i = 0; i < HMAP_SIZE; ++i)
878d83
    for(int j = 0; j < HMAP_SIZE; ++j)
878d83
      w->wmap->map[i][j] = w->hmap->map[i][j];
878d83
}
878d83
878d83
878d83
void waterRain(Water *w, double k) {
878d83
  for(int i = 0; i < HMAP_SIZE; ++i)
878d83
    for(int j = 0; j < HMAP_SIZE; ++j)
878d83
      w->wmap->map[i][j] += k;
878d83
}
878d83
878d83
878d83
void waterFall(Water *w, double wk, double hk) {
878d83
  static const int di[4] = { -1, 1,  0, 0 };
878d83
  static const int dj[4] = {  0, 0, -1, 1 };
878d83
878d83
  hmapCopy(w->hmap);
878d83
  hmapCopy(w->wmap);
878d83
  for(int i = 0; i < HMAP_SIZE; ++i) {
878d83
    for(int j = 0; j < HMAP_SIZE; ++j) {
878d83
      double dz = w->wmap->old[i][j] - w->hmap->old[i][j];
878d83
      dz *= 0.25;
878d83
      if (dz > 0) {
878d83
        double sum = 0;
878d83
        double v[4] = {};
878d83
        for(int k = 0; k < 4; ++k) {
878d83
          int ii = ((i+di[k]) + HMAP_SIZE)%HMAP_SIZE;
878d83
          int jj = ((j+dj[k]) + HMAP_SIZE)%HMAP_SIZE;
878d83
          double vv = w->wmap->old[i][j] - w->wmap->old[ii][jj];
878d83
          if (vv < 0) vv = 0;
878d83
          //vv = vv*vv*vv;
878d83
          v[k] = vv;
878d83
          sum += vv;
878d83
        }
878d83
        double s = wk*sum;
878d83
        if (s > dz) s = dz;
878d83
        if (sum > 1e-10) {
878d83
          for(int k = 0; k < 4; ++k) {
878d83
            int ii = ((i+di[k]) + HMAP_SIZE)%HMAP_SIZE;
878d83
            int jj = ((j+dj[k]) + HMAP_SIZE)%HMAP_SIZE;
878d83
            double vv = v[k]/sum*s;
878d83
            w->wmap->map[ii][jj] += v[k]/sum*s;
878d83
            w->wmap->map[i][j] -= vv;
878d83
            double dh = w->hmap->old[i][j] - w->hmap->map[ii][jj];
878d83
            dh *= 0.25;
878d83
            if (dh > 0) {
878d83
              vv = vv*hk;
878d83
              if (vv > dh) vv = dh;
878d83
              w->hmap->map[ii][jj] += vv;
878d83
              w->hmap->map[i][j] -= vv;
878d83
            }
878d83
          }
878d83
        }
878d83
      }
878d83
    }
878d83
  }
878d83
}
878d83
878d83
878d83
double waterEvaporation(Water *w, double k) {
878d83
  double sum;
878d83
  for(int i = 0; i < HMAP_SIZE; ++i) {
878d83
    for(int j = 0; j < HMAP_SIZE; ++j) {
878d83
      double dz = w->wmap->map[i][j] - w->hmap->map[i][j];
878d83
      if (dz < 0) dz = 0;
878d83
      if (dz > k) dz = k;
878d83
      sum += dz;
878d83
      w->wmap->map[i][j] -= dz;
878d83
    }
878d83
  }
878d83
  return sum;
878d83
}
878d83
878d83
878d83
void waterCycle(Water *w, double fallK, double erosionK, double evaK) {
878d83
  double sum = waterEvaporation(w, evaK);
878d83
  waterRain(w, sum/(HMAP_SIZE*HMAP_SIZE));
878d83
  for(int i = 0; i < 10; ++i) {
878d83
    waterFall(w, fallK/10, erosionK/10);
878d83
    printf(".");
878d83
    fflush(stdout);
878d83
  }
878d83
  printf("\n");
878d83
}