From dd9d3013d260f27f86b268c203a290f91431d8e5 Mon Sep 17 00:00:00 2001 From: skal Date: Wed, 4 Feb 2026 22:08:56 +0100 Subject: feat: Optional sequence end times and comprehensive effect documentation This milestone implements several key enhancements to the sequencing system and developer documentation: ## Optional Sequence End Times (New Feature) - Added support for explicit sequence termination via [time] syntax - Example: SEQUENCE 0 0 [30.0] forcefully ends all effects at 30 seconds - Updated seq_compiler.cc to parse optional [time] parameter with brackets - Added end_time_ field to Sequence class (default -1.0 = no explicit end) - Modified update_active_list() to check sequence end time and deactivate all effects when reached - Fully backward compatible - existing sequences work unchanged ## Comprehensive Effect Documentation (demo.seq) - Documented all effect constructor parameters (standard: device, queue, format) - Added runtime parameter documentation (time, beat, intensity, aspect_ratio) - Created detailed effect catalog with specific behaviors: * Scene effects: HeptagonEffect, ParticlesEffect, Hybrid3DEffect, FlashCubeEffect * Post-process effects: GaussianBlurEffect, SolarizeEffect, ChromaAberrationEffect, ThemeModulationEffect, FadeEffect, FlashEffect - Added examples section showing common usage patterns - Documented exact parameter behaviors (e.g., blur pulsates 0.5x-2.5x, flash triggers at intensity > 0.7, theme cycles every 8 seconds) ## Code Quality & Verification - Audited all hardcoded 1280x720 dimensions throughout codebase - Verified all shaders use uniforms.resolution and uniforms.aspect_ratio - Confirmed Effect::resize() properly updates width_/height_ members - No issues found - dimension handling is fully dynamic and robust ## Files Changed - tools/seq_compiler.cc: Parse [end_time], generate set_end_time() calls - src/gpu/effect.h: Added end_time_, set_end_time(), get_end_time() - src/gpu/effect.cc: Check sequence end time in update_active_list() - assets/demo.seq: Comprehensive syntax and effect documentation - Generated files updated (timeline.cc, assets_data.cc, music_data.cc) This work establishes a more flexible sequencing system and provides developers with clear documentation for authoring demo timelines. handoff(Claude): Optional sequence end times implemented, effect documentation complete, dimension handling verified. Ready for next phase of development. --- src/gpu/effects/flash_cube_effect.cc | 96 ++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/gpu/effects/flash_cube_effect.cc (limited to 'src/gpu/effects/flash_cube_effect.cc') diff --git a/src/gpu/effects/flash_cube_effect.cc b/src/gpu/effects/flash_cube_effect.cc new file mode 100644 index 0000000..44f6e2b --- /dev/null +++ b/src/gpu/effects/flash_cube_effect.cc @@ -0,0 +1,96 @@ +// This file is part of the 64k demo project. +// It implements the FlashCubeEffect - a flashing background cube with Perlin noise. + +#include "gpu/effects/flash_cube_effect.h" +#include "generated/assets.h" +#include "util/asset_manager.h" +#include +#include + +FlashCubeEffect::FlashCubeEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : Effect(device, queue) { + (void)format; +} + +void FlashCubeEffect::resize(int width, int height) { + width_ = width; + height_ = height; + renderer_.resize(width_, height_); +} + +void FlashCubeEffect::init(MainSequence* demo) { + (void)demo; + WGPUTextureFormat format = demo->format; + + renderer_.init(device_, queue_, format); + renderer_.resize(width_, height_); + + // Texture Manager + texture_manager_.init(device_, queue_); + + // Load Perlin noise texture + size_t size = 0; + const uint8_t* noise_data = GetAsset(AssetId::ASSET_NOISE_TEX, &size); + if (noise_data && size == 256 * 256 * 4) { + texture_manager_.create_texture("noise", 256, 256, noise_data); + renderer_.set_noise_texture(texture_manager_.get_texture_view("noise")); + } else { + std::cerr << "Failed to load NOISE_TEX asset for FlashCubeEffect." << std::endl; + } + + // Create a very large background cube + // Scale and distance ensure it's clearly behind foreground objects + scene_.clear(); + Object3D cube(ObjectType::BOX); + cube.position = vec3(0, 0, 0); + cube.scale = vec3(100.0f, 100.0f, 100.0f); // Much larger cube + cube.color = vec4(0.3f, 0.3f, 0.5f, 1.0f); // Dark blue base color + scene_.add_object(cube); +} + +void FlashCubeEffect::render(WGPURenderPassEncoder pass, float time, float beat, + float intensity, float aspect_ratio) { + // Detect beat changes for flash trigger (using intensity as proxy for beat hits) + // Intensity spikes on beats, so we can use it to trigger flashes + if (intensity > 0.5f && flash_intensity_ < 0.3f) { // High intensity + flash cooled down + flash_intensity_ = 1.0f; // Trigger full flash + } + + // Exponential decay of flash + flash_intensity_ *= 0.90f; // Slower fade for more visible effect + + // Always have base brightness, add flash on top + float base_brightness = 0.2f; + float flash_boost = base_brightness + flash_intensity_ * 0.8f; // 0.2 to 1.0 range + + scene_.objects[0].color = vec4( + 0.4f * flash_boost, // Reddish tint + 0.6f * flash_boost, // More green + 1.0f * flash_boost, // Strong blue for background feel + 1.0f + ); + + // Slowly rotate the cube for visual interest + scene_.objects[0].rotation = quat::from_axis(vec3(0.3f, 1, 0.2f), time * 0.05f); + + // Position camera OUTSIDE the cube looking at it from a distance + // This way we see the cube as a background element + float cam_distance = 150.0f; // Much farther to ensure it's behind everything + float orbit_angle = time * 0.1f; + + camera_.set_look_at( + vec3(std::sin(orbit_angle) * cam_distance, + std::cos(orbit_angle * 0.3f) * 30.0f, + std::cos(orbit_angle) * cam_distance), // Camera orbits around + vec3(0, 0, 0), // Look at cube center + vec3(0, 1, 0) + ); + + camera_.aspect_ratio = aspect_ratio; + // Extend far plane to accommodate distant camera position (150 units + cube size) + camera_.far_plane = 300.0f; + + // Draw the cube + renderer_.draw(pass, scene_, camera_, time); +} -- cgit v1.2.3