]> icculus.org git repositories - divverent/nexuiz.git/blob - misc/tools/hitplot2tga.c
hitplot to tga tool
[divverent/nexuiz.git] / misc / tools / hitplot2tga.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <err.h>
5 #include <string.h>
6 #include <math.h>
7
8 typedef void (*colorfunc_t) (double x, double y, double dx, double dy, double *r, double *g, double *b);
9
10 double rnd()
11 {
12         return rand() / (RAND_MAX + 1.0);
13 }
14
15 double softclip(double x, double a)
16 {
17         // don't ask what this does - but it works
18         double cse = (2*a*x - x - a + 1) * x;
19         return cse / (cse + (1 - a));
20 }
21
22 void writepic(colorfunc_t f, const char *fn, int width, int height)
23 {
24         int x, y;
25         uint8_t tga[18];
26
27         FILE *file = fopen(fn, "wb");
28         if(!file)
29                 err(1, "fopen >%s", fn);
30
31         memset(tga, 0, sizeof(tga));
32         tga[2] = 2;          // uncompressed type
33         tga[12] = (width >> 0) & 0xFF;
34         tga[13] = (width >> 8) & 0xFF;
35         tga[14] = (height >> 0) & 0xFF;
36         tga[15] = (height >> 8) & 0xFF;
37         tga[16] = 24;        // pixel size
38
39         if(fwrite(&tga, sizeof(tga), 1, file) != 1)
40                 err(1, "fwrite >%s", fn);
41         //for(y = height-1; y >= 0; --y)
42         for(y = 0; y < height; ++y)
43                 for(x = 0; x < width; ++x)
44                 {
45                         uint8_t rgb[3];
46                         double rr, gg, bb;
47                         double xx, yy;
48                         double xxx, yyy, zzz;
49                         double r;
50                         xx = (x + 0.5) / width;
51                         yy = (y + 0.5) / height;
52                         f(xx, yy, 0.5 / width, 0.5 / height, &rr, &gg, &bb);
53                         rgb[2] = floor(rnd() + rr * 255);
54                         rgb[1] = floor(rnd() + gg * 255);
55                         rgb[0] = floor(rnd() + bb * 255);
56                         if(fwrite(rgb, sizeof(rgb), 1, file) != 1)
57                                 err(1, "fwrite >%s", fn);
58                 }
59         
60         fclose(file);
61 }
62
63 typedef struct
64
65         double x, y, dist;
66         int weapon;
67 }
68 plotpoint_t;
69
70 plotpoint_t *plotpoints;
71 size_t nPlotpoints, allocatedPlotpoints;
72
73 void readpoints(const char *fn)
74 {
75         char buf[1024];
76
77         FILE *infile = fopen(fn, "r");
78         if(!infile)
79                 err(1, "fopen <%s", fn);
80
81         nPlotpoints = allocatedPlotpoints = 0;
82         plotpoints = NULL;
83
84         while(fgets(buf, sizeof(buf), infile))
85         {
86                 if(*buf == '#') 
87                 {
88                         fputs(buf + 1, stdout);
89                         continue;
90                 }
91                 if(nPlotpoints >= allocatedPlotpoints)
92                 {
93                         if(allocatedPlotpoints == 0)
94                                 allocatedPlotpoints = 1024;
95                         else
96                                 allocatedPlotpoints = nPlotpoints * 2;
97                         plotpoints = (plotpoint_t *) realloc(plotpoints, allocatedPlotpoints * sizeof(*plotpoints));
98                 }
99                 if(sscanf(buf, "%lf %lf %lf %d", &plotpoints[nPlotpoints].x, &plotpoints[nPlotpoints].y, &plotpoints[nPlotpoints].dist, &plotpoints[nPlotpoints].weapon) != 4)
100                         continue;
101                 ++nPlotpoints;
102         }
103 }
104
105 void calcplot1(double x, double y, double *out, double sigma2)
106 {
107         size_t i;
108         double dist2;
109         double val, totalval = 0, weight, totalweight = 0;
110
111         for(i = 0; i < nPlotpoints; ++i)
112         {
113                 dist2 = (x - plotpoints[i].x) * (x - plotpoints[i].x) + (y - plotpoints[i].y) * (y - plotpoints[i].y);
114                 weight = 1; // / plotpoints[i].dist;
115                 val = exp(-dist2 / sigma2);
116
117                 totalweight += weight;
118                 totalval += weight * val;
119         }
120
121         *out = softclip(totalval / (totalweight * sqrt(sigma2 * 2 * M_PI)), 0.8);
122 }
123
124 void calcplotp(double x, double y, double dx, double dy, double *out)
125 {
126         size_t i;
127         double distx, disty;
128
129         for(i = 0; i < nPlotpoints; ++i)
130         {
131                 distx = x - plotpoints[i].x;
132                 disty = y - plotpoints[i].y;
133
134                 if(distx < dx)
135                 if(distx > -dx)
136                 if(disty < dy)
137                 if(disty > -dy)
138                 {
139                         *out = 1;
140                         break;
141                 }
142         }
143 }
144
145 void calcplot(double x, double y, double dx, double dy, double *r, double *g, double *b)
146 {
147         calcplot1(x, y, r, 1/64.0);
148         calcplot1(x, y, g, 1/512.0);
149         calcplot1(x, y, b, 1/4096.0);
150         calcplotp(x, y, dx, dy, b);
151 }
152
153 int main(int argc, char **argv)
154 {
155         FILE *in;
156
157         if(argc != 3)
158                 errx(1, "Usage: %s infile.plot outfile.tga", *argv);
159         
160         readpoints(argv[1]);
161         writepic(calcplot, argv[2], 512, 512);
162 }