hermespy-rt

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

commit 5b5adef14a58975360f9a790aaa78ae0090a2fab
parent b7f19dffbb1e09485c00ed0dc3f985e220d17604
Author: Egor Achkasov <eaachkasov@edu.hse.ru>
Date:   Wed,  4 Dec 2024 10:43:08 +0100

Change signature; fread error handling; continous arrays...

Change ints to size_t in compute_paths signature
Call exit(8) on incorrect fread and fgets return
Make hits and hit_indices continuous

Diffstat:
Mcompute_paths.c | 116++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mcompute_paths.h | 12++++++------
2 files changed, 68 insertions(+), 60 deletions(-)

diff --git a/compute_paths.c b/compute_paths.c @@ -6,6 +6,7 @@ #include <string.h> /* for strlen, sprintf */ #include <stdio.h> /* for fopen, FILE, fclose */ #include <math.h> /* for sin, cos, sqrt */ +#include <stdint.h> #define PI 3.14159265358979323846 #define EPS 1e-6 @@ -101,52 +102,52 @@ Mesh load_mesh_ply(const char *mesh_filepath) /* HEADER */ /* ply */ - fread(buff, 1, 4, f); + if (fread(buff, 1, 4, f) != 4) exit(8); if (strncmp(buff, "ply\n", 4)) exit(8); /* format binary_little_endian 1.0 */ - fread(buff, 1, 32, f); + if (fread(buff, 1, 32, f) != 32) exit(8); if (strncmp(buff, "format binary_little_endian 1.0\n", 32)) exit(8); /* element vertex <num_vertices> */ - fgets(buff, 128, f); + if (fgets(buff, 128, f) == NULL) exit(8); if (strncmp(buff, "element vertex ", 15)) exit(8); sscanf(buff, "element vertex %zu", &num_vertices); /* property float x */ /* property float y */ /* property float z */ - fread(buff, 1, 17*3, f); + if (fread(buff, 1, 17*3, f) != 17*3) exit(8); if (strncmp(buff, "property float x\nproperty float y\nproperty float z\n", 17*3)) exit(8); /* element radio_material */ - fgets(buff, 128, f); + if (fgets(buff, 128, f) == NULL) exit(8); if (strncmp(buff, "element radio_material ", 23)) exit(8); sscanf(buff, "element radio_material %zu", &num_materials); /* property list uint char name */ - fread(buff, 1, 29, f); + if (fread(buff, 1, 29, f) != 29) exit(8); if (strncmp(buff, "property list uint char name\n", 29)) exit(8); /* property float a */ /* property float b */ /* property float c */ /* property float d */ - fread(buff, 1, 17*4, f); + if (fread(buff, 1, 17*4, f) != 17*4) exit(8); if (strncmp(buff, "property float a\nproperty float b\nproperty float c\nproperty float d\n", 17*4)) exit(8); /* element face <num_faces> */ - fgets(buff, 128, f); + if (fgets(buff, 128, f) == NULL) exit(8); if (strncmp(buff, "element face ", 13)) exit(8); sscanf(buff, "element face %zu", &num_faces); /* property list uchar int vertex_index */ - fread(buff, 1, 38, f); + if (fread(buff, 1, 38, f) != 38) exit(8); if (strncmp(buff, "property list uchar uint vertex_index\n", 38)) exit(8); /* property uint material_index */ - fread(buff, 1, 29, f); + if (fread(buff, 1, 29, f) != 29) exit(8); if (strncmp(buff, "property uint material_index\n", 29)) exit(8); /* end_header */ - fread(buff, 1, 11, f); + if (fread(buff, 1, 11, f) != 11) exit(8); if (strncmp(buff, "end_header\n", 11)) exit(8); /* Init mesh */ @@ -162,15 +163,16 @@ Mesh load_mesh_ply(const char *mesh_filepath) /* VERTICES */ for (size_t i = 0; i < mesh.num_vertices; ++i) - fread(&mesh.vertices[i], sizeof(Vec3), 1, f); + if (fread(&mesh.vertices[i], sizeof(Vec3), 1, f) != 1) + exit(8); /* RADIO_MATERIALS */ unsigned int name_size; for (size_t i = 0; i < num_materials; ++i) { /* skip name */ - fread(&name_size, sizeof(unsigned int), 1, f); + if (fread(&name_size, sizeof(unsigned int), 1, f) != 1) exit(8); fseek(f, name_size, SEEK_CUR); - fread(&mesh.rms[i], sizeof(RadioMaterial), 1, f); + if (fread(&mesh.rms[i], sizeof(RadioMaterial), 1, f) != 1) exit(8); } /* INDICES */ @@ -178,13 +180,13 @@ Mesh load_mesh_ply(const char *mesh_filepath) uint8_t n; Vec3 *v1, *v2, *v3, u, v; for (size_t i = 0; i < mesh.num_indices; i += 3) { - fread(&n, 1, 1, f); + if (fread(&n, 1, 1, f) != 1) exit(8); if (n != 3) { fprintf(stderr, "Only trianglar faces are supported\n"); exit(8); } - fread(&mesh.indices[i], sizeof(int32_t), 3, f); - fread(&mesh.rm_indices[i / 3], sizeof(int32_t), 1, f); + if (fread(&mesh.indices[i], sizeof(int32_t), 3, f) != 3) exit(8); + if (fread(&mesh.rm_indices[i / 3], sizeof(int32_t), 1, f) != 1) exit(8); /* calculate normal */ v1 = &mesh.vertices[mesh.indices[i]]; v2 = &mesh.vertices[mesh.indices[i + 1]]; @@ -207,7 +209,7 @@ Mesh load_mesh_ply(const char *mesh_filepath) * \param t output distance to the hit point. If no hit, t is not modified. * \param ind output index of the hit triangle. If no hit, i is not modified. */ -void moeller_trumbore(Ray *ray, Mesh *mesh, float *t, size_t *ind) +void moeller_trumbore(Ray *ray, Mesh *mesh, float *t, int32_t *ind) { /* TODO BVH */ /* for each triangle */ @@ -252,10 +254,10 @@ void compute_paths( IN const float *rx_velocities, /* shape (num_rx, 3) */ IN const float *tx_velocities, /* shape (num_tx, 3) */ IN float carrier_frequency, /* > 0.0 */ - IN int num_rx, /* number of receivers */ - IN int num_tx, /* number of transmitters */ - IN int num_paths, /* number of paths */ - IN int num_bounces, /* number of bounces */ + IN size_t num_rx, /* number of receivers */ + IN size_t num_tx, /* number of transmitters */ + IN size_t num_paths, /* number of paths */ + IN size_t num_bounces, /* number of bounces */ OUT float *a, /* output array of gains (num_paths,) */ OUT float *tau /* output array of delays (num_paths,) */ ) @@ -268,7 +270,7 @@ void compute_paths( float k, phi, theta; for (size_t i = 0; i < num_paths; ++i) { k = (float)i + .5; - phi = 1. - 2. * k / num_paths; + phi = acos(1. - 2. * k / num_paths); theta = PI * (1. + sqrt(5.)) * k; ray_directions[i] = (Vec3){ cos(theta) * sin(phi), @@ -279,14 +281,13 @@ void compute_paths( /* Create num_path rays for each tx */ /* Shape (num_tx, num_paths) */ - Ray **rays = (Ray**)malloc(num_tx * sizeof(Ray*)); + Ray *rays = (Ray*)malloc(num_tx * num_paths * sizeof(Ray)); Vec3 tx_position; for (size_t i = 0; i < num_tx; ++i) { - rays[i] = (Ray*)malloc(num_paths * sizeof(Ray)); tx_position = (Vec3){tx_positions[i * 3], tx_positions[i * 3 + 1], tx_positions[i * 3 + 2]}; for (size_t j = 0; j < num_paths; ++j) { - rays[i][j].o = tx_position; - rays[i][j].d = ray_directions[j]; + rays[i * num_paths + j].o = tx_position; + rays[i * num_paths + j].d = ray_directions[j]; } } free(ray_directions); @@ -294,31 +295,38 @@ void compute_paths( /* Calculate the paths */ /* TODO calculate a and tau in moeller_trumbore */ /* shape (num_bounces, num_tx, num_paths) */ - Vec3 ***hits = (Vec3***)malloc(num_bounces * sizeof(Vec3**)); - size_t ***hit_indices = (size_t***)malloc(num_bounces * sizeof(size_t**)); + Vec3 *hits = (Vec3*)malloc(num_bounces * num_tx * num_paths * sizeof(Vec3)); + int32_t *hit_indices = (int32_t*)malloc(num_bounces * num_tx * num_paths * sizeof(int32_t)); float t; - size_t ind; - for (size_t i = 0; i < num_bounces; ++i) { - hits[i] = (Vec3**)malloc(num_tx * sizeof(Vec3*)); - hit_indices[i] = (size_t**)malloc(num_tx * sizeof(size_t*)); - for (size_t j = 0; j < num_tx; ++j) { - hits[i][j] = (Vec3*)malloc(num_paths * sizeof(Vec3)); - hit_indices[i][j] = (size_t*)malloc(num_paths * sizeof(size_t)); + int32_t ind; + Ray *r; + Vec3 *h; + for (size_t i = 0; i < num_bounces; ++i) + for (size_t j = 0; j < num_tx; ++j) for (size_t k = 0; k < num_paths; ++k) { t = -1.; ind = -1; - moeller_trumbore(&rays[j][k], &mesh, &t, &ind); - hits[i][j][k] = vec3_scale(&rays[j][k].d, t); - hits[i][j][k] = vec3_add(&hits[i][j][k], &rays[j][k].o); - rays[j][k].o = hits[i][j][k]; - hit_indices[i][j][k] = ind; + r = &rays[j * num_paths + k]; + moeller_trumbore(r, &mesh, &t, &ind); + hit_indices[i * num_tx * num_paths + j * num_paths + k] = ind; + h = &hits[i * num_tx * num_paths + j * num_paths + k]; + *h = vec3_scale(&r->d, t); + *h = vec3_add(h, &r->o); + r->o = *h; } - } - } + FILE *f = fopen("hits.bin", "wb"); + fwrite(hits, sizeof(Vec3), num_bounces * num_tx * num_paths, f); + fclose(f); /* TODO Remove */ - a = hits; - tau = hit_indices; + for (size_t i = 0; i < num_bounces; ++i) + for (size_t j = 0; j < num_rx; ++j) + for (size_t k = 0; k < num_paths; ++k) { + h = &hits[i * num_tx * num_paths + j * num_paths + k]; + a[i * num_rx * num_paths * 3 + j * num_paths * 3 + k * 3] = h->x; + a[i * num_rx * num_paths * 3 + j * num_paths * 3 + k * 3 + 1] = h->y; + a[i * num_rx * num_paths * 3 + j * num_paths * 3 + k * 3 + 2] = h->z; + } /* Free */ /* Free the hits */ @@ -335,13 +343,13 @@ void compute_paths( free(hit_indices); */ /* Free the rays */ - for (size_t i = 0; i < num_tx; ++i) - free(rays[i]); - free(rays); - /* Free the mesh */ - free(mesh.vertices); - free(mesh.rms); - free(mesh.indices); - free(mesh.rm_indices); - free(mesh.normals); + // for (size_t i = 0; i < num_tx; ++i) + // free(rays[i]); + // free(rays); + // /* Free the mesh */ + // free(mesh.vertices); + // free(mesh.rms); + // free(mesh.indices); + // free(mesh.rm_indices); + // free(mesh.normals); } diff --git a/compute_paths.h b/compute_paths.h @@ -1,14 +1,14 @@ #ifndef COMPUTE_PATHS_H #define COMPUTE_PATHS_H -#include <stdint.h> /* for int32_t */ +#include <stddef.h> /* for size_t */ #define IN #define OUT /** Compute gains and delays between in a Mitsuba scene. * - * Scene must be defined in a Mitsuba .xml JSON format. + * Scene must be defined in a specific PLY format. See README for details. * The meshes must be present in the same directory as the .xml file, * under meshes/ directory in .ply files in PLY format. * Meshes filenames must be the same as the name of the object in the .xml file. @@ -32,10 +32,10 @@ void compute_paths( IN const float *rx_velocities, /* shape (num_rx, 3) */ IN const float *tx_velocities, /* shape (num_tx, 3) */ IN float carrier_frequency, /* > 0.0 */ - IN int num_rx, /* number of receivers */ - IN int num_tx, /* number of transmitters */ - IN int num_paths, /* number of paths */ - IN int num_bounces, /* number of bounces */ + IN size_t num_rx, /* number of receivers */ + IN size_t num_tx, /* number of transmitters */ + IN size_t num_paths, /* number of paths */ + IN size_t num_bounces, /* number of bounces */ OUT float *a, /* output array of gains (num_paths,) */ OUT float *tau /* output array of delays (num_paths,) */ );