hermespy-rt

Minimalistic signal processing ray-tracer in C
git clone https://git.ea.contact/hermespy-rt
Log | Files | Refs

vizrays.c (7371B)


      1 #include "viz.h" /* for vizrays */
      2 #include "../inc/vec3.h" /* for Vec3 */
      3 #include "../inc/scene.h" /* for Scene, Mesh, scene_load */
      4 #include "../inc/ray.h" /* for Ray */
      5 
      6 #include <GL/glut.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <math.h>
     10 #include <stdint.h>
     11 #include <ctype.h> /* for tolower */ 
     12 
     13 /**
     14  * Structs
     15  */
     16 
     17 typedef struct {
     18   Vec3 o, t;
     19   float d;
     20   float lastX, lastY;
     21   float yaw, pitch, roll;
     22 } Camera;
     23 
     24 /**
     25  * Globals
     26  */
     27 
     28 Camera g_cam = {
     29   {0.f, 0.f, 5.f},
     30   {0.f, 0.f, 0.f},
     31   5.f,
     32   0.f, 0.f,
     33   0.f, 0.f, 0.f
     34 };
     35 uint8_t g_mouseDown = 0;
     36 
     37 Ray* g_rays = NULL;
     38 uint8_t *g_active = NULL;
     39 Scene* g_scene = NULL;
     40 
     41 uint32_t g_numTx = 0;
     42 uint32_t g_numPaths = 0;
     43 uint32_t g_numBounces = 0;
     44 
     45 uint32_t g_bounce_cur = 0;
     46 
     47 /**
     48  * Draw functions
     49  */
     50 
     51 void drawScene() {
     52   glBegin(GL_TRIANGLES);
     53   for (uint32_t i = 0; i < g_scene->num_meshes; i++) {
     54     Mesh* mesh = &g_scene->meshes[i];
     55     float mesh_color = (float)i / g_scene->num_meshes;
     56     glColor3f(mesh_color, 1.f - mesh_color, 0.f);
     57 
     58     for (uint32_t j = 0; j < mesh->num_triangles; j++) {
     59       uint32_t idx = mesh->is[j * 3];
     60       Vec3 v1 = mesh->vs[idx];
     61       idx = mesh->is[j * 3 + 1];
     62       Vec3 v2 = mesh->vs[idx];
     63       idx = mesh->is[j * 3 + 2];
     64       Vec3 v3 = mesh->vs[idx];
     65       glVertex3f(v1.x, v1.y, v1.z);
     66       glVertex3f(v2.x, v2.y, v2.z);
     67       glVertex3f(v3.x, v3.y, v3.z);
     68     }
     69   }
     70   glEnd();
     71 }
     72 
     73 void drawRays() {
     74   float color = (float)g_bounce_cur / g_numBounces;
     75   glColor3f(color, 0.0f, 1.0f - color);
     76   
     77   uint8_t active_bit = 1;
     78   uint32_t num_skipped = 0;
     79   for (uint32_t tx = 0; tx < g_numTx; ++tx) {
     80     glBegin(GL_LINES);
     81  
     82     uint32_t active_byte = (tx * (g_numBounces + 1) + g_bounce_cur) * (g_numPaths / 8 + 1);
     83     uint32_t ray_ind_base = (tx * (g_numBounces + 1) + g_bounce_cur) * g_numPaths;
     84 
     85     for (uint32_t path = 0; path < g_numPaths; ++path, active_bit <<= 1) {
     86       if (!active_bit) {
     87         active_byte++;
     88         active_bit = 1;
     89       }
     90       if (!(g_active[active_byte] & active_bit))
     91       {
     92         num_skipped++;
     93         continue;
     94       }
     95       
     96       uint32_t idx = ray_ind_base + path;
     97       GLfloat x = g_rays[idx].o.x;
     98       GLfloat y = g_rays[idx].o.y;
     99       GLfloat z = g_rays[idx].o.z;
    100       /* Origin */
    101       glVertex3f(x, y, z);
    102       /* Destination */
    103       glVertex3f(
    104         x + g_rays[idx].d.x,
    105         y + g_rays[idx].d.y,
    106         z + g_rays[idx].d.z
    107       );
    108     }
    109     glEnd();
    110     
    111     /* Draw points */
    112     glPointSize(5.0f);
    113     glBegin(GL_POINTS);
    114     active_byte = g_bounce_cur * (g_numTx * g_numPaths / 8 + 1);
    115     active_bit = 1;
    116     for (uint32_t path = 0; path < g_numPaths; ++path) {
    117       if (!active_bit) {
    118         active_byte++;
    119         active_bit = 1;
    120       }
    121       if (!(g_active[active_byte] & active_bit))
    122         continue;
    123       uint32_t idx = ray_ind_base + path;
    124       glVertex3f(g_rays[idx].o.x, g_rays[idx].o.y, g_rays[idx].o.z);
    125     }
    126     glEnd();
    127   }
    128   
    129   printf("\rSkipped %d paths", num_skipped);
    130   fflush(stdout);
    131 }
    132 
    133 /**
    134  * Callbacks
    135  */
    136 
    137 void reshape(int w, int h) {
    138   glViewport(0, 0, w, h);
    139   glMatrixMode(GL_PROJECTION);
    140   glLoadIdentity();
    141   gluPerspective(60.0f, (float)w/h, 0.1f, 1000.0f);
    142   glMatrixMode(GL_MODELVIEW);
    143 }
    144 
    145 void display() {
    146   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    147   glLoadIdentity();
    148   
    149   /* Look at target from camera position */
    150   gluLookAt(
    151       g_cam.o.x, g_cam.o.y, g_cam.o.z,
    152       g_cam.t.x, g_cam.t.y, g_cam.t.z,
    153       0.0f, 1.0f, 0.0f
    154   );
    155 
    156   if (g_scene) drawScene();
    157   drawRays();
    158   
    159   glutSwapBuffers();
    160 }
    161 
    162 void updateCamera() {
    163   float x = g_cam.d * cosf(g_cam.pitch) * cosf(g_cam.yaw);
    164   float y = g_cam.d * sinf(g_cam.pitch);
    165   float z = g_cam.d * cosf(g_cam.pitch) * sinf(g_cam.yaw);
    166   
    167   g_cam.o.x = g_cam.t.x + x;
    168   g_cam.o.y = g_cam.t.y + y;
    169   g_cam.o.z = g_cam.t.z + z;
    170 
    171   gluLookAt(g_cam.o.x, g_cam.o.y, g_cam.o.z,
    172             g_cam.t.x, g_cam.t.y, g_cam.t.z,
    173             0.f, 1.f, 0.f);
    174 }
    175 
    176 void keyboard(unsigned char key, int x, int y) {
    177   float moveSpeed = 0.1f;
    178   float tiltSpeed = 0.15f;
    179   /* Speed up if SHIFT is down */
    180   if (glutGetModifiers() & GLUT_ACTIVE_SHIFT) {
    181     moveSpeed *= 5;
    182     key = tolower(key);
    183   }
    184   
    185   /* Calculate forward direction */
    186   Vec3 dir = {
    187     g_cam.t.x - g_cam.o.x,
    188     g_cam.t.y - g_cam.o.y,
    189     g_cam.t.z - g_cam.o.z
    190   };
    191   float norm = sqrtf(dir.x * dir.x + dir.y * dir.y + dir.z * dir.z);
    192   Vec3 forward = {dir.x / norm, dir.y / norm, dir.z / norm};
    193   
    194   /* Calculate right vector (cross product of forward and up (0,0,1)) */
    195   norm = sqrtf(forward.z * forward.z + forward.x * forward.x);
    196   Vec3 right = {forward.z / norm, 0.0f, -forward.x / norm};
    197   
    198   switch (key) {
    199     case 'w': /* Move target forward */
    200       g_cam.t.x += forward.x * moveSpeed;
    201       g_cam.t.z += forward.z * moveSpeed;
    202       break;
    203     case 's': /* Move target backward */
    204       g_cam.t.x -= forward.x * moveSpeed;
    205       g_cam.t.z -= forward.z * moveSpeed;
    206       break;
    207     case 'a': /* Move target left */
    208       g_cam.t.x += right.x * moveSpeed;
    209       g_cam.t.z += right.z * moveSpeed;
    210       break;
    211     case 'd': /* Move target right */
    212       g_cam.t.x -= right.x * moveSpeed;
    213       g_cam.t.z -= right.z * moveSpeed;
    214       break;
    215 
    216     case 'q': /* Roll left */
    217       g_cam.roll += tiltSpeed;
    218       break;
    219     case 'e': /* Roll right */
    220       g_cam.roll -= tiltSpeed;
    221       break;
    222 
    223     case 'x': /* Increase g_curBounce */
    224       if (g_bounce_cur < g_numBounces) g_bounce_cur++;
    225       break;
    226     case 'z': /* Decrease g_curBounce */
    227       if (g_bounce_cur > 0) g_bounce_cur--;
    228       break;
    229   }
    230   
    231   updateCamera();
    232   glutPostRedisplay();
    233 }
    234 
    235 void mouse(int button, int state, int x, int y) {
    236   if (button == GLUT_LEFT_BUTTON) {
    237     g_mouseDown = (state == GLUT_DOWN);
    238     g_cam.lastX = x;
    239     g_cam.lastY = y;
    240   }
    241   /* Handle scroll wheel */
    242   else if (button == 3) { /* Scroll up */
    243     g_cam.d = fmaxf(0.1f, g_cam.d - 0.5f); /* Prevent going too close */
    244     updateCamera();
    245     glutPostRedisplay();
    246   }
    247   else if (button == 4) { /* Scroll down */
    248     g_cam.d += 0.5f;
    249     updateCamera();
    250     glutPostRedisplay();
    251   }
    252 }
    253 
    254 void mouseMotion(int x, int y) {
    255   if (!g_mouseDown) return;
    256 
    257   float sensitivity = 0.005f;
    258   float dx = (float)(x - g_cam.lastX);
    259   float dy = (float)(y - g_cam.lastY);
    260   
    261   g_cam.yaw -= dx * sensitivity;
    262   g_cam.pitch -= dy * sensitivity;
    263   
    264   /* Clamp pitch to prevent flipping */
    265   if (g_cam.pitch > 1.5f) g_cam.pitch = 1.5f;
    266   if (g_cam.pitch < -1.5f) g_cam.pitch = -1.5f;
    267   
    268   g_cam.lastX = x;
    269   g_cam.lastY = y;
    270   
    271   updateCamera();
    272   glutPostRedisplay();
    273 }
    274 
    275 /**
    276  * vizrays
    277  */
    278 
    279 void vizrays(
    280   IN RaysInfo *raysInfo,
    281   IN Scene *scene,
    282   IN uint32_t numTx
    283 )
    284 {
    285   g_rays = raysInfo->rays;
    286   g_active = raysInfo->rays_active;
    287   g_scene = scene;
    288   g_numTx = numTx;
    289   g_numPaths = raysInfo->num_rays;
    290   g_numBounces = raysInfo->num_bounces;
    291   
    292   /* Initialize GLUT */
    293   int fake_argc = 1;
    294   char *fake_argv[] = {"vizrays"};
    295   glutInit(&fake_argc, fake_argv);
    296   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    297   glutInitWindowSize(800, 600);
    298   glutCreateWindow("Ray Visualization");
    299   
    300   /* Set up OpenGL */
    301   glEnable(GL_DEPTH_TEST);
    302   glClearColor(0.f, 0.f, 0.f, 1.0f);
    303   
    304   /* Register callbacks */
    305   glutDisplayFunc(display);
    306   glutReshapeFunc(reshape);
    307   glutKeyboardFunc(keyboard);
    308   glutMouseFunc(mouse);
    309   glutMotionFunc(mouseMotion);
    310   
    311   updateCamera();
    312   glutMainLoop();
    313 }