From 37f10d76ddfbe474dcb31c4b7611f2d94824ae95 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 12 Jan 2025 18:23:01 -0600 Subject: [PATCH] working tracers --- src/common.h | 8 +++---- src/config.h | 2 +- src/draw.c | 35 ++++++++++++++++++------------ src/draw.h | 1 + src/entity.h | 12 +++++++---- src/game.c | 60 ++++++++++++++++++++++++++++++++++------------------ src/phys.c | 4 +++- src/user.c | 36 +++++++++++++++++++++++++------ 8 files changed, 106 insertions(+), 52 deletions(-) diff --git a/src/common.h b/src/common.h index 4f99ca38..a8044567 100644 --- a/src/common.h +++ b/src/common.h @@ -272,11 +272,11 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); /* Color */ #define RGBA_32(r, g, b, a) (u32)((u32)(r) | ((u32)(g) << 8) | ((u32)(b) << 16) | ((u32)(a) << 24)) -#define RGB_32(r, g, b) RGBA_32(r, g, b, 0xFF) +#define RGB_32(r, g, b) RGBA_32((r), (g), (b), 0xFF) -#define _RGB_F_TO_U8(f) ((u8)((f * 255.0f) + 0.5f)) -#define RGBA_32_F(r, g, b, a) RGBA_32(_RGB_F_TO_U8(r), _RGB_F_TO_U8(g), _RGB_F_TO_U8(b), _RGB_F_TO_U8(a)) -#define RGB_32_F(r, g, b) RGBA_32_F(r, g, b, 1.f) +#define _RGB_F_TO_U8(fl) ((u8)((fl * 255.0f) + 0.5f)) +#define RGBA_32_F(r, g, b, a) RGBA_32(_RGB_F_TO_U8((r)), _RGB_F_TO_U8((g)), _RGB_F_TO_U8((b)), _RGB_F_TO_U8((a))) +#define RGB_32_F(r, g, b) RGBA_32_F((r), (g), (b), 1.f) #define COLOR_WHITE RGB_32(0xFF, 0xFF, 0xFF) #define COLOR_BLACK RGB_32(0 , 0 , 0 ) diff --git a/src/config.h b/src/config.h index 445355e9..c659ccbb 100644 --- a/src/config.h +++ b/src/config.h @@ -55,7 +55,7 @@ #define USER_INTERP_ENABLED 1 #define COLLIDER_DEBUG RTC -#define COLLIDER_DEBUG_DETAILED 1 +#define COLLIDER_DEBUG_DETAILED 0 /* ========================== * * Settings diff --git a/src/draw.c b/src/draw.c index 055f8574..0634cb4e 100644 --- a/src/draw.c +++ b/src/draw.c @@ -28,7 +28,7 @@ struct draw_startup_receipt draw_startup(struct renderer_startup_receipt *render * Texture * ========================== */ -INTERNAL void draw_sprite_quad_internal(struct renderer_canvas *canvas, struct clip_rect clip, u32 tint, struct quad quad) +INTERNAL void draw_sprite_quad_internal(struct renderer_canvas *canvas, struct clip_rect clip, u32 tint0, u32 tint1, struct quad quad) { struct texture_shader_vertex *vertices = NULL; vidx *indices = NULL; @@ -38,25 +38,25 @@ INTERNAL void draw_sprite_quad_internal(struct renderer_canvas *canvas, struct c vertices[0] = (struct texture_shader_vertex) { .pos = quad.p1, .uv = { clip.p1.x, clip.p1.y }, - .color = tint + .color = tint0 }; /* Top right */ vertices[1] = (struct texture_shader_vertex) { .pos = quad.p2, .uv = { clip.p2.x, clip.p1.y }, - .color = tint + .color = tint0 }; /* Bottom right */ vertices[2] = (struct texture_shader_vertex) { .pos = quad.p3, .uv = { clip.p2.x, clip.p2.y }, - .color = tint + .color = tint1 }; /* Bottom left */ vertices[3] = (struct texture_shader_vertex) { .pos = quad.p4, .uv = { clip.p1.x, clip.p2.y }, - .color = tint + .color = tint1 }; /* Top / right triangle */ @@ -74,7 +74,7 @@ void draw_sprite_quad(struct renderer_canvas *canvas, struct draw_sprite_params { renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .sprite = params.sprite }); - draw_sprite_quad_internal(canvas, params.clip, params.tint, quad); + draw_sprite_quad_internal(canvas, params.clip, params.tint, params.tint, quad); } void draw_sprite_rect(struct renderer_canvas *canvas, struct draw_sprite_params params, struct rect rect) @@ -148,14 +148,14 @@ void draw_solid_circle(struct renderer_canvas *canvas, struct v2 pos, f32 radius void draw_solid_quad(struct renderer_canvas *canvas, struct quad quad, u32 color) { renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture_handle = G.solid_white }); - draw_sprite_quad_internal(canvas, CLIP_ALL, color, quad); + draw_sprite_quad_internal(canvas, CLIP_ALL, color, color, quad); } void draw_solid_rect(struct renderer_canvas *canvas, struct rect rect, u32 color) { renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture_handle = G.solid_white }); struct quad quad = quad_from_rect(rect); - draw_sprite_quad_internal(canvas, CLIP_ALL, color, quad); + draw_sprite_quad_internal(canvas, CLIP_ALL, color, color, quad); } /* ========================== * @@ -166,14 +166,21 @@ void draw_solid_line(struct renderer_canvas *canvas, struct v2 start, struct v2 { renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture_handle = G.solid_white }); struct quad quad = quad_from_line(start, end, thickness); - draw_sprite_quad_internal(canvas, CLIP_ALL, color, quad); + draw_sprite_quad_internal(canvas, CLIP_ALL, color, color, quad); +} + +void draw_gradient_line(struct renderer_canvas *canvas, struct v2 start, struct v2 end, f32 thickness, u32 color_start, u32 color_end) +{ + renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture_handle = G.solid_white }); + struct quad quad = quad_from_line(start, end, thickness); + draw_sprite_quad_internal(canvas, CLIP_ALL, color_start, color_end, quad); } void draw_solid_ray(struct renderer_canvas *canvas, struct v2 pos, struct v2 rel, f32 thickness, u32 color) { renderer_canvas_ensure_texture_cmd(canvas, (struct texture_shader_parameters) { .texture_handle = G.solid_white }); struct quad quad = quad_from_ray(pos, rel, thickness); - draw_sprite_quad_internal(canvas, CLIP_ALL, color, quad); + draw_sprite_quad_internal(canvas, CLIP_ALL, color, color, quad); } void draw_solid_poly_line(struct renderer_canvas *canvas, struct v2_array array, b32 loop, f32 thickness, u32 color) @@ -187,13 +194,13 @@ void draw_solid_poly_line(struct renderer_canvas *canvas, struct v2_array array, struct v2 p1 = array.points[i - 1]; struct v2 p2 = array.points[i]; struct quad q = quad_from_line(p1, p2, thickness); - draw_sprite_quad_internal(canvas, CLIP_ALL, color, q); + draw_sprite_quad_internal(canvas, CLIP_ALL, color, color, q); } if (loop && array.count > 2) { struct v2 p1 = array.points[array.count - 1]; struct v2 p2 = array.points[0]; struct quad q = quad_from_line(p1, p2, thickness); - draw_sprite_quad_internal(canvas, CLIP_ALL, color, q); + draw_sprite_quad_internal(canvas, CLIP_ALL, color, color, q); } } @@ -261,7 +268,7 @@ void draw_solid_arrow_line(struct renderer_canvas *canvas, struct v2 start, stru draw_solid_poly_internal(canvas, head_points_v2_array, color); struct quad line_quad = quad_from_line(start, head_start, thickness); - draw_sprite_quad_internal(canvas, CLIP_ALL, color, line_quad); + draw_sprite_quad_internal(canvas, CLIP_ALL, color, color, line_quad); } void draw_solid_arrow_ray(struct renderer_canvas *canvas, struct v2 pos, struct v2 rel, f32 thickness, f32 arrowhead_height, u32 color) @@ -343,7 +350,7 @@ void draw_text_ex(struct renderer_canvas *canvas, struct font *font, struct v2 p }; struct quad quad = quad_from_rect(RECT(x, y, width, height)); - draw_sprite_quad_internal(canvas, clip, 0xFFFFFFFF, quad); + draw_sprite_quad_internal(canvas, clip, 0xFFFFFFFF, 0xFFFFFFFF, quad); draw_pos.x += glyph->advance * scale; } diff --git a/src/draw.h b/src/draw.h index 8880b15c..72efbb87 100644 --- a/src/draw.h +++ b/src/draw.h @@ -31,6 +31,7 @@ void draw_solid_quad(struct renderer_canvas *canvas, struct quad quad, u32 color void draw_solid_rect(struct renderer_canvas *canvas, struct rect rect, u32 color); void draw_solid_line(struct renderer_canvas *canvas, struct v2 start, struct v2 end, f32 thickness, u32 color); +void draw_gradient_line(struct renderer_canvas *canvas, struct v2 start, struct v2 end, f32 thickness, u32 color_start, u32 color_end); void draw_solid_ray(struct renderer_canvas *canvas, struct v2 start, struct v2 ray, f32 thickness, u32 color); void draw_solid_poly_line(struct renderer_canvas *canvas, struct v2_array array, b32 loop, f32 thickness, u32 color); void draw_solid_circle_line(struct renderer_canvas *canvas, struct v2 pos, f32 radius, f32 thickness, u32 color, u32 detail); diff --git a/src/entity.h b/src/entity.h index 9a66b7df..01e112a5 100644 --- a/src/entity.h +++ b/src/entity.h @@ -232,11 +232,15 @@ struct entity { /* ====================================================================== */ /* Tracer */ - f64 tracer_start_time; - struct v2 tracer_start; - f32 tracer_fade; /* How many seconds for tracer to fade to transparency */ + /* ENTITY_PROP_TRACER */ - struct v2 tracer_tail; + struct v2 tracer_start; + struct v2 tracer_start_velocity; + f32 tracer_fade_duration; /* Time for tracer to fade from opacity of 1 to 0 */ + + /* calculated each frame */ + struct v2 tracer_gradient_start; + struct v2 tracer_gradient_end; /* ====================================================================== */ /* Testing */ diff --git a/src/game.c b/src/game.c index 2092be50..709c30b6 100644 --- a/src/game.c +++ b/src/game.c @@ -376,6 +376,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array) /* Create test blood */ /* TODO: Remove this */ +#if 0 { struct xform xf = XFORM_TRS(.t = point); struct entity *decal = entity_alloc(root); @@ -386,6 +387,10 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array) decal->linear_velocity = v2_mul(v2_norm(normal), 0.5f); decal->angular_velocity = 1 - (((f32)sys_rand_u32() / (f32)U32_MAX) * 2); } +#else + (UNUSED)normal; + (UNUSED)root; +#endif } } } @@ -815,8 +820,9 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) bullet->bullet_src_pos = rel_pos; bullet->bullet_src_dir = rel_dir; //bullet->bullet_impulse = 0.1f; - //bullet->bullet_impulse = 0.25f; - bullet->bullet_impulse = 1.0f; + bullet->bullet_impulse = 0.25f; + //bullet->bullet_impulse = 0.5f; + //bullet->bullet_impulse = 1.0f; //bullet->bullet_impulse = 5.f; bullet->mass_unscaled = 0.04f; bullet->inertia_unscaled = 0.00001f; @@ -832,7 +838,9 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) /* Spawn tracer */ { struct entity *tracer = entity_alloc(root); - tracer->tracer_fade = 0.5f; + //tracer->tracer_fade_duration = 0.075f; + //tracer->tracer_fade_duration = 0.025f; + tracer->tracer_fade_duration = 0.01f; entity_enable_prop(tracer, ENTITY_PROP_TRACER); bullet->bullet_tracer = tracer->handle; @@ -1033,6 +1041,31 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) phys_step(&ctx, dt); } + /* ========================== * + * Update tracers + * ========================== */ + + for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { + struct entity *ent = &store->entities[entity_index]; + if (!entity_is_valid_and_active(ent)) continue; + if (!entity_has_prop(ent, ENTITY_PROP_TRACER)) continue; + + struct v2 end = entity_get_xform(ent).og; + + struct v2 tick_velocity = v2_mul(ent->tracer_start_velocity, dt); + struct v2 gradient_start = v2_add(ent->tracer_gradient_start, tick_velocity); + struct v2 gradient_end = v2_add(ent->tracer_gradient_end, tick_velocity); + + if (v2_dot(tick_velocity, v2_sub(gradient_start, end)) > 0) { + /* Tracer has disappeared */ + entity_enable_prop(ent, ENTITY_PROP_RELEASE_NEXT_TICK); + } + + ent->tracer_gradient_start = gradient_start; + ent->tracer_gradient_end = gradient_end; + + } + /* ========================== * * Initialize bullet kinematics from sources * ========================== */ @@ -1064,29 +1097,14 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) entity_set_xform(tracer, xf); entity_enable_prop(tracer, ENTITY_PROP_PHYSICAL_KINEMATIC); tracer->linear_velocity = ent->linear_velocity; - tracer->tracer_start_time = time; tracer->tracer_start = pos; - tracer->tracer_tail = pos; + tracer->tracer_start_velocity = ent->linear_velocity; + tracer->tracer_gradient_end = pos; + tracer->tracer_gradient_start = v2_sub(pos, v2_mul(ent->linear_velocity, tracer->tracer_fade_duration)); } } } - /* ========================== * - * Update tracers - * ========================== */ - -#if 0 - for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { - struct entity *ent = &store->entities[entity_index]; - if (!entity_is_valid_and_active(ent)) continue; - if (!entity_has_prop(ent, ENTITY_PROP_TRACER)) continue; - - struct v2 start = ent->tracer_start; - struct v2 tail = ent->tracer_tail; - struct v2 end = entity_get_xform(ent).og; - } -#endif - /* ========================== * * Update camera position * ========================== */ diff --git a/src/phys.c b/src/phys.c index ed91b50a..b3e9f3bd 100644 --- a/src/phys.c +++ b/src/phys.c @@ -287,7 +287,6 @@ void phys_prepare_contacts(struct phys_ctx *ctx) { __prof; struct entity_lookup *contact_lookup = ctx->contact_lookup; - struct entity_lookup *debug_lookup = ctx->debug_lookup; struct entity_store *store = ctx->store; for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { @@ -378,6 +377,8 @@ void phys_prepare_contacts(struct phys_ctx *ctx) } } +#if COLLIDER_DEBUG + struct entity_lookup *debug_lookup = ctx->debug_lookup; for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { struct entity *dbg_ent = &store->entities[entity_index]; if (!entity_is_valid_and_active(dbg_ent)) continue; @@ -413,6 +414,7 @@ void phys_prepare_contacts(struct phys_ctx *ctx) } } } +#endif } void phys_warm_start_contacts(struct phys_ctx *ctx) diff --git a/src/user.c b/src/user.c index c19acfff..475256c0 100644 --- a/src/user.c +++ b/src/user.c @@ -542,7 +542,8 @@ INTERNAL void user_update(void) e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, tick_blend); e->camera_xform_target = xform_lerp(e0->camera_xform_target, e1->camera_xform_target, tick_blend); - e->tracer_tail = v2_lerp(e0->tracer_tail, e1->tracer_tail, tick_blend); + e->tracer_gradient_start = v2_lerp(e0->tracer_gradient_start, e1->tracer_gradient_start, tick_blend); + e->tracer_gradient_end = v2_lerp(e0->tracer_gradient_end, e1->tracer_gradient_end, tick_blend); } } } @@ -911,12 +912,33 @@ INTERNAL void user_update(void) /* Draw tracer */ if (entity_has_prop(ent, ENTITY_PROP_TRACER)) { - struct v2 start = ent->tracer_tail; - struct v2 end = xf.og; + struct v2 velocity = ent->tracer_start_velocity; - f32 thickness = 0.0025; - u32 color = RGBA_32_F(1, 1, 1, 1); - draw_solid_line(G.world_canvas, start, end, thickness, color); + struct v2 a = ent->tracer_start; + struct v2 b = xf.og; + struct v2 c = ent->tracer_gradient_start; + struct v2 d = ent->tracer_gradient_end; + + struct v2 vcd = v2_sub(d, c); + struct v2 vca = v2_sub(a, c); + struct v2 vdb = v2_sub(b, d); + struct v2 vdc = v2_neg(vcd); + + f32 opacity_a = 1; + if (v2_dot(velocity, vca) < 0) { + a = c; + opacity_a = 0; + } else { + opacity_a = v2_dot(vcd, vca) / v2_len_sq(vcd); + } + + f32 opacity_b = clamp_f32(1.f - (v2_dot(vdc, vdb) / v2_len_sq(vdc)), 0, 1); + + //f32 thickness = 0.0025; + f32 thickness = 0.005; + u32 color_start = RGBA_32_F(1, 1, 1, opacity_a); + u32 color_end = RGBA_32_F(1, 1, 1, opacity_b); + draw_gradient_line(G.world_canvas, a, b, thickness, color_start, color_end); } /* Draw sprite */ @@ -1331,9 +1353,9 @@ INTERNAL void user_update(void) } } } -#endif #endif } +#endif #endif /* Draw hierarchy */