stew

a monorepo of some sort
Log | Files | Refs

commit 0f91019ec56fe855be84fdd8905550fee74d4cde
parent 200b8e120f87b0e8c110d15078bc145ea3f2bc3e
Author: glenda <glenda@device>
Date:   Sun,  6 Nov 2022 21:58:16 +0000

cubes: render ⅙-th of a cube

Diffstat:
Msrc/cubes/cubes.c | 258+++++++++++++++++++++++++++----------------------------------------------------
1 file changed, 88 insertions(+), 170 deletions(-)

diff --git a/src/cubes/cubes.c b/src/cubes/cubes.c @@ -4,139 +4,113 @@ #include <event.h> #include <geometry.h> -#define OTSize (64 * 64 * 64) +/* + * given 640 resolution and 80 digrees FoV, + * single pixel will be 0.125 digrees wide. + * 360/.125 = 2880 - amount of pixels needed + * for full circle. + * Small enough amount to precompute all possible + * angles for every possible direction + */ -#define QTSize (64 * 64) +#define OTSize (64 * 64 * 64) #define CSWidth 640 #define CSHeight 640 #define CSSize (CSWidth * CSHeight) -typedef struct Cube Cube; -typedef struct Vect Vect; -struct Cube { - Point3 min; Point3 max; -}; - -struct Vect { - Point3 pos; Point3 dir; -}; - -typedef union Quad Quad; - -union Quad { - s32int p[4]; - struct { - s32int tl; - s32int tr; - s32int bl; - s32int br; - }; -}; - u32int otree[OTSize]; u32int imgbuf[CSSize]; -Quad qtree[QTSize]; +Image *img; +vlong n; +char *s; -Cube cube; -Vect view; +typedef struct Raydef Raydef; +struct Raydef { + double O[3]; + double D[3]; +}; -void -qtinit(void) -{ - s32int data[] = { - 0x00000001, 0x00000000, 0x00000000, 0x00000002, - 0x00000000, 0x00000002, 0x00000000, 0x00000002, - 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff00ffff, - }; - memcpy(qtree, data, sizeof(data)); -} +typedef struct Boxdef Boxdef; +struct Boxdef { + double min[3]; + double max[3]; +}; -s32int -getqt(double X, double Y) -{ - unsigned int i = 0; - for (; i < sizeof(qtree);) { - Quad q = qtree[i]; - s32int r = q.p[(X > 0) | ((Y > 0) << 1)]; - if (r <= 0) return r; - double DX, DY; - DX = (X > 0) ? -1 : 1; - DY = (Y > 0) ? -1 : 1; - - X = X * 2 + DX; - Y = Y * 2 + DY; - i = r; - } - return 0; -} +Boxdef box = {{0,0,0}, {1,1,1}}; +Raydef view = {{10,20,30}, {-1,-2,-3}}; -void -otinit(void) +Raydef +raynorm(Raydef r) { - int i, x,y,z; - double X,Y,Z; - for (i = 0; i < OTSize; i++) { - x = i % 64; - y = (i / 64) % 64; - z = i / 64 / 64; - X = -1 + (double)x / 32; - Y = -1 + (double)y / 32; - Z = -1 + (double)z / 32; - - if ((X*X + Y*Y + Z*Z) < 1) { - otree[i] = 0xffff0000; - } else { - otree[i] = 0x00000000; - } + double d = r.D[0] * r.D[0] + r.D[1] * r.D[1] + r.D[2] * r.D[2]; + if (d != 0) { + r.D[0] /= d; + r.D[1] /= d; + r.D[2] /= d; } + return r; } -void -initscene(void) -{ - otinit(); - qtinit(); - cube = (Cube){ - (Point3){-1, -1, -1, 1}, - (Point3){ 1, 1, 1, 1}, - }; - view = (Vect){ - (Point3){10, 20, 30, 1}, - (Point3){0, 0, 0, 1}, - }; -} - -int m[3][3]; -Point pts[3]; -Image *img; -vlong n; -char *s; - -void -triangle(int i) +/* + * Ray is O + Dt, where O is origin and D is direction + * Box is defined by 2 boundary points, M, N (min and max) + * which translates into 6 planes: + * x = Nx; x = Mx; y = Ny; y = My; z = Nz; z = Mz + * Intersections of ray and planes: + * Tn = (Bn - On)/Dn; where B (as in boundary) is either M or N, + * and n stands for axis (x,y,z) + * (beware division by zero!) + * + */ + +Raydef +intersectY(Raydef ray, double Y) { - int X = i % CSWidth; - int Y = i / CSWidth; - - #define l(m) (m[0] * X + m[1] * Y + m[2]) - #define istriag ((l(m[0]) > 0) && (l(m[1]) > 0) && (l(m[2]) > 0)) - #define isline ((l(m[0]) <= 10) || (l(m[1]) <= 10) || (l(m[2]) <= 10)) - - imgbuf[i] = istriag ? 0x00ff7f00 : (imgbuf[i] / 2) &0xffff0000; - - - #undef l - #undef istriag - #undef isline + Raydef ref; + double t; + if (ray.D[1] >= Y) { + Raydef ret = { + {Inf(ray.D[0]), Inf(ray.D[1]), Inf(ray.D[2])}, + {ray.D[0], ray.D[1], ray.D[2]}, + }; + return ret; + } + t = (Y-ray.O[1]) / ray.D[1]; + ref.O[0] = ray.O[0] + ray.D[0] * t; + ref.O[1] = Y; + ref.O[2] = ray.O[2] + ray.D[2] * t; + ref.D[0] = ray.D[0]; + ref.D[1] = -ray.D[1]; + ref.D[2] = ray.D[2]; + return ref; } void vrender(void) { - int i; - for (i = 0; i < CSSize; i++) triangle(i); + int i, x, y; + double X, Y; + for (i = 0, y = 0; y < CSHeight; y++) { + Y = (double)(y) / CSHeight; + for (x = 0; x < CSWidth; x++, i++) { + X = (double)(x) / CSWidth; + // TODO: generate camera ray properly + Raydef r = { + .O {0, 0, 0}, + .D {-1 + X * 2, 1 - Y * 2, 2} + }; + r = intersectY(r, 0); + + if (isInf(r.O[0], 0) != 0) imgbuf[i] = 0x004f7fff; + else { + double d = sqrt((r.D[1] * r.D[1]) / (r.D[0] * r.D[0] + r.D[2] * r.D[2])); + int br = 0xff * d; + imgbuf[i] = (br << 16) + (br << 8) + (br); + } + } + } } void @@ -145,12 +119,6 @@ redraw(Image *) draw(screen, screen->r, display->white, nil, ZP); draw(screen, screen->r, img, nil, ZP); - //Point dp = screen->r.min; - - //line(screen, addpt(dp, pts[0]), addpt(dp, pts[1]), 0, 0, 0, display->white, ZP); - //line(screen, addpt(dp, pts[1]), addpt(dp, pts[2]), 0, 0, 0, display->white, ZP); - //line(screen, addpt(dp, pts[2]), addpt(dp, pts[0]), 0, 0, 0, display->white, ZP); - string(screen, screen->r.min, display->white, ZP, font, s); } @@ -163,78 +131,28 @@ eresized(int new) } void -randomize_pts(void) -{ - pts[0] = Pt(nrand(640), nrand(640)); - pts[1] = Pt(nrand(640), nrand(640)); - pts[2] = Pt(nrand(640), nrand(640)); -} - -void -pts2linear(void) -{ -#define lconv(m, u, w) \ - m[0] = w.y - u.y, \ - m[1] = u.x - w.x, \ - m[2] = - m[0] * u.x - m[1] * u.y - - lconv(m[0], pts[0], pts[1]); - lconv(m[1], pts[1], pts[2]); - lconv(m[2], pts[2], pts[0]); - -#undef lconv -} - -void -normalize(void) -{ -#define l(m, u) (m[0] * u.x + m[1] * u.y + m[2]) -#define invert(m) m[0] = -m[0], m[1] = -m[1], m[2] = -m[2]; - - if (l(m[0], pts[2]) < 0) invert(m[0]); - if (l(m[1], pts[0]) < 0) invert(m[1]); - if (l(m[2], pts[1]) < 0) invert(m[2]); - -#undef l -#undef invert -} - - -void main(void) { - + view = raynorm(view); srand(nsec()); - - initscene(); - n = nsec(); - vrender(); - n = nsec() - n; s = smprint("render time %lld nsec", n); initdraw(nil, 0, "cubes"); img = allocimage(display, Rect(0, 0, CSWidth, CSHeight), XRGB32, 0, DRed); - randomize_pts(); - pts2linear(); - normalize(); n = nsec(); vrender(); n = nsec() - n; - loadimage(img, img->r, (uchar *)imgbuf, CSSize * 4); s = smprint("render time %lld nsec", n); + loadimage(img, img->r, (uchar *)imgbuf, CSSize * 4); redraw(img); Event e; einit(Emouse); - int timer = etimer(0, 125); + int timer = etimer(0, 500); for(;;) { int key = event(&e); if (key == timer) { - - randomize_pts(); - pts2linear(); - normalize(); n = nsec(); vrender(); n = nsec() - n; - loadimage(img, img->r, (uchar *)imgbuf, CSSize * 4); free(s); s = smprint("render time %lld nsec", n); + loadimage(img, img->r, (uchar *)imgbuf, CSSize * 4); redraw(img); } }