This commit is contained in:
jacob 2026-01-07 02:41:29 -06:00
parent d0e119c476
commit 254c6c4126
5 changed files with 150 additions and 171 deletions

View File

@ -35,6 +35,8 @@ Struct(S_Shape)
// TODO: Move boolean fields into bitwise property flags // TODO: Move boolean fields into bitwise property flags
// TODO: Pack efficiently, deduplicate redundant fields
Struct(S_Ent) Struct(S_Ent)
{ {
////////////////////////////// //////////////////////////////

View File

@ -72,6 +72,19 @@ String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey)
return StringFromList(arena, parts, Lit(" + ")); return StringFromList(arena, parts, Lit(" + "));
} }
V_Emitter *V_PushEmitter(u32 particle_count)
{
V_Frame *frame = V_CurrentFrame();
V_EmitterNode *en = PushStruct(frame->arena, V_EmitterNode);
SllQueuePush(frame->first_emitter_node, frame->last_emitter_node, en);
frame->emitters_count += 1;
V_Emitter *emitter = &en->emitter;
emitter->count = particle_count;
emitter->first_particle_seq = V.particle_seq;
V.particle_seq += emitter->count;
return emitter;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Draw helpers //~ Draw helpers
@ -2370,8 +2383,6 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Process vis commands //- Process vis commands
// b32 should_clear_stains = !TweakBool("Persist stains", 0);
b32 should_clear_stains = 0;
b32 should_clear_particles = 0; b32 should_clear_particles = 0;
for (V_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next) for (V_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
{ {
@ -2510,11 +2521,6 @@ void V_TickForever(WaveLaneCtx *lane)
} }
} break; } break;
case V_CmdKind_clear_stains:
{
should_clear_stains = 1;
} break;
case V_CmdKind_clear_particles: case V_CmdKind_clear_particles:
{ {
should_clear_particles = 1; should_clear_particles = 1;
@ -2626,34 +2632,25 @@ void V_TickForever(WaveLaneCtx *lane)
if (closest_victim->valid) if (closest_victim->valid)
{ {
V_Emitter *emitter = 0;
{
V_EmitterNode *en = PushStruct(frame->arena, V_EmitterNode);
SllQueuePush(frame->first_emitter_node, frame->last_emitter_node, en);
frame->emitters_count += 1;
emitter = &en->emitter;
}
V_ParticleFlag flags = 0; V_ParticleFlag flags = 0;
flags |= V_ParticleFlag_StainOnPrune; flags |= V_ParticleFlag_StainOnPrune;
if (TweakBool("Emitter stain trail", 0)) if (TweakBool("Emitter stain trail", 0))
{ {
flags |= V_ParticleFlag_StainTrail; flags |= V_ParticleFlag_StainTrail;
} }
// f32 count = TweakFloat("Emitter count", 50, 0, 10000);
emitter->flags = flags; f32 count = TweakFloat("Emitter count", 50, 1, 1000);
Vec2 dir = victim_raycast.normal;
emitter->pos = victim_raycast.p;
f32 count = TweakFloat("Emitter count", 50, 0, 10000);
f32 speed = TweakFloat("Emitter speed", 10, 0, 100); f32 speed = TweakFloat("Emitter speed", 10, 0, 100);
f32 falloff = TweakFloat("Emitter falloff", 30, 0, 100); f32 falloff = TweakFloat("Emitter falloff", 30, 0, 100);
// f32 angle_spread = TweakFloat("Emitter spread", Tau / 20, 0, Tau); // f32 angle_spread = TweakFloat("Emitter spread", Tau / 20, 0, Tau);
f32 angle_spread = TweakFloat("Emitter spread", 0.1, 0, 1) * Tau; f32 angle_spread = TweakFloat("Emitter spread", 0.1, 0, 1) * Tau;
emitter->count = count; V_Emitter *emitter = V_PushEmitter(count);
// emitter->count = 100; emitter->flags = flags;
// emitter->count = 500;
Vec2 dir = victim_raycast.normal;
emitter->pos = victim_raycast.p;
emitter->speed = speed; emitter->speed = speed;
emitter->speed_spread = speed * 2; emitter->speed_spread = speed * 2;
@ -2678,9 +2675,6 @@ void V_TickForever(WaveLaneCtx *lane)
// V_DrawPoint(victim_raycast.p, Color_Green); // V_DrawPoint(victim_raycast.p, Color_Green);
// V_DrawLine(victim_raycast.p, AddVec2(victim_raycast.p, MulVec2(victim_raycast.normal, 0.5)), Color_White); // V_DrawLine(victim_raycast.p, AddVec2(victim_raycast.p, MulVec2(victim_raycast.normal, 0.5)), Color_White);
emitter->first_particle_seq = V.particle_seq;
V.particle_seq += emitter->count;
} }
@ -2692,149 +2686,134 @@ void V_TickForever(WaveLaneCtx *lane)
} }
} }
//////////////////////////////
//- Spawn test emitter
// Spawn test emitter
if (frame->held_buttons[Button_F])
{
V_Emitter *emitter = V_PushEmitter(25);;
Vec2 dir = frame->look;
emitter->pos = frame->world_cursor;
emitter->angle = AngleFromVec2(dir);
// emitter->count = 100;
emitter->speed = 10;
emitter->color_lin = LinearFromSrgb(Color_Yellow);
emitter->seed = RandU64FromState(&frame->rand);
emitter->speed_spread = 1;
// emitter->angle_spread = 1;
// emitter->angle_spread = 0.5;
emitter->angle_spread = Tau / 4;
// emitter->angle_spread = Tau;
}
//////////////////////////////
//- Draw entities
// for (S_Ent *ent = S_FirstEnt(world); ent->valid; ent = S_NextEnt(ent))
// {
// Xform ent_to_world_xf = ent->xf;
// Xform ent_to_draw_xf = MulXform(frame->xf.world_to_draw, ent_to_world_xf);
// S_Shape draw_shape = S_MulXformShape(ent_to_draw_xf, ent->local_shape);
// f32 opacity = 0.5;
// b32 is_visible = 1;
// if (is_visible)
// {
// // // Draw shape
// // {
// // Vec4 color = Color_Purple;
// // color.w *= opacity;
// // i32 detail = 32;
// // V_DrawShape(draw_shape, color, detail, V_DrawFlag_Line);
// // }
// // Draw weapon
// // if (ent->has_weapon)
// // {
// // Vec4 color = Color_Cyan;
// // color.w *= opacity;
// // f32 width = 0.1;
// // f32 height = 0.75;
// // S_Shape local_shape = S_ShapeFromDesc(
// // .count = 4,
// // .points = {
// // VEC2(-width / 2, -height), VEC2(width / 2, -height),
// // VEC2(width / 2, 0), VEC2(-width / 2, 0),
// // }
// // );
// // Xform local_xf = XformFromTrs(TRS(.t = { 0, 0 }, .r = Tau / 4));
// // Xform xf = MulXform(ent_to_draw_xf, local_xf);
// // S_Shape shape = S_MulXformShape(xf, local_shape);
// // V_DrawShape(shape, color, 10, V_DrawFlag_Line);
// // }
// // // Draw aabb
// // {
// // Vec4 color = Color_Orange;
// // color.w *= opacity;
// // Rng2 bb = S_BoundingBoxFromShape(draw_shape);
// // V_DrawRect(bb, color, V_DrawFlag_Line);
// // }
// }
// }
//////////////////////////////
//- Draw sim debug shapes
for (u64 desc_idx = 0; desc_idx < sim_debug_draw_descs_count; ++desc_idx)
{
S_DebugDrawDesc *desc = &sim_debug_draw_descs[desc_idx];
Vec4 color = Vec4FromU32(desc->srgb32);
i32 detail = 24;
f32 radius = 5;
switch(desc->kind)
{
case S_DebugDrawKind_Point:
{
Vec2 ui_p = MulXformV2(frame->xf.world_to_ui, desc->point.p);
S_Shape ui_shape = S_ShapeFromDesc(
.count = 1,
.points = { ui_p },
.radius = radius
);
V_DrawShape(ui_shape, color, detail, V_DrawFlag_None);
} break;
case S_DebugDrawKind_Line:
{
Vec2 ui_p0 = MulXformV2(frame->xf.world_to_ui, desc->line.p0);
Vec2 ui_p1 = MulXformV2(frame->xf.world_to_ui, desc->line.p1);
V_DrawLine(ui_p0, ui_p1, color);
} break;
case S_DebugDrawKind_Rect:
{
Rng2 ui_rect = Zi;
ui_rect.p0 = MulXformV2(frame->xf.world_to_ui, desc->rect.p0);
ui_rect.p1 = MulXformV2(frame->xf.world_to_ui, desc->rect.p1);
V_DrawRect(ui_rect, color, V_DrawFlag_Line);
} break;
case S_DebugDrawKind_Shape:
{
S_Shape ui_shape = S_MulXformShape(frame->xf.world_to_ui, desc->shape);
// V_DrawShape(ui_shape, color, detail, V_DrawFlag_Line);
V_DrawShape(ui_shape, color, detail, V_DrawFlag_None);
} break;
}
}
////////////////////////////// //////////////////////////////
//- Render //- Render
{ {
//////////////////////////////
//- Draw entities
for (S_Ent *ent = S_FirstEnt(world); ent->valid; ent = S_NextEnt(ent))
{
Xform ent_to_world_xf = ent->xf;
Xform ent_to_draw_xf = MulXform(frame->xf.world_to_draw, ent_to_world_xf);
S_Shape draw_shape = S_MulXformShape(ent_to_draw_xf, ent->local_shape);
f32 opacity = 0.5;
b32 is_visible = 1;
if (is_visible)
{
// // Draw shape
// {
// Vec4 color = Color_Purple;
// color.w *= opacity;
// i32 detail = 32;
// V_DrawShape(draw_shape, color, detail, V_DrawFlag_Line);
// }
// Draw weapon
// if (ent->has_weapon)
// {
// Vec4 color = Color_Cyan;
// color.w *= opacity;
// f32 width = 0.1;
// f32 height = 0.75;
// S_Shape local_shape = S_ShapeFromDesc(
// .count = 4,
// .points = {
// VEC2(-width / 2, -height), VEC2(width / 2, -height),
// VEC2(width / 2, 0), VEC2(-width / 2, 0),
// }
// );
// Xform local_xf = XformFromTrs(TRS(.t = { 0, 0 }, .r = Tau / 4));
// Xform xf = MulXform(ent_to_draw_xf, local_xf);
// S_Shape shape = S_MulXformShape(xf, local_shape);
// V_DrawShape(shape, color, 10, V_DrawFlag_Line);
// }
// // Draw aabb
// {
// Vec4 color = Color_Orange;
// color.w *= opacity;
// Rng2 bb = S_BoundingBoxFromShape(draw_shape);
// V_DrawRect(bb, color, V_DrawFlag_Line);
// }
}
}
//////////////////////////////
//- Draw sim debug shapes
for (u64 desc_idx = 0; desc_idx < sim_debug_draw_descs_count; ++desc_idx)
{
S_DebugDrawDesc *desc = &sim_debug_draw_descs[desc_idx];
Vec4 color = Vec4FromU32(desc->srgb32);
i32 detail = 24;
f32 radius = 5;
switch(desc->kind)
{
case S_DebugDrawKind_Point:
{
Vec2 ui_p = MulXformV2(frame->xf.world_to_ui, desc->point.p);
S_Shape ui_shape = S_ShapeFromDesc(
.count = 1,
.points = { ui_p },
.radius = radius
);
V_DrawShape(ui_shape, color, detail, V_DrawFlag_None);
} break;
case S_DebugDrawKind_Line:
{
Vec2 ui_p0 = MulXformV2(frame->xf.world_to_ui, desc->line.p0);
Vec2 ui_p1 = MulXformV2(frame->xf.world_to_ui, desc->line.p1);
V_DrawLine(ui_p0, ui_p1, color);
} break;
case S_DebugDrawKind_Rect:
{
Rng2 ui_rect = Zi;
ui_rect.p0 = MulXformV2(frame->xf.world_to_ui, desc->rect.p0);
ui_rect.p1 = MulXformV2(frame->xf.world_to_ui, desc->rect.p1);
V_DrawRect(ui_rect, color, V_DrawFlag_Line);
} break;
case S_DebugDrawKind_Shape:
{
S_Shape ui_shape = S_MulXformShape(frame->xf.world_to_ui, desc->shape);
// V_DrawShape(ui_shape, color, detail, V_DrawFlag_Line);
V_DrawShape(ui_shape, color, detail, V_DrawFlag_None);
} break;
}
}
//////////////////////////////
//- Spawn test emitter
// Spawn test emitter
if (frame->held_buttons[Button_F])
{
V_Emitter *emitter = 0;
{
V_EmitterNode *en = PushStruct(frame->arena, V_EmitterNode);
SllQueuePush(frame->first_emitter_node, frame->last_emitter_node, en);
frame->emitters_count += 1;
emitter = &en->emitter;
}
Vec2 dir = frame->look;
emitter->pos = frame->world_cursor;
emitter->angle = AngleFromVec2(dir);
emitter->count = 25;
// emitter->count = 100;
emitter->speed = 10;
emitter->color_lin = LinearFromSrgb(Color_Yellow);
emitter->seed = RandU64FromState(&frame->rand);
emitter->speed_spread = 1;
// emitter->angle_spread = 1;
// emitter->angle_spread = 0.5;
emitter->angle_spread = Tau / 4;
// emitter->angle_spread = Tau;
emitter->first_particle_seq = V.particle_seq;
V.particle_seq += emitter->count;
}
////////////////////////////// //////////////////////////////
//- Begin gpu frame //- Begin gpu frame
@ -2908,7 +2887,7 @@ void V_TickForever(WaveLaneCtx *lane)
params.max_particles = max_particles; params.max_particles = max_particles;
params.particles = gpu_particles_ref; params.particles = gpu_particles_ref;
params.should_clear_stains = should_clear_stains; params.should_clear_stains = should_clear_particles;
params.cells = gpu_cells_ref; params.cells = gpu_cells_ref;
params.stains = gpu_stains_ref; params.stains = gpu_stains_ref;
} }

View File

@ -15,7 +15,6 @@
X(spawn, Spawn/Teleport Player, V_CmdDescFlag_None, V_HOTKEY( Button_T ), ) \ X(spawn, Spawn/Teleport Player, V_CmdDescFlag_None, V_HOTKEY( Button_T ), ) \
X(spawn_dummy, Spawn Dummy, V_CmdDescFlag_None, V_HOTKEY( Button_R ), ) \ X(spawn_dummy, Spawn Dummy, V_CmdDescFlag_None, V_HOTKEY( Button_R ), ) \
X(delete, Delete entity at cursor, V_CmdDescFlag_None, V_HOTKEY( Button_M2 ), ) \ X(delete, Delete entity at cursor, V_CmdDescFlag_None, V_HOTKEY( Button_M2 ), ) \
X(clear_stains, Clear stains, V_CmdDescFlag_None, V_HOTKEY( Button_C, .alt = 1 ), ) \
X(clear_particles, Clear particles, V_CmdDescFlag_None, V_HOTKEY( Button_C ), ) \ X(clear_particles, Clear particles, V_CmdDescFlag_None, V_HOTKEY( Button_C ), ) \
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
@ -315,6 +314,7 @@ V_Frame *V_LastFrame(void);
V_Cmd *V_PushVisCmd(String name); V_Cmd *V_PushVisCmd(String name);
S_Cmd *V_PushSimCmd(S_CmdKind kind); S_Cmd *V_PushSimCmd(S_CmdKind kind);
String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey); String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey);
V_Emitter *V_PushEmitter(u32 particle_count);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Draw helpers //~ Draw helpers

View File

@ -304,17 +304,15 @@ ComputeShader(V_SimParticlesCS, 64)
// f32 speed_rand = speed_noise / (f32)0xFFFF; // f32 speed_rand = speed_noise / (f32)0xFFFF;
// f32 angle_rand = angle_noise / (f32)0xFFFF; // f32 angle_rand = angle_noise / (f32)0xFFFF;
f32 rand_speed = (f32)((seed >> 0) & 0xFF) / (f32)0xFF - 0.5; f32 rand_speed = (f32)((seed >> 0) & 0xFFFF) / (f32)0xFFFF - 0.5;
f32 rand_angle = (f32)((seed >> 8) & 0xFF) / (f32)0xFF - 0.5; f32 rand_angle = (f32)((seed >> 16) & 0xFFFF) / (f32)0xFFFF - 0.5;
f32 rand_falloff = (f32)((seed >> 16) & 0xFF) / (f32)0xFF - 0.5; f32 rand_falloff = (f32)((seed >> 32) & 0xFFFF) / (f32)0xFFFF - 0.5;
f32 rand_r = (f32)((seed >> 24) & 0xFF) / (f32)0xFF - 0.5; f32 rand_color = (f32)((seed >> 48) & 0xFF) / (f32)0xFF - 0.5;
f32 rand_g = (f32)((seed >> 32) & 0xFF) / (f32)0xFF - 0.5;
f32 rand_b = (f32)((seed >> 48) & 0xFF) / (f32)0xFF - 0.5;
f32 speed = emitter.speed + rand_speed * emitter.speed_spread; f32 speed = emitter.speed + rand_speed * emitter.speed_spread;
f32 angle = emitter.angle + rand_angle * emitter.angle_spread; f32 angle = emitter.angle + rand_angle * emitter.angle_spread;
f32 velocity_falloff = emitter.velocity_falloff + rand_falloff * emitter.velocity_falloff; f32 velocity_falloff = emitter.velocity_falloff + rand_falloff * emitter.velocity_falloff;
Vec3 color = emitter.color_lin.rgb + Vec3(rand_r, rand_g, rand_b) * emitter.color_spread; Vec3 color = emitter.color_lin.rgb + rand_color * emitter.color_spread;
particle.flags = emitter.flags; particle.flags = emitter.flags;
particle.pos = emitter.pos; particle.pos = emitter.pos;

View File

@ -1,4 +1,4 @@
#define V_CellsPerMeter 48.0 #define V_CellsPerMeter 40.0
#define V_CellsPerSqMeter (V_CellsPerMeter * V_CellsPerMeter) #define V_CellsPerSqMeter (V_CellsPerMeter * V_CellsPerMeter)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////