rotation
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 16 Oct 2022 02:33:01 +0000 (05:33 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 16 Oct 2022 02:33:01 +0000 (05:33 +0300)
Makefile
src/lut.c [new file with mode: 0644]
src/lut.h [new file with mode: 0644]
src/main.c
src/voxscape.c

index 2859bb3..40100fc 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,8 +6,9 @@ bin = voxscape
 warn = -pedantic -Wall
 #opt = -O3
 dbg = -g
+incdir = -I.
 
-CFLAGS = $(warn) $(opt) $(dbg) -MMD
+CFLAGS = $(warn) $(opt) $(dbg) -MMD $(incdir)
 LDFLAGS = -lGL -lglut -lm -limago
 
 $(bin): $(obj)
diff --git a/src/lut.c b/src/lut.c
new file mode 100644 (file)
index 0000000..895d84f
--- /dev/null
+++ b/src/lut.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <math.h>
+#include "lut.h"
+
+/*#include "sintab.h"*/
+
+#undef WRITE_C
+
+#ifndef SINTAB_DATA_H_
+int32_t sintab[SINTAB_SIZE];
+#endif
+
+void init_lut(void)
+{
+#ifndef SINTAB_DATA_H_
+       int i;
+       float t, theta;
+
+#ifdef WRITE_C
+       int col = 4;
+       FILE *fp = fopen("sintab.h", "wb");
+       if(fp) {
+               fprintf(fp, "#ifndef SINTAB_DATA_H_\n");
+               fprintf(fp, "#define SINTAB_DATA_H_\n\n");
+               fprintf(fp, "int32_t sintab[] = {\n\t");
+       }
+#endif
+
+       for(i=0; i<SINTAB_SIZE; i++) {
+               t = (float)i / SINTAB_SIZE;
+               theta = t * (M_PI * 2);
+               sintab[i] = (int32_t)(sin(theta) * 65536.0f);
+#ifdef WRITE_C
+               if(fp) {
+                       col += fprintf(fp, "%ld", (long)sintab[i]);
+                       if(i < SINTAB_SIZE - 1) {
+                               if(col >= 72) {
+                                       fprintf(fp, ",\n\t");
+                                       col = 4;
+                               } else {
+                                       col += fprintf(fp, ", ");
+                               }
+                       } else {
+                               fprintf(fp, "\n");
+                       }
+               }
+#endif
+       }
+
+#ifdef WRITE_C
+       if(fp) {
+               fprintf(fp, "};\n\n");
+               fprintf(fp, "#endif\t/* SINTAB_DATA_H_ */\n");
+               fclose(fp);
+       }
+#endif
+#endif /* !defined SINTAB_DATA_H_ */
+}
diff --git a/src/lut.h b/src/lut.h
new file mode 100644 (file)
index 0000000..4e77b45
--- /dev/null
+++ b/src/lut.h
@@ -0,0 +1,20 @@
+#ifndef LUT_H_
+#define LUT_H_
+
+#include <stdint.h>
+
+#define SINTAB_BITS    9
+#define SINTAB_SIZE    (1 << SINTAB_BITS)
+
+#define SIN(angle) \
+       (sintab[((angle) >> (16 - SINTAB_BITS)) & (SINTAB_SIZE - 1)])
+
+#define COS(angle) \
+       (sintab[(((angle) >> (16 - SINTAB_BITS)) + (SINTAB_SIZE / 4)) & (SINTAB_SIZE - 1)])
+
+
+extern int32_t sintab[SINTAB_SIZE];
+
+void init_lut(void);
+
+#endif /* LUT_H_ */
index c2192ee..f690a0e 100644 (file)
@@ -6,12 +6,15 @@
 #include <GL/glut.h>
 #include "glfb.h"
 #include "voxscape.h"
+#include "lut.h"
 
 enum {
-       INP_FWD         = 1,
-       INP_BACK        = 2,
-       INP_LEFT        = 4,
-       INP_RIGHT       = 8
+       INP_FWD         = 0x01,
+       INP_BACK        = 0x02,
+       INP_LEFT        = 0x04,
+       INP_RIGHT       = 0x08,
+       INP_LTURN       = 0x10,
+       INP_RTURN       = 0x20
 };
 
 int init(void);
@@ -29,7 +32,7 @@ int win_width, win_height;
 unsigned int fb[FB_W * FB_H];
 
 unsigned int input;
-int32_t pos[2];
+int32_t pos[2], angle;// = 0x4000;
 
 struct voxscape *vox;
 
@@ -59,6 +62,8 @@ int main(int argc, char **argv)
 
 int init(void)
 {
+       init_lut();
+
        pos[0] = 512 << 16;
        pos[1] = 512 << 16;
 
@@ -67,7 +72,7 @@ int init(void)
        }
        vox_framebuf(vox, FB_W, FB_H, fb);
        vox_proj(vox, 45, 1, 200);
-       vox_view(vox, pos[0], pos[1], 0);
+       vox_view(vox, pos[0], pos[1], angle);
 
        glfb_setup(FB_W, FB_H, GLFB_RGBA32, FB_W * 4);
        return 0;
@@ -79,6 +84,8 @@ void cleanup(void)
 }
 
 #define WALK_SPEED     0x40000
+#define TURN_SPEED     0x100
+
 void update(void)
 {
        if(input & INP_FWD) pos[1] += WALK_SPEED;
@@ -86,7 +93,10 @@ void update(void)
        if(input & INP_LEFT) pos[0] -= WALK_SPEED;
        if(input & INP_RIGHT) pos[0] += WALK_SPEED;
 
-       vox_view(vox, pos[0], pos[1], 0);
+       if(input & INP_LTURN) angle += TURN_SPEED;
+       if(input & INP_RTURN) angle -= TURN_SPEED;
+
+       vox_view(vox, pos[0], pos[1], angle);
 }
 
 void display(void)
@@ -136,6 +146,12 @@ void keyb(unsigned char key, int x, int y)
        case 'd':
                input |= INP_RIGHT;
                break;
+       case 'q':
+               input |= INP_LTURN;
+               break;
+       case 'e':
+               input |= INP_RTURN;
+               break;
 
        default:
                break;
@@ -157,6 +173,12 @@ void keyb_up(unsigned char key, int x, int y)
        case 'd':
                input &= ~INP_RIGHT;
                break;
+       case 'q':
+               input &= ~INP_LTURN;
+               break;
+       case 'e':
+               input &= ~INP_RTURN;
+               break;
 
        default:
                break;
index 28a02bf..0ea8f06 100644 (file)
@@ -6,6 +6,7 @@
 #include <assert.h>
 #include <imago2.h>
 #include "voxscape.h"
+#include "lut.h"
 
 enum {
        SLICELEN        = 1
@@ -179,17 +180,12 @@ void vox_begin(struct voxscape *vox)
 {
        int i;
 
-       /*
-       for(i=0; i<vox->fbwidth; i++) {
-               vox->coltop[i] = vox->fbheight;
-       }
-       */
        memset(vox->coltop, 0, vox->fbwidth * sizeof *vox->coltop);
 
        if(!(vox->valid & SLICELEN)) {
                float theta = (float)vox->fov * M_PI / 360.0f;  /* half angle */
                for(i=0; i<vox->nslices; i++) {
-                       vox->slicelen[i] = (int32_t)((vox->znear + i) * tan(theta) * 10.0f * 65536.0f);
+                       vox->slicelen[i] = (int32_t)((vox->znear + i) * tan(theta) * 4.0f * 65536.0f);
                }
                vox->valid |= SLICELEN;
        }
@@ -197,22 +193,25 @@ void vox_begin(struct voxscape *vox)
 
 void vox_render_slice(struct voxscape *vox, int n)
 {
-       int i, j, tx, ty, hval, colstart, colheight;
-       int32_t x, y, len, xstep;
+       int i, j, tx, ty, hval, colstart, colheight, z;
+       int32_t x, y, len, xstep, ystep;
        uint32_t color;
        uint32_t *fbptr;
 
-       len = vox->slicelen[n];
-       xstep = len / vox->fbwidth;
+       z = vox->znear + n;
+
+       len = vox->slicelen[n] >> 8;
+       xstep = ((COS(vox->angle) >> 8) * len) / vox->fbwidth;
+       ystep = ((SIN(vox->angle) >> 8) * len) / vox->fbwidth;
 
-       x = vox->x - xstep * (vox->fbwidth >> 1);
-       y = vox->y + ((vox->znear + n) << 16);
+       x = vox->x - SIN(vox->angle) * z - xstep * (vox->fbwidth >> 1);
+       y = vox->y + COS(vox->angle) * z - ystep * (vox->fbwidth >> 1);
        for(i=0; i<vox->fbwidth; i++) {
                tx = (x >> 16) & vox->xmask;
                ty = (y >> 16) & vox->ymask;
 
                hval = vox->height[(ty << vox->xshift) + tx] - 80;
-               hval = hval * 80 / (vox->znear + n) + 250;
+               hval = hval * 160 / (vox->znear + n) + 250;
                if(hval > vox->fbheight) hval = vox->fbheight;
                if(hval > vox->coltop[i]) {
                        color = vox->color[(ty << vox->xshift) + tx];
@@ -228,6 +227,7 @@ void vox_render_slice(struct voxscape *vox, int n)
                }
 
                x += xstep;
+               y += ystep;
        }
 }