sandbox/Antoonvh/raycaster.c

    Adaptive Ray caster

    This program sends pixel coordinates to stdout, reads the correspoding RGB codes from stdin, and writes a ppm image to stderr.

    #include "utils.h"
    scalar ref[], r[], g[], b[], * rgb = {r, g, b};
    
    void refine_ref (Point point, scalar s) {
      foreach_child()
        s[] = nodata;
    }
    
    int maxlevel = 9;
    double tol = 5;
    
    int main(int argc, char ** argv) {
      if (argc > 1)
        maxlevel = atoi(argv[1]);
      if (argc > 2)
        tol = atof(argv[2]);
      int Ni = 1 << maxlevel;
      init_grid (1 << (maxlevel - 2));
      ref.refine = refine_ref;
      foreach() 
        ref[] = nodata;
      int count = 1;
      while (count > 0) {
        count = 0;
        foreach(reduction(+:count)) 
          if (ref[] == nodata) 
    	count++;
        fwrite (&count, 1, sizeof(int),  stdout);
        fflush (stdout);
        int s = sizeof(double);
        if (count > 0) {
          foreach_leaf() { //Z-order sequence
    	if (ref[] == nodata) {
    	  fwrite (&x, s, 1, stdout);
    	  fwrite (&y, s, 1, stdout);
    	}
          }
          fflush (stdout);
          foreach_leaf() { //Identical Z-order sequence
    	if (ref[] == nodata) {
    	  for (scalar s in rgb) {
    	    unsigned char c;
    	    read (STDIN_FILENO, &c, 1);
    	    s[] = c;
    	  }
    	}
    	ref[] = 0.;
          }
          boundary (rgb);
          int d = min (depth() + 1, maxlevel);
          while(adapt_wavelet ({r,g,b}, (double[]){tol, tol, tol}, d, 99).nf);
        }
      }
      fprintf (stderr, "P6\n%d %d\n%d\n", Ni, Ni, 255);
      for (int j = 0; j < Ni; j++) {
        double yp = L0 - (j + 0.5)*L0/Ni;
        for (int i = 0; i < Ni; i++) {
          double xp = X0 + (i + 0.5)*L0/Ni;
          unsigned char px[3];
          Point point = locate (xp, yp);
          if (level == maxlevel) {
    	px[0] = r[];
    	px[1] = g[];
    	px[2] = b[];
          } else {
    	px[0] = interpolate_linear (point, (struct _interpolate){r, xp, yp});
    	px[1] = interpolate_linear (point, (struct _interpolate){g, xp, yp});
    	px[2] = interpolate_linear (point, (struct _interpolate){b, xp, yp});
          }
          fwrite (px, 1, 3, stderr);
        }
      }
      fflush (stderr);
    }