Commit: 6f70fb0962e6c9cd37882b12821159b434f61c2e
Parent: 1a87fc8b28e9232f27f13573cfe07b5fd6168f58
Author: Randy Palamar
Date: Sun, 25 May 2025 13:14:27 -0600
multi volume rendering
in this case we actually want the volumes themselves to rotate,
not the camera.
Diffstat:
M | common.c | | | 41 | +++++++++++++++++++++++++++++------------ |
M | util.c | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 72 insertions(+), 12 deletions(-)
diff --git a/common.c b/common.c
@@ -35,11 +35,12 @@ typedef struct {
u32 texture;
} VolumeDisplayItem;
-#define DRAW_ALL_VOLUMES 0
+#define DRAW_ALL_VOLUMES 1
global u32 single_volume_index = 0;
global VolumeDisplayItem volumes[] = {
/* WALKING FORCES */
- {"./data/test/frame_%02u.bin", 512, 1024, 64, {{-18.5, -9.6, 5}}, {{18.5, 9.6, 42}}, 0.58, 62, 0, 0, 1},
+ {"./data/test/frame_%02u.bin", 512, 1024, 64, {{-18.5, -9.6, 5}}, {{18.5, 9.6, 42}}, 0.58, 62, 3 * -18.5, 0, 1},
+ {"./data/test/frame_%02u.bin", 512, 1024, 64, {{-18.5, -9.6, 5}}, {{18.5, 9.6, 42}}, 0.58, 62, 3 * 18.5, 0, 1},
};
#define MODEL_RENDER_MODEL_MATRIX_LOC (0)
@@ -481,7 +482,7 @@ set_camera(u32 program, u32 location, v3 position, v3 normal, v3 orthogonal)
}
function void
-draw_volume_item(ViewerContext *ctx, VolumeDisplayItem *v)
+draw_volume_item(ViewerContext *ctx, VolumeDisplayItem *v, f32 rotation)
{
if (!v->texture) {
v->texture = load_complex_texture(ctx->arena, v->file_path, v->multi_file,
@@ -490,11 +491,27 @@ draw_volume_item(ViewerContext *ctx, VolumeDisplayItem *v)
u32 program = ctx->model_render_context.shader;
v3 scale = v3_sub(v->max_coord_mm, v->min_coord_mm);
- m4 model_transform;
- model_transform.c[0] = (v4){{scale.x, 0, 0, 0}};
- model_transform.c[1] = (v4){{0, scale.z, 0, 0}};
- model_transform.c[2] = (v4){{0, 0, scale.y, 0}};
- model_transform.c[3] = (v4){{v->translate_x, 0, 0, 1}};
+ m4 S;
+ S.c[0] = (v4){{scale.x, 0, 0, 0}};
+ S.c[1] = (v4){{0, scale.z, 0, 0}};
+ S.c[2] = (v4){{0, 0, scale.y, 0}};
+ S.c[3] = (v4){{0, 0, 0, 1}};
+
+ m4 T;
+ T.c[0] = (v4){{1, 0, 0, v->translate_x}};
+ T.c[1] = (v4){{0, 1, 0, 0}};
+ T.c[2] = (v4){{0, 0, 1, 0}};
+ T.c[3] = (v4){{0, 0, 0, 1}};
+
+ f32 sa = sin_f32(rotation);
+ f32 ca = cos_f32(rotation);
+ m4 R;
+ R.c[0] = (v4){{ ca, 0, sa, 0}};
+ R.c[1] = (v4){{ 0, 1, 0, 0}};
+ R.c[2] = (v4){{-sa, 0, ca, 0}};
+ R.c[3] = (v4){{ 0, 0, 0, 1}};
+
+ m4 model_transform = m4_mul(m4_mul(R, S), T);
glProgramUniformMatrix4fv(program, MODEL_RENDER_MODEL_MATRIX_LOC, 1, 0, model_transform.E);
glProgramUniform1f(program, MODEL_RENDER_CLIP_FRACTION_LOC, 1 - v->clip_fraction);
@@ -513,8 +530,8 @@ update_scene(ViewerContext *ctx, f32 dt)
if (ctx->cycle_t > 1) ctx->cycle_t -= 1;
f32 angle = ctx->cycle_t * 2 * PI;
- ctx->camera_position.x = ctx->camera_radius * cos_f32(angle);
- ctx->camera_position.z = -ctx->camera_radius * sin_f32(angle);
+ ctx->camera_position.x = 0;
+ ctx->camera_position.z = -ctx->camera_radius;
ctx->camera_position.y = ctx->camera_radius * tan_f32(ctx->camera_angle);
RenderTarget *rt = &ctx->multisample_target;
@@ -549,9 +566,9 @@ update_scene(ViewerContext *ctx, f32 dt)
#if DRAW_ALL_VOLUMES
for (u32 i = 0; i < countof(volumes); i++)
- draw_volume_item(ctx, volumes + i);
+ draw_volume_item(ctx, volumes + i, angle);
#else
- draw_volume_item(ctx, volumes + single_volume_index);
+ draw_volume_item(ctx, volumes + single_volume_index, angle);
#endif
/* NOTE(rnp): resolve multisampled scene */
diff --git a/util.c b/util.c
@@ -127,6 +127,49 @@ cross(v3 a, v3 b)
return result;
}
+function f32
+v4_dot(v4 a, v4 b)
+{
+ f32 result = 0;
+ result += a.x * b.x;
+ result += a.y * b.y;
+ result += a.z * b.z;
+ result += a.w * b.w;
+ return result;
+}
+
+function v4
+m4_row(m4 a, u32 row)
+{
+ v4 result;
+ result.E[0] = a.c[0].E[row];
+ result.E[1] = a.c[1].E[row];
+ result.E[2] = a.c[2].E[row];
+ result.E[3] = a.c[3].E[row];
+ return result;
+}
+
+function v4
+m4_column(m4 a, u32 column)
+{
+ v4 result = a.c[column];
+ return result;
+}
+
+function m4
+m4_mul(m4 a, m4 b)
+{
+ m4 result;
+ for (u32 i = 0; i < countof(result.E); i++) {
+ u32 base = i / 4;
+ u32 sub = i % 4;
+ v4 v1 = m4_row(a, base);
+ v4 v2 = m4_column(b, sub);
+ result.E[i] = v4_dot(v1, v2);
+ }
+ return result;
+}
+
function u32
utf8_encode(u8 *out, u32 cp)
{