commit f4d69b664ce946b8e4f1f904bcfc6ea0d4aa7607 Author: cannoli-fruit Date: Tue Jun 30 01:43:59 2026 -0400 init diff --git a/bldit.lua b/bldit.lua new file mode 100644 index 0000000..9f128bf --- /dev/null +++ b/bldit.lua @@ -0,0 +1,57 @@ +bldit_version = "1.1.3" +package_version = "1.1.3" + +dependencies = {} + +exec_name = "ray" + +targets = { + default = { + build = function() + e,h,c = os.execute("rm -fr build") + if c ~= 0 and c ~= nil then + print("Build Error") + print("GIVEN UP") + return c + end + e,h,c = os.execute("mkdir build") + if c ~= 0 and c ~= nil then + print("Build Error") + print("GIVEN UP") + return c + end + cmd = [[find src -type f -name "*.c" -print]] + p = io.popen(cmd) + assert(p, "File detection error, GIVEN UP") + + for f in p:lines() do + base = f:match("([^/]+)%.c$") + obj = "build/"..base..".o" + cc = "cc -c '"..f.."' -o '"..obj.."'" + e,h,c = os.execute(cc) + if c ~= 0 and c ~= nil then + print("Compilation Error") + print("GIVEN UP") + return c + end + end + p:close() + libs = "-lm" + e,h,c = os.execute("cc build/*.o "..libs.." -o "..exec_name) + if c ~= 0 and c ~= nil then + print("Compilation Error") + print("GIVEN UP") + return c + end + return 0 + end, + install = function() + e,h,c = os.execute("cp "..exec_name.." /bin") + return c or 0 + end, + uninstall = function() + e,h,c = os.execute("rm /bin"..exec_name) + return c or 0 + end, + } +} diff --git a/bldit.lua~ b/bldit.lua~ new file mode 100644 index 0000000..b44af2e --- /dev/null +++ b/bldit.lua~ @@ -0,0 +1,56 @@ +bldit_version = "1.1.3" +package_version = "1.1.3" + +dependencies = {} + +exec_name = "ray" + +targets = { + default = { + build = function() + e,h,c = os.execute("rm -fr build") + if c ~= 0 and c ~= nil then + print("Build Error") + print("GIVEN UP") + return c + end + e,h,c = os.execute("mkdir build") + if c ~= 0 and c ~= nil then + print("Build Error") + print("GIVEN UP") + return c + end + cmd = [[find src -type f -name "*.c" -print]] + p = io.popen(cmd) + assert(p, "File detection error, GIVEN UP") + + for f in p:lines() do + base = f:match("([^/]+)%.c$") + obj = "build/"..base..".o" + cc = "cc -c '"..f.."' -o '"..obj.."'" + e,h,c = os.execute(cc) + if c ~= 0 and c ~= nil then + print("Compilation Error") + print("GIVEN UP") + return c + end + end + p:close() + e,h,c = os.execute("cc build/*.o -o "..exec_name) + if c ~= 0 and c ~= nil then + print("Compilation Error") + print("GIVEN UP") + return c + end + return 0 + end, + install = function() + e,h,c = os.execute("cp "..exec_name.." /bin") + return c or 0 + end, + uninstall = function() + e,h,c = os.execute("rm /bin"..exec_name) + return c or 0 + end, + } +} diff --git a/build/main.o b/build/main.o new file mode 100644 index 0000000..3221d2a Binary files /dev/null and b/build/main.o differ diff --git a/image.ppm b/image.ppm new file mode 100644 index 0000000..9ec4dea Binary files /dev/null and b/image.ppm differ diff --git a/main.o b/main.o new file mode 100644 index 0000000..954f6cb Binary files /dev/null and b/main.o differ diff --git a/pkgit.lua b/pkgit.lua new file mode 100644 index 0000000..0d5e1f4 --- /dev/null +++ b/pkgit.lua @@ -0,0 +1,26 @@ +repositories["pkgit"] = { + url = "https://git.symlinx.net/pkgit", + + targets = { + default = { + build = function() + e,h,c = os.execute("make") + if c ~= 0 then + print("Compilation Error: ", c, type(c)) + print("GIVEN UP") + return c + end + return 0 + end, + install = function() + e,h,c = os.execute("make install PREFIX="..prefix) + return c or 0 + end, + uninstall = function() + e,h,c = os.execute("make uninstall PREFIX="..prefix) + return c or 0 + end, + } + } +} + diff --git a/ray b/ray new file mode 100755 index 0000000..33c2baa Binary files /dev/null and b/ray differ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..42bce11 --- /dev/null +++ b/src/main.c @@ -0,0 +1,349 @@ +#include +#include +#include +#include + +typedef struct { + float x; + float y; + float z; +} Vec3; + +typedef struct { + float refl; + float brightness; + Vec3 col; +} Material; + +typedef struct { + Vec3 p0; + Vec3 p1; + Vec3 p2; + Material mat; +} Triangle; + +typedef struct { + Vec3 o; + Vec3 d; +} Ray; + +typedef struct { + Vec3 p; + Vec3 normal; + int intersected; + float t; + Material mat; +} Collision; + +Vec3 vec3_sub(Vec3 *a, Vec3 *b) { + return (Vec3){ + .x = a->x - b->x, + .y = a->y - b->y, + .z = a->z - b->z, + }; +} + +Vec3 vec3_add(Vec3 *a, Vec3 *b) { + return (Vec3){ + .x = a->x + b->x, + .y = a->y + b->y, + .z = a->z + b->z, + }; +} + +Vec3 vec3_hadamard(Vec3 *a, Vec3 *b) { + return (Vec3){ + .x = a->x * b->x, + .y = a->y * b->y, + .z = a->z * b->z, + }; +} + +Vec3 vec3_scale(float x, Vec3 *v) { + return (Vec3){.x = v->x * x, .y = v->y * x, .z = v->z * x}; +} + +Vec3 vec3_cross(Vec3 *a, Vec3 *b) { + return (Vec3){.x = a->y * b->z - a->z * b->y, + .y = a->z * b->x - a->x * b->z, + .z = a->x * b->y - a->y * b->x}; +} + +float vec3_mag(Vec3 *a) { + return sqrt(a->x * a->x + a->y * a->y + a->z * a->z); +} + +Vec3 vec3_norm(Vec3 *a) { return vec3_scale(1 / vec3_mag(a), a); } + +float vec3_dot(Vec3 *a, Vec3 *b) { + return a->x * b->x + a->y * b->y + a->z * b->z; +} + +float clamp(float x, float min, float max) { + if (x < min) + return min; + if (x > max) + return max; + return x; +} + +Vec3 clamp_col(Vec3 *c) { + return (Vec3){ + .x = pow(clamp(c->x, 0, 1), 1 / 1.8), + .y = pow(clamp(c->y, 0, 1), 1 / 1.8), + .z = pow(clamp(c->z, 0, 1), 1 / 1.8), + }; +} + +Collision intersect(Ray *r, Triangle *tr) { + Vec3 e1 = vec3_sub(&tr->p1, &tr->p0); + Vec3 e2 = vec3_sub(&tr->p2, &tr->p0); + + Vec3 pvec = vec3_cross(&r->d, &e2); + float det = vec3_dot(&e1, &pvec); + + if (fabs(det) < 0.01) + return (Collision){0}; + + float invdet = 1.0 / det; + + Vec3 tvec = vec3_sub(&r->o, &tr->p0); + float u = vec3_dot(&pvec, &tvec) * invdet; + if (u < 0.0 || u > 1.0) + return (Collision){0}; + + Vec3 qvec = vec3_cross(&tvec, &e1); + float v = vec3_dot(&r->d, &qvec) * invdet; + if (v < 0.0 || (u + v) > 1.0) + return (Collision){0}; + + float t = vec3_dot(&e2, &qvec) * invdet; + if (t < 0.0) + return (Collision){0}; + + Vec3 td = vec3_scale(t, &r->d); + Vec3 x = vec3_add(&td, &r->o); + + Vec3 norm = vec3_cross(&e1, &e2); + norm = vec3_norm(&norm); + + if (vec3_dot(&norm, &r->d) > 0.0) + norm = vec3_scale(-1.0f, &norm); + + return (Collision){.p = x, // + .normal = norm, + .t = t, + .intersected = 1, + .mat = tr->mat}; +} + +Collision intersectScene(Ray *r, Triangle *scene, size_t tricnt) { + Collision closestCollision = {0}; + for (int i = 0; i < tricnt; ++i) { + Collision c = intersect(r, &scene[i]); + if (c.intersected) { + if (!closestCollision.intersected) { + closestCollision = c; + } + if (c.t < closestCollision.t) { + closestCollision = c; + } + } + } + return closestCollision; +} + +float randfloat() { return (float)rand() / 4294967296; } + +Vec3 shade(Collision *c, Ray *r, size_t depth, Triangle *scene, size_t tricnt) { + if (!c->intersected) { + return (Vec3){.x = 0.0f, .y = 0.0f, .z = 0.0f}; + } + Vec3 col = (Vec3){.x = 0.0f, .y = 0.0f, .z = 0.0f}; + + Vec3 amb = vec3_scale(0.1, &c->mat.col); + col = vec3_add(&col, &amb); + + for (int i = 0; i < 1; ++i) { // Assume only 1 light at 10,10,-2 for now + Vec3 light = (Vec3){.x = 10, .y = -10, .z = -2}; + Vec3 lightColor = (Vec3){.x = 1, .y = 1, .z = 1}; + float lightStrength = 0.5; + + Vec3 toLight = vec3_sub(&light, &c->p); + float lightDist = vec3_mag(&toLight); + toLight = vec3_norm(&toLight); + Vec3 offset = vec3_scale(0.01, &c->normal); + Ray shadow = (Ray){.o = vec3_add(&c->p, &offset), .d = toLight}; + Collision shadowC = intersectScene(&shadow, scene, tricnt); + int inShadow = + shadowC.intersected && shadowC.t < lightDist && shadowC.t > 0.1; + if (!inShadow) { + float diff = vec3_dot(&c->normal, &toLight); + if (diff < 0.0) + diff = 0.0; + Vec3 lightContr = vec3_scale(lightStrength * diff, &lightColor); + Vec3 hitColor = vec3_hadamard(&lightContr, &c->mat.col); + Vec3 colNoise = (Vec3){ + .x = randfloat() * 0.08, + .y = randfloat() * 0.08, + .z = randfloat() * 0.08, + }; + col = vec3_add(&col, &hitColor); + col = vec3_add(&col, &colNoise); + } + } + return col; +} + +Vec3 trace(Ray *r, Triangle *scene, size_t tricnt, size_t depth) { + Collision c = intersectScene(r, scene, tricnt); + Vec3 rawcol = shade(&c, r, depth, scene, tricnt); + return clamp_col(&rawcol); +} + +void addQuad(Triangle *scene, size_t *tricnt, Vec3 *col, Vec3 p1, Vec3 p2, + Vec3 p3, Vec3 p4) { + scene[(*tricnt)++] = (Triangle){.p0 = p1, + .p1 = p2, + .p2 = p3, // + .mat = (Material){ + .refl = 0.7, + .brightness = 0.7, + .col = *col, + }}; + scene[(*tricnt)++] = (Triangle){.p0 = p2, + .p1 = p4, + .p2 = p3, // + .mat = (Material){ + .refl = 0.7, + .brightness = 0.7, + .col = *col, + }}; +} + +void addBeam(Triangle *scene, size_t *tricnt, Vec3 *col, float x, float y, + float z, float w, float l, float d) { + Vec3 c1 = (Vec3){.x = x, .y = y, .z = z}; + Vec3 c2 = (Vec3){.x = x + w, .y = y, .z = z}; + Vec3 c3 = (Vec3){.x = x, .y = y + l, .z = z}; + Vec3 c4 = (Vec3){.x = x + w, .y = y + l, .z = z}; + + Vec3 c5 = (Vec3){.x = x, .y = y, .z = z + d}; + Vec3 c6 = (Vec3){.x = x + w, .y = y, .z = z + d}; + Vec3 c7 = (Vec3){.x = x, .y = y + l, .z = z + d}; + Vec3 c8 = (Vec3){.x = x + w, .y = y + l, .z = z + d}; + + addQuad(scene, tricnt, col, c1, c2, c3, c4); + addQuad(scene, tricnt, col, c5, c6, c7, c8); + addQuad(scene, tricnt, col, c1, c3, c5, c7); + addQuad(scene, tricnt, col, c2, c4, c6, c8); + addQuad(scene, tricnt, col, c1, c2, c5, c6); + addQuad(scene, tricnt, col, c3, c4, c7, c8); +} + +Vec3 rotateX(Vec3 *v, float angle) { + float c = cosf(angle); + float s = sinf(angle); + + return (Vec3){.x = v->x, .y = c * v->y - s * v->z, .z = s * v->y + c * v->z}; +} +Vec3 rotateY(Vec3 *v, float angle) { + float c = cosf(angle); + float s = sinf(angle); + + return (Vec3){.x = c * v->x - s * v->z, .y = v->y, .z = s * v->x + c * v->z}; +} + +int main() { + printf("Hello World!\n"); + + size_t W = 640; + size_t H = 480; + + FILE *f = fopen("image.ppm", "wb"); + fprintf(f, "P6\n"); + fprintf(f, "%d %d\n", W, H); + fprintf(f, "255\n", W, H); + + size_t tricnt = 0; + Triangle *scene = malloc(128 * sizeof(Triangle)); + Vec3 red = (Vec3){.x = 0.8, .y = 0.2, .z = 0.2}; + Vec3 green = (Vec3){.x = 0.2, .y = 0.8, .z = 0.2}; + Vec3 blue = (Vec3){.x = 0.2, .y = 0.2, .z = 0.8}; + float bx = 111; + float by = 113; + float bz = 84; + float l = 16; + float g = 2; + addBeam(scene, &tricnt, &red, bx, by, bz, g, l, g); + addBeam(scene, &tricnt, &green, bx + g, by + l - g, bz, g, g, l); + addBeam(scene, &tricnt, &blue, bx + g, by + l, bz + l - g, l, g, g); + + /* Chessboard + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + float lx = i - 4; + float rx = i - 3; + float cz = j + 4; + float fz = j + 5; + float y = -3; + + Vec3 col = {0}; + if ((i + j) & 1) { + col.x = 138.0 / 255.0; + col.y = 95.0 / 255.0; + col.z = 45.0 / 255.0; + } else { + col.x = 252.0 / 255.0; + col.y = 180.0 / 255.0; + col.z = 93.0 / 255.0; + } + + scene[2 * (i + j * 8) + 0] = (Triangle){ + .p0 = (Vec3){.x = lx, .y = y, .z = cz}, // + .p1 = (Vec3){.x = rx, .y = y, .z = cz}, // + .p2 = (Vec3){.x = rx, .y = y, .z = fz}, // + .mat = (Material){.refl = 0.7, .brightness = 0.7, .col = col}}; + scene[2 * (i + j * 8) + 1] = (Triangle){ + .p0 = (Vec3){.x = rx, .y = y, .z = fz}, // + .p1 = (Vec3){.x = lx, .y = y, .z = fz}, // + .p2 = (Vec3){.x = lx, .y = y, .z = cz}, // + .mat = (Material){.refl = 0.7, .brightness = 0.7, .col = col}}; + } + } + */ + + float aspect = (float)W / (float)H; + for (int j = 0; j < H; ++j) { + for (int i = 0; i < W; ++i) { + Vec3 camOrigin = (Vec3){.x = 0, .y = 0, .z = 0}; + + float u = (2.0f * (i + 0.5f) / W - 1.0f) * aspect; + float v = 1.0f - 2.0f * (j + 0.5f) / H; + + float zoom = 8; + u /= zoom; + v /= zoom; + + float rconst = 0.00; + float ur = (randfloat() - 0.5) * rconst; + u += ur; + + float vr = (randfloat() - 0.5) * rconst * 0.75; + v += vr; + + Vec3 camDir = (Vec3){.x = u, .y = v, .z = 1.0}; + camDir = rotateX(&camDir, -0.76); + camDir = rotateY(&camDir, -0.78539); + camDir = vec3_norm(&camDir); + Ray camray = (Ray){.o = camOrigin, .d = camDir}; + Vec3 col = trace(&camray, scene, tricnt, 4); + uint8_t quant = 0xD0; + fputc((uint8_t)(0xFF * col.x) & quant, f); + fputc((uint8_t)(0xFF * col.y) & quant, f); + fputc((uint8_t)(0xFF * col.z) & quant, f); + } + } + + return 0; +} diff --git a/src/main.c~ b/src/main.c~ new file mode 100644 index 0000000..dafadc7 --- /dev/null +++ b/src/main.c~ @@ -0,0 +1,6 @@ +#include + +int main() { + printf("Hello World!\n"); + return 0; +}