sandbox/Antoonvh/raycasterv.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"
#include "my_vertex.h"
#include "adapt_field.h"
vector u;
void refine_r (Point point, scalar s) {
(s, 0, 0, 0) = s[];
fine (s, 2, 0, 0) = s[1];
fine (s, 0, 2, 0) = s[0,1];
fine (s, 2, 2, 0) = s[1,1];
fine (s, 1, 0, 0) = nodata;
fine (s, 1, 1, 0) = nodata;
fine (s, 0, 1, 0) = nodata;
fine (s, 1, 2, 0) = nodata;
fine (s, 2, 1, 0) = nodata;
fine }
void refine_gb (Point point, scalar s) {
(s, 0, 0, 0) = s[];
fine (s, 2, 0, 0) = s[1];
fine (s, 0, 2, 0) = s[0,1];
fine (s, 2, 2, 0) = s[1,1];
fine }
double interpv (scalar s, double xp, double yp) {
= locate (xp, yp);
Point point if (point.level > 0) {
double w00 = (xp - (x - Delta/2.))*(yp - (y - Delta/2.));
double w10 = ((x + Delta/2.) - xp)*(yp - (y - Delta/2.));
double w01 = (xp - (x - Delta/2.))*((y + Delta/2.) - yp);
double w11 = ((x + Delta/2.) - xp)*((y + Delta/2.) - yp);
return (w00*s[1,1] + w10*s[0,1] + w01*s[1] + w11*s[])/sq(Delta);
}
else return 0;
}
void get_w (scalar * list, scalar w) {
scalar * wl = list_clone (list);
scalar s, ws;
for (s, ws in list,wl)
wavelet (s, ws);
for (int l = depth() - 2; l < depth(); l++)
foreach_coarse_level (l) {
double maxw = 0.;
foreach_child() {
double a = 0;
for (scalar ws in wl)
+= fabs(ws[]);
a = max(maxw, a);
maxw }
[] = maxw;
w}
foreach()
[] = coarse(w,0,0,0);
w}
int maxlevel = 9;
double tol = 5;
int main (int argc, char ** argv) {
if (argc > 1)
= atoi(argv[1]);
maxlevel if (argc > 2)
= atof(argv[2]);
tol #if _OPENMP
int threads = npe();
#endif
int s = sizeof(double);
int Ni = 1 << maxlevel;
(1 << (maxlevel - 2));
init_grid scalar w[];
scalar r[], g[], b[], * rgb = {r, g, b};
for (scalar s in rgb) {
.refine = refine_gb;
s.prolongation = refine_vert;
s.restriction = restriction_vert;
s}
.refine = refine_r;
rforeach_vertex()
[] = nodata;
rint count = 1;
while (count > 0) {
= 0;
count foreach_vertex(reduction(+:count))
if (r[] == nodata)
++;
count(&count, 1, sizeof(int), stdout);
fwrite fflush (stdout);
if (count > 0) {
#if _OPENMP
(1);
omp_set_num_threads#endif
foreach_vertex() {
if (r[] == nodata) {
(&x, s, 1, stdout);
fwrite (&y, s, 1, stdout);
fwrite }
}
fflush (stdout);
foreach_vertex() {
if (r[] == nodata) {
for (scalar s in rgb) {
unsigned char c;
(STDIN_FILENO, &c, 1);
read [] = c;
s}
}
}
#if _OPENMP
(threads);
omp_set_num_threads#endif
if (depth() == maxlevel - 2)
multigrid_restriction(rgb);
get_w (rgb, w);
adapt_field (w, tol, 0, maxlevel, 99, list = rgb);
}
}
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 = (i + 0.5)*L0/Ni;
unsigned char px[3];
[0] = interpv (r, xp, yp);
px[1] = interpv (g, xp, yp);
px[2] = interpv (b, xp, yp);
px(px, sizeof(unsigned char), 3, stderr);
fwrite }
}
fflush (stderr);
}