diff --git a/src/pp/pp_sim/pp_sim_core.h b/src/pp/pp_sim/pp_sim_core.h index 7be9a0d6..b794778b 100644 --- a/src/pp/pp_sim/pp_sim_core.h +++ b/src/pp/pp_sim/pp_sim_core.h @@ -35,6 +35,8 @@ Struct(S_Shape) // TODO: Move boolean fields into bitwise property flags +// TODO: Pack efficiently, deduplicate redundant fields + Struct(S_Ent) { ////////////////////////////// diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 46b6d372..7a1aa2b7 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -72,6 +72,19 @@ String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey) 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 @@ -2370,8 +2383,6 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Process vis commands - // b32 should_clear_stains = !TweakBool("Persist stains", 0); - b32 should_clear_stains = 0; b32 should_clear_particles = 0; 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; - case V_CmdKind_clear_stains: - { - should_clear_stains = 1; - } break; - case V_CmdKind_clear_particles: { should_clear_particles = 1; @@ -2626,34 +2632,25 @@ void V_TickForever(WaveLaneCtx *lane) 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; flags |= V_ParticleFlag_StainOnPrune; if (TweakBool("Emitter stain trail", 0)) { flags |= V_ParticleFlag_StainTrail; } - - emitter->flags = flags; - - Vec2 dir = victim_raycast.normal; - emitter->pos = victim_raycast.p; - - f32 count = TweakFloat("Emitter count", 50, 0, 10000); + // f32 count = TweakFloat("Emitter count", 50, 0, 10000); + f32 count = TweakFloat("Emitter count", 50, 1, 1000); f32 speed = TweakFloat("Emitter speed", 10, 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", 0.1, 0, 1) * Tau; - emitter->count = count; - // emitter->count = 100; - // emitter->count = 500; + V_Emitter *emitter = V_PushEmitter(count); + emitter->flags = flags; + + Vec2 dir = victim_raycast.normal; + emitter->pos = victim_raycast.p; + emitter->speed = speed; emitter->speed_spread = speed * 2; @@ -2678,9 +2675,6 @@ void V_TickForever(WaveLaneCtx *lane) // V_DrawPoint(victim_raycast.p, Color_Green); // 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 { - ////////////////////////////// - //- 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 @@ -2908,7 +2887,7 @@ void V_TickForever(WaveLaneCtx *lane) params.max_particles = max_particles; 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.stains = gpu_stains_ref; } diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index e31bc7f9..f911bb2d 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -15,7 +15,6 @@ 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(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 ), ) \ /* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ @@ -315,6 +314,7 @@ V_Frame *V_LastFrame(void); V_Cmd *V_PushVisCmd(String name); S_Cmd *V_PushSimCmd(S_CmdKind kind); String V_StringFromHotkey(Arena *arena, V_Hotkey hotkey); +V_Emitter *V_PushEmitter(u32 particle_count); //////////////////////////////////////////////////////////// //~ Draw helpers diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index 0f835056..b78e144c 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -304,17 +304,15 @@ ComputeShader(V_SimParticlesCS, 64) // f32 speed_rand = speed_noise / (f32)0xFFFF; // f32 angle_rand = angle_noise / (f32)0xFFFF; - f32 rand_speed = (f32)((seed >> 0) & 0xFF) / (f32)0xFF - 0.5; - f32 rand_angle = (f32)((seed >> 8) & 0xFF) / (f32)0xFF - 0.5; - f32 rand_falloff = (f32)((seed >> 16) & 0xFF) / (f32)0xFF - 0.5; - f32 rand_r = (f32)((seed >> 24) & 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 rand_speed = (f32)((seed >> 0) & 0xFFFF) / (f32)0xFFFF - 0.5; + f32 rand_angle = (f32)((seed >> 16) & 0xFFFF) / (f32)0xFFFF - 0.5; + f32 rand_falloff = (f32)((seed >> 32) & 0xFFFF) / (f32)0xFFFF - 0.5; + f32 rand_color = (f32)((seed >> 48) & 0xFF) / (f32)0xFF - 0.5; f32 speed = emitter.speed + rand_speed * emitter.speed_spread; f32 angle = emitter.angle + rand_angle * emitter.angle_spread; 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.pos = emitter.pos; diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index d9ab5693..e3a60912 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -1,4 +1,4 @@ -#define V_CellsPerMeter 48.0 +#define V_CellsPerMeter 40.0 #define V_CellsPerSqMeter (V_CellsPerMeter * V_CellsPerMeter) ////////////////////////////////////////////////////////////