nl-knd_client 0.0.0.pre.usegit
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +25 -0
- data/.rspec +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +53 -0
- data/LICENSE +661 -0
- data/README.md +59 -0
- data/Rakefile +10 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/ext/Makefile +36 -0
- data/ext/front.c +26 -0
- data/ext/front_grid.c +43 -0
- data/ext/kinutils/extconf.rb +8 -0
- data/ext/kinutils/kinutils.c +411 -0
- data/ext/kinutils/unpack.c +212 -0
- data/ext/kinutils/unpack.h +108 -0
- data/ext/overhead.c +26 -0
- data/ext/overhead_grid.c +42 -0
- data/ext/side.c +26 -0
- data/ext/side_grid.c +42 -0
- data/ext/unpacktest.c +69 -0
- data/lib/nl/knd_client.rb +21 -0
- data/lib/nl/knd_client/em_knd_client.rb +904 -0
- data/lib/nl/knd_client/em_knd_command.rb +77 -0
- data/lib/nl/knd_client/simple_knd_client.rb +106 -0
- data/lib/nl/knd_client/version.rb +5 -0
- data/lib/nl/knd_client/zone.rb +227 -0
- data/nl-knd_client.gemspec +37 -0
- metadata +145 -0
@@ -0,0 +1,212 @@
|
|
1
|
+
/*
|
2
|
+
* Non-inline definitions and functions for Kinect data pack/unpack code.
|
3
|
+
* (C)2011 Mike Bourgeous
|
4
|
+
*/
|
5
|
+
#include <string.h>
|
6
|
+
#include <math.h>
|
7
|
+
|
8
|
+
#include <nlutils/nlutils.h>
|
9
|
+
|
10
|
+
#define UNPACK_INLINE
|
11
|
+
#include "unpack.h"
|
12
|
+
|
13
|
+
// TODO: Put ku_xworld, ku_yworld, lut into a library of addons, or submit as patches
|
14
|
+
// to libfreenect.
|
15
|
+
|
16
|
+
// Depth look-up table (translates depth sample into world-space millimeters).
|
17
|
+
int ku_depth_lut[2048];
|
18
|
+
|
19
|
+
// Converts x in pixels and z in world millimeters to x in world millimeters.
|
20
|
+
static int ku_xworld(int x, int zw)
|
21
|
+
{
|
22
|
+
// tan 28 ~= .53171 (1089 ~= .53171 * 2048)
|
23
|
+
// 0xcccd is the ~reciprocal of 10 (factor of W/2=320)
|
24
|
+
// Add 2**34 (0x400000000) for rounding before shift
|
25
|
+
// Shift right by 35:
|
26
|
+
// 11 bits for tangent (* 2048 above)
|
27
|
+
// 19 bits for reciprocal multiplication by 1/10 (factor of W/2=320)
|
28
|
+
// 5 bits for division by 32 (other factor of W/2=320)
|
29
|
+
//
|
30
|
+
// In total, with an overly generous maximum range of +/-16384mm (15
|
31
|
+
// bits), and an overhead of 35 bits due to arithmetic, 50 bits are
|
32
|
+
// needed for the calculation.
|
33
|
+
return (((int64_t)zw * (320 - x) * 1089 * 0xcccd) + 0x400000000) >> 35;
|
34
|
+
}
|
35
|
+
|
36
|
+
// Converts y in pixels and z in world millimeters to y in world millimeters.
|
37
|
+
static int ku_yworld(int y, int zw)
|
38
|
+
{
|
39
|
+
return ku_xworld(y + (640 - 480) / 2, zw);
|
40
|
+
}
|
41
|
+
|
42
|
+
// Initializes the depth look-up table.
|
43
|
+
// Copied from the knd daemon code, based on:
|
44
|
+
// http://groups.google.com/group/openkinect/browse_thread/thread/31351846fd33c78/e98a94ac605b9f21#e98a94ac605b9f21
|
45
|
+
void ku_init_lut()
|
46
|
+
{
|
47
|
+
int i;
|
48
|
+
|
49
|
+
for(i = 0; i < 2047; i++) {
|
50
|
+
ku_depth_lut[i] = (int)(0.1236f * tanf(i / 2842.5f + 1.1863f) * 1000.0f);
|
51
|
+
}
|
52
|
+
ku_depth_lut[2047] = 1048576;
|
53
|
+
}
|
54
|
+
|
55
|
+
// Finds the closest entry in the depth look-up table to the given world-space
|
56
|
+
// depth value in millimeters without going over. Uses a binary search.
|
57
|
+
int ku_reverse_lut(int zw)
|
58
|
+
{
|
59
|
+
int idx = PXZMAX / 2;
|
60
|
+
int off = PXZMAX / 4;
|
61
|
+
|
62
|
+
while(off > 0 && ku_depth_lut[idx] != zw) {
|
63
|
+
if(ku_depth_lut[idx] > zw) {
|
64
|
+
idx -= off;
|
65
|
+
} else if(ku_depth_lut[idx] < zw) {
|
66
|
+
idx += off;
|
67
|
+
}
|
68
|
+
|
69
|
+
off >>= 1;
|
70
|
+
}
|
71
|
+
|
72
|
+
// Binary search isn't perfect due to truncation, so find the optimum value
|
73
|
+
while(ku_depth_lut[idx] > zw && idx > 0) {
|
74
|
+
idx--;
|
75
|
+
}
|
76
|
+
while(ku_depth_lut[idx + 1] < zw && idx <= PXZMAX) {
|
77
|
+
idx++;
|
78
|
+
}
|
79
|
+
|
80
|
+
return idx;
|
81
|
+
}
|
82
|
+
|
83
|
+
// Plots a linear depth version of the given perspective image on the 8-bit
|
84
|
+
// output surface, which must be 640x480 bytes.
|
85
|
+
void plot_linear(const uint16_t *in, uint8_t *out)
|
86
|
+
{
|
87
|
+
int x, y, pix;
|
88
|
+
|
89
|
+
for(pix = 0, y = 0; y < 640; y++) {
|
90
|
+
for(x = 0; x < 480; x++, pix++) {
|
91
|
+
out[pix] = 255 - CLAMP(0, 255, ((int32_t)ku_depth_lut[(65535 - in[pix]) >> 5] - 400) * 255 / ZMAX);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
// Turns overhead view coordinates into a pixel index.
|
97
|
+
#define OVPX(xw, zw) (((zw) * ZPIX / ZMAX) * XPIX + ((xw) * XPIX / XMAX + XPIX / 2))
|
98
|
+
|
99
|
+
// Plots an overhead view on the given raw linear 8-bit grayscale image
|
100
|
+
// surface, which must be XPIX bytes wide by ZPIX bytes tall.
|
101
|
+
void plot_overhead(const uint16_t *in, uint8_t *out)
|
102
|
+
{
|
103
|
+
int y, x, pix, val;
|
104
|
+
int xw, zw, opx;
|
105
|
+
int c;
|
106
|
+
|
107
|
+
memset(out, 0, XPIX * ZPIX);
|
108
|
+
|
109
|
+
// TODO: Draw borders
|
110
|
+
|
111
|
+
for(pix = 0, y = 0; y < 480; y++) {
|
112
|
+
for(x = 0; x < 640; x++, pix++) {
|
113
|
+
val = (65535 - in[pix]) >> 5;
|
114
|
+
zw = ku_depth_lut[val];
|
115
|
+
if(val >= 2047 || zw >= ZMAX) {
|
116
|
+
continue;
|
117
|
+
}
|
118
|
+
xw = ku_xworld(x, zw);
|
119
|
+
|
120
|
+
opx = OVPX(xw, zw);
|
121
|
+
if(opx < 0 || opx >= XPIX * ZPIX) {
|
122
|
+
continue;
|
123
|
+
}
|
124
|
+
c = out[opx];
|
125
|
+
c += 2;
|
126
|
+
if(c > 255) {
|
127
|
+
c = 255;
|
128
|
+
}
|
129
|
+
out[opx] = c;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
// Turns side view coordinates into a pixel index.
|
135
|
+
#define SVPX(zw, yw) (((-yw) * YPIX / YMAX + YPIX / 2) * ZPIX + ((zw) * ZPIX / ZMAX))
|
136
|
+
|
137
|
+
// Plots a side view on the given raw linear 8-bit grayscale image surface,
|
138
|
+
// which must be ZPIX bytes wide by YPIX bytes tall.
|
139
|
+
void plot_side(const uint16_t *in, uint8_t *out)
|
140
|
+
{
|
141
|
+
int y, x, pix, val;
|
142
|
+
int yw, zw, opx;
|
143
|
+
int c;
|
144
|
+
|
145
|
+
memset(out, 0, ZPIX * YPIX);
|
146
|
+
|
147
|
+
// TODO: Draw borders
|
148
|
+
// TODO: Allow skipping for speed
|
149
|
+
|
150
|
+
for(pix = 0, y = 0; y < 480; y++) {
|
151
|
+
for(x = 0; x < 640; x++, pix++) {
|
152
|
+
val = (65535 - in[pix]) >> 5;
|
153
|
+
zw = ku_depth_lut[val];
|
154
|
+
if(val >= 2047 || zw >= ZMAX) {
|
155
|
+
continue;
|
156
|
+
}
|
157
|
+
yw = ku_yworld(y, zw);
|
158
|
+
|
159
|
+
opx = SVPX(zw, yw);
|
160
|
+
if(opx < 0 || opx >= ZPIX * YPIX) {
|
161
|
+
continue;
|
162
|
+
}
|
163
|
+
c = out[opx];
|
164
|
+
c += 2;
|
165
|
+
if(c > 255) {
|
166
|
+
c = 255;
|
167
|
+
}
|
168
|
+
out[opx] = c;
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
// Turns front view coordinates into a pixel index.
|
174
|
+
#define FVPX(xw, yw) (((-yw) * YPIX / YMAX + YPIX / 2) * XPIX + ((-xw) * XPIX / XMAX + XPIX / 2))
|
175
|
+
|
176
|
+
// Plots a front view on the given raw linear 8-bit grayscale image surface,
|
177
|
+
// which must be XPIX bytes wide by YPIX bytes tall.
|
178
|
+
void plot_front(const uint16_t *in, uint8_t *out)
|
179
|
+
{
|
180
|
+
int y, x, pix, val;
|
181
|
+
int xw, yw, zw, opx;
|
182
|
+
int c;
|
183
|
+
|
184
|
+
memset(out, 0, XPIX * YPIX);
|
185
|
+
|
186
|
+
// TODO: Draw borders
|
187
|
+
// TODO: Allow skipping for speed
|
188
|
+
|
189
|
+
for(pix = 0, y = 0; y < 480; y++) {
|
190
|
+
for(x = 0; x < 640; x++, pix++) {
|
191
|
+
val = (65535 - in[pix]) >> 5;
|
192
|
+
zw = ku_depth_lut[val];
|
193
|
+
if(val >= 2047 || zw >= ZMAX) {
|
194
|
+
continue;
|
195
|
+
}
|
196
|
+
xw = ku_xworld(x, zw);
|
197
|
+
yw = ku_yworld(y, zw);
|
198
|
+
|
199
|
+
opx = FVPX(xw, yw);
|
200
|
+
if(opx < 0 || opx >= XPIX * YPIX) {
|
201
|
+
continue;
|
202
|
+
}
|
203
|
+
c = out[opx];
|
204
|
+
c += 1 + (zw - 512) / 256; // TODO: Scale intensity by surface area
|
205
|
+
if(c > 255) {
|
206
|
+
c = 255;
|
207
|
+
}
|
208
|
+
out[opx] = c;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
/*
|
2
|
+
* Definitions for Kinect data pack/unpack code.
|
3
|
+
* (C)2011 Mike Bourgeous
|
4
|
+
*/
|
5
|
+
#ifndef UNPACK_H_
|
6
|
+
#define UNPACK_H_
|
7
|
+
|
8
|
+
#include <stdint.h>
|
9
|
+
|
10
|
+
#ifndef UNPACK_INLINE
|
11
|
+
#define UNPACK_INLINE inline
|
12
|
+
#endif /* UNPACK_INLINE */
|
13
|
+
|
14
|
+
// assuming xmax~=3.797 and ymax~=2.848 when z ~= 7
|
15
|
+
// calculated as x=5*tan(28)/tan(35) and y=x*3/4
|
16
|
+
#define XPIX 500
|
17
|
+
#define YPIX 500
|
18
|
+
#define ZPIX 500
|
19
|
+
#define XMAX 7594 // Actually 2*xmax
|
20
|
+
#define YMAX 5696 // Actually 2*ymax
|
21
|
+
#define ZMAX 7000
|
22
|
+
#define PXZMAX 1092
|
23
|
+
|
24
|
+
|
25
|
+
// Depth look-up table (translates depth sample into world-space millimeters).
|
26
|
+
extern int ku_depth_lut[2048];
|
27
|
+
|
28
|
+
// Unpacks and inverts 8 11-bit pixels (11 bytes) from in and stores them as
|
29
|
+
// MSB-aligned 16-bit values in out (16 bytes)
|
30
|
+
UNPACK_INLINE void unpack11_to_16(const uint8_t *in, uint16_t *out)
|
31
|
+
{
|
32
|
+
out[0] = 65535 - (((in[0] << 3) | (in[1] >> 5)) << 5);
|
33
|
+
out[1] = 65535 - ((((in[1] & 0x1f) << 6) | (in[2] >> 2)) << 5);
|
34
|
+
out[2] = 65535 - ((((in[2] & 0x03) << 9) | (in[3] << 1) | (in[4] >> 7)) << 5);
|
35
|
+
out[3] = 65535 - ((((in[4] & 0x7f) << 4) | (in[5] >> 4)) << 5);
|
36
|
+
out[4] = 65535 - ((((in[5] & 0x0f) << 7) | (in[6] >> 1)) << 5);
|
37
|
+
out[5] = 65535 - ((((in[6] & 0x01) << 10) | (in[7] << 2) | (in[8] >> 6)) << 5);
|
38
|
+
out[6] = 65535 - ((((in[8] & 0x3f) << 5) | (in[9] >> 3)) << 5);
|
39
|
+
out[7] = 65535 - ((((in[9] & 0x07) << 8) | in[10]) << 5);
|
40
|
+
}
|
41
|
+
|
42
|
+
// Packs 8 LSB-aligned 11-in-16-bit pixels (16 bytes) into 11 output bytes
|
43
|
+
UNPACK_INLINE void pack16_to_11(const uint16_t *in, uint8_t *out)
|
44
|
+
{
|
45
|
+
out[0] = in[0] >> 3;
|
46
|
+
out[1] = ((in[0] & 0x07) << 5) | (in[1] >> 6);
|
47
|
+
out[2] = ((in[1] & 0x3f) << 2) | (in[2] >> 9);
|
48
|
+
out[3] = (in[2] & 0x1fe) >> 1;
|
49
|
+
out[4] = ((in[2] & 0x01) << 7) | (in[3] >> 4);
|
50
|
+
out[5] = ((in[3] & 0x0f) << 4) | (in[4] >> 7);
|
51
|
+
out[6] = ((in[4] & 0x7f) << 1) | (in[5] >> 10);
|
52
|
+
out[7] = (in[5] & 0x3fc) >> 2;
|
53
|
+
out[8] = ((in[5] & 0x03) << 6) | (in[6] >> 5);
|
54
|
+
out[9] = ((in[6] & 0x1f) << 3) | (in[7] >> 8);
|
55
|
+
out[10] = in[7] & 0xff;
|
56
|
+
}
|
57
|
+
|
58
|
+
// Unpacks 8 11-bit pixels (11 bytes) into 8 output bytes
|
59
|
+
UNPACK_INLINE void unpack11_to_8(const uint8_t *in, uint8_t *out)
|
60
|
+
{
|
61
|
+
uint16_t buf16[8];
|
62
|
+
int i;
|
63
|
+
|
64
|
+
unpack11_to_16(in, buf16);
|
65
|
+
for(i = 0; i < 8; i++) {
|
66
|
+
out[i] = buf16[i] >> 3;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
// Unpacks a single pixel into a right-aligned 16-bit value
|
71
|
+
UNPACK_INLINE int pxval_11(uint8_t *buf, int pixel)
|
72
|
+
{
|
73
|
+
uint32_t byteindex = (pixel * 11) >> 3;
|
74
|
+
uint32_t shiftbits = ((7 + pixel * 5) & 0x7) + 14;
|
75
|
+
uint32_t base;
|
76
|
+
|
77
|
+
buf = buf + byteindex;
|
78
|
+
base = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
79
|
+
|
80
|
+
return (base >> shiftbits) & 0x7ff;
|
81
|
+
}
|
82
|
+
|
83
|
+
// Initializes the depth look-up table.
|
84
|
+
// Copied from the knd daemon code, based on:
|
85
|
+
// http://groups.google.com/group/openkinect/browse_thread/thread/31351846fd33c78/e98a94ac605b9f21#e98a94ac605b9f21
|
86
|
+
void ku_init_lut();
|
87
|
+
|
88
|
+
// Finds the closest entry in the depth look-up table to the given world-space
|
89
|
+
// depth value in millimeters without going over. Uses a binary search.
|
90
|
+
int ku_reverse_lut(int zw);
|
91
|
+
|
92
|
+
// Plots a linear depth version of the given perspective image on the 8-bit
|
93
|
+
// output surface, which must be 640x480 bytes.
|
94
|
+
void plot_linear(const uint16_t *in, uint8_t *out);
|
95
|
+
|
96
|
+
// Plots an overhead view on the given raw linear 8-bit grayscale image
|
97
|
+
// surface, which must be XPIX bytes wide by ZPIX bytes tall.
|
98
|
+
void plot_overhead(const uint16_t *in, uint8_t *out);
|
99
|
+
|
100
|
+
// Plots a side view on the given raw linear 8-bit grayscale image surface,
|
101
|
+
// which must be ZPIX bytes wide by YPIX bytes tall.
|
102
|
+
void plot_side(const uint16_t *in, uint8_t *out);
|
103
|
+
|
104
|
+
// Plots a front view on the given raw linear 8-bit grayscale image surface,
|
105
|
+
// which must be XPIX bytes wide by YPIX bytes tall.
|
106
|
+
void plot_front(const uint16_t *in, uint8_t *out);
|
107
|
+
|
108
|
+
#endif /* UNPACK_H_ */
|
data/ext/overhead.c
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
/*
|
2
|
+
* Experimental Kinect depth image unpacking code.
|
3
|
+
* (C)2011 Mike Bourgeous
|
4
|
+
*/
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdint.h>
|
7
|
+
|
8
|
+
#include "unpack.h"
|
9
|
+
|
10
|
+
int main()
|
11
|
+
{
|
12
|
+
uint16_t in[640 * 480];
|
13
|
+
uint8_t out[XPIX * ZPIX];
|
14
|
+
|
15
|
+
if(fread(in, 2, 640 * 480, stdin) != 640 * 480) {
|
16
|
+
fprintf(stderr, "Must provide %d bytes of unpacked depth data to stdin.\n", 640 * 480 * 2);
|
17
|
+
}
|
18
|
+
|
19
|
+
ku_init_lut();
|
20
|
+
plot_overhead(in, out);
|
21
|
+
|
22
|
+
fwrite(out, 1, XPIX * ZPIX, stdout);
|
23
|
+
|
24
|
+
return 0;
|
25
|
+
}
|
26
|
+
|
data/ext/overhead_grid.c
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
/*
|
2
|
+
* Code to render a basic grid for the overhead view, for later manipulation.
|
3
|
+
* The final grid will be created from this program's output using the GIMP.
|
4
|
+
* (C)2012 Mike Bourgeous
|
5
|
+
*/
|
6
|
+
#include <stdio.h>
|
7
|
+
#include <stdint.h>
|
8
|
+
#include <string.h>
|
9
|
+
|
10
|
+
#include "unpack.h"
|
11
|
+
|
12
|
+
void draw_grid(uint8_t *grid, uint8_t color, int spacing)
|
13
|
+
{
|
14
|
+
int x, z;
|
15
|
+
|
16
|
+
// Loop through x in world space, z in pixels
|
17
|
+
for(x = 0; x < XMAX / 2; x += spacing) {
|
18
|
+
for(z = 0; z < ZPIX; z++) {
|
19
|
+
grid[x * XPIX / XMAX + XPIX / 2 + z * XPIX] = color;
|
20
|
+
grid[XPIX / 2 - (x * XPIX / XMAX) + z * XPIX] = color;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
// Loop through z in world space, x in pixels
|
25
|
+
for(z = 0; z < ZMAX; z += spacing) {
|
26
|
+
for(x = 0; x < XPIX; x++) {
|
27
|
+
grid[x + z * ZPIX / ZMAX * XPIX] = color;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
int main()
|
33
|
+
{
|
34
|
+
uint8_t out[XPIX * ZPIX];
|
35
|
+
|
36
|
+
memset(out, 0, sizeof(out));
|
37
|
+
draw_grid(out, 128, 500);
|
38
|
+
draw_grid(out, 255, 1000);
|
39
|
+
fwrite(out, 1, sizeof(out), stdout);
|
40
|
+
|
41
|
+
return 0;
|
42
|
+
}
|
data/ext/side.c
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
/*
|
2
|
+
* Experimental Kinect depth image unpacking code.
|
3
|
+
* (C)2011 Mike Bourgeous
|
4
|
+
*/
|
5
|
+
#include <stdio.h>
|
6
|
+
#include <stdint.h>
|
7
|
+
|
8
|
+
#include "unpack.h"
|
9
|
+
|
10
|
+
int main()
|
11
|
+
{
|
12
|
+
uint16_t in[640 * 480];
|
13
|
+
uint8_t out[ZPIX * YPIX];
|
14
|
+
|
15
|
+
if(fread(in, 2, 640 * 480, stdin) != 640 * 480) {
|
16
|
+
fprintf(stderr, "Must provide %d bytes of unpacked depth data to stdin.\n", 640 * 480 * 2);
|
17
|
+
}
|
18
|
+
|
19
|
+
ku_init_lut();
|
20
|
+
plot_side(in, out);
|
21
|
+
|
22
|
+
fwrite(out, 1, sizeof(out), stdout);
|
23
|
+
|
24
|
+
return 0;
|
25
|
+
}
|
26
|
+
|
data/ext/side_grid.c
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
/*
|
2
|
+
* Code to render a basic grid for the side view, for later manipulation.
|
3
|
+
* The final grid will be created from this program's output using the GIMP.
|
4
|
+
* (C)2012 Mike Bourgeous
|
5
|
+
*/
|
6
|
+
#include <stdio.h>
|
7
|
+
#include <stdint.h>
|
8
|
+
#include <string.h>
|
9
|
+
|
10
|
+
#include "unpack.h"
|
11
|
+
|
12
|
+
void draw_grid(uint8_t *grid, uint8_t color, int spacing)
|
13
|
+
{
|
14
|
+
int y, z;
|
15
|
+
|
16
|
+
// Loop through y in world space, z in piyels
|
17
|
+
for(y = 0; y < YMAX / 2; y += spacing) {
|
18
|
+
for(z = 0; z < ZPIX; z++) {
|
19
|
+
grid[y * YPIX / YMAX * ZPIX + YPIX / 2 * ZPIX + z] = color;
|
20
|
+
grid[YPIX / 2 * ZPIX - (y * YPIX / YMAX * ZPIX) + z] = color;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
// Loop through z in world space, y in piyels
|
25
|
+
for(z = 0; z < ZMAX; z += spacing) {
|
26
|
+
for(y = 0; y < YPIX; y++) {
|
27
|
+
grid[y * ZPIX + z * ZPIX / ZMAX] = color;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
int main()
|
33
|
+
{
|
34
|
+
uint8_t out[YPIX * ZPIX];
|
35
|
+
|
36
|
+
memset(out, 0, sizeof(out));
|
37
|
+
draw_grid(out, 128, 500);
|
38
|
+
draw_grid(out, 255, 1000);
|
39
|
+
fwrite(out, 1, sizeof(out), stdout);
|
40
|
+
|
41
|
+
return 0;
|
42
|
+
}
|