octree

octree tools and accessories
git clone git://nsmpr.xyz/octree.git
Log | Files | Refs

render.c (2219B)


      1 #include <u.h>
      2 #include <libc.h>
      3 
      4 #include "render.h"
      5 
      6 #define BSIZE 512
      7 #define SQR(X) (X * X)
      8 
      9 double
     10 vectmod(Vect d)
     11 {
     12 	return sqrt(SQR(d.x) + SQR(d.y) + SQR(d.z));
     13 }
     14 
     15 Vect
     16 vectnorm(Vect d)
     17 {
     18 	double m;
     19 	m = vectmod(d);
     20 	return (Vect){d.x/m, d.y/m, d.z/m};
     21 }
     22 
     23 Vect
     24 vectxvect(Vect d1, Vect d2)
     25 {
     26 	return (Vect){d1.x * d2.x, d1.y * d2.y, d1.z * d2.z};
     27 }
     28 
     29 
     30 Vect
     31 addvect(Vect d1, Vect d2)
     32 {
     33 	return (Vect){d1.x + d2.x, d1.y + d2.y, d1.z + d2.z};
     34 }
     35 
     36 Vect
     37 subvect(Vect d1, Vect d2)
     38 {
     39 	return addvect(d1, (Vect){-d2.x, -d2.y, -d2.z});
     40 }
     41 
     42 Vect
     43 todecart(Vect v)
     44 {
     45 	/* TODO: recheck this code, it's probably wrong.
     46 	 * hypot specifically.
     47 	 */
     48 	return (Vect) {
     49 		v.z * sin(v.x),
     50 		v.z * sin(v.y),
     51 		hypot(v.z * cos(v.y), v.z * cos(v.x)),
     52 	};
     53 }
     54 
     55 double
     56 vectscalar(Vect d1, Vect d2)
     57 {
     58 	return d1.x * d2.x + d1.y * d2.y + d1.z * d2.z;
     59 }
     60 
     61 int
     62 spherehit(Ray *v, Sphere s)
     63 {
     64 	double d, old;
     65 	int i;
     66 	old = Inf(1);
     67 	for (i = 0; i < 1024; i++) {
     68 		d = vectmod(subvect(v->pos, s.pos)) - s.radius;
     69 		v->pos = addvect(v->pos,
     70 			vectxvect(vectnorm(v->dir), (Vect){d, d, d}));
     71 		if (d < 0.001) {
     72 			v->dir = subvect(s.pos, v->pos);
     73 			return 1;
     74 		}
     75 		if (d > old) return 0;
     76 		old = d;
     77 	}
     78 	return 0;
     79 }
     80 
     81 Vect
     82 ray(Ray v)
     83 {
     84 	Vect vv;
     85 	vv = v.pos;
     86 	Sphere sphere = {{0, 0, }, 1};
     87 	Vect light = vectnorm((Vect){10, -10, 10});
     88 	Vect p = Pblack;
     89 	if (spherehit(&v, sphere)) {
     90 		double f;
     91 		Vect r;
     92 		r = vectnorm(v.dir);
     93 		f = vectscalar(r, light)/(vectmod(light)*vectmod(r));
     94 		if (f < 0) f = 0;
     95 		p = (Vect){f, f, f};
     96 	}
     97 	return p;
     98 }
     99 
    100 u32int
    101 render(int x, int y)
    102 {
    103 	double fov;
    104 	Vect p;
    105 	u32int r, g, b;
    106 	Ray v;
    107 	fov = PI/2;
    108 	v.pos = (Vect) { 0, 0, -3 };
    109 	v.dir = todecart((Vect) {
    110 		fov*((double)x/BSIZE - 0.5),
    111 		fov*((double)y/BSIZE - 0.5),
    112 		1});
    113 	p = ray(v);
    114 	r = (u32int)(0xff * p.x)&0xff;
    115 	g = (u32int)(0xff * p.y)&0xff;
    116 	b = (u32int)(0xff * p.z)&0xff;
    117 	return (r<<16)|(g<<8)|b;
    118 }
    119 
    120 void
    121 main(void)
    122 {
    123 	int i, x, y;
    124 	u32int buf[SQR(BSIZE)];
    125 	write(1, "   x8r8g8b8 ", 12);
    126 	write(1, "          0 ", 12);
    127 	write(1, "          0 ", 12);
    128 	fprint(1, "%11d ", BSIZE);
    129 	fprint(1, "%11d ", BSIZE);
    130 	for (i = 0; i < SQR(BSIZE); i++) {
    131 		x = i%BSIZE;
    132 		y = BSIZE-(i/BSIZE);
    133 		buf[i] = render(x, y);
    134 	}
    135 	write(1, buf, 4 * SQR(BSIZE));
    136 	exits(nil);
    137 }