diff --git a/scripts/cube_logic.lua b/scripts/cube_logic.lua index c448235..14dd345 100644 --- a/scripts/cube_logic.lua +++ b/scripts/cube_logic.lua @@ -574,8 +574,8 @@ local function create_room_objects() {room.wall_thickness, room.wall_height, room.half_size}, green_wall), } - -- Add lanterns in the four corners - local lantern_offset = 4.0 + -- Add lanterns in the four corners (adjusted for bigger room) + local lantern_offset = room.half_size - 2.0 -- 2 units from wall objects[#objects + 1] = create_lantern(lantern_offset, lantern_offset) objects[#objects + 1] = create_lantern(-lantern_offset, lantern_offset) objects[#objects + 1] = create_lantern(lantern_offset, -lantern_offset) diff --git a/scripts/dev_commands.py b/scripts/dev_commands.py index f6a876f..8e11bbc 100644 --- a/scripts/dev_commands.py +++ b/scripts/dev_commands.py @@ -324,6 +324,7 @@ def _sync_assets(build_dir: str, dry_run: bool) -> None: ("scripts", ["*.lua"]), ("shaders", ["*.spv"]), ("scripts/models", ["*.stl", "*.obj", "*.fbx"]), + ("config", ["*.json"]), ] print("\n=== Syncing Assets ===") @@ -369,7 +370,7 @@ def run_demo(args: argparse.Namespace) -> None: exe_name = args.target or ("sdl3_app.exe" if IS_WINDOWS else "sdl3_app") binary = str(Path(build_dir) / exe_name) - cmd: list[str] = [binary] + cmd: list[str] = [binary, "-j", "config/seed_runtime.json"] run_args = _strip_leading_double_dash(args.args) if run_args: cmd.extend(run_args) diff --git a/shaders/solid.frag b/shaders/solid.frag index 9791877..cec1102 100644 --- a/shaders/solid.frag +++ b/shaders/solid.frag @@ -4,7 +4,52 @@ layout(location = 0) in vec3 fragColor; layout(location = 1) in vec3 fragWorldPos; layout(location = 0) out vec4 outColor; -void main() { - // Use vertex color directly for solid colors - outColor = vec4(fragColor, 1.0); +// Lantern positions (8 lights) +const vec3 LIGHT_POSITIONS[8] = vec3[8]( + vec3(13.0, 4.5, 13.0), // Corner + vec3(-13.0, 4.5, 13.0), // Corner + vec3(13.0, 4.5, -13.0), // Corner + vec3(-13.0, 4.5, -13.0), // Corner + vec3(0.0, 4.5, 13.0), // Wall midpoint + vec3(0.0, 4.5, -13.0), // Wall midpoint + vec3(13.0, 4.5, 0.0), // Wall midpoint + vec3(-13.0, 4.5, 0.0) // Wall midpoint +); + +const vec3 LIGHT_COLOR = vec3(1.0, 0.9, 0.6); // Warm lantern color +const float LIGHT_INTENSITY = 0.8; +const float AMBIENT_STRENGTH = 0.08; // Low ambient for darker atmosphere + +float calculateAttenuation(float distance) { + // Quadratic attenuation: 1 / (constant + linear*d + quadratic*d^2) + const float kConstant = 1.0; + const float kLinear = 0.09; + const float kQuadratic = 0.032; + return 1.0 / (kConstant + kLinear * distance + kQuadratic * distance * distance); +} + +void main() { + vec3 ambient = AMBIENT_STRENGTH * fragColor; + vec3 lighting = vec3(0.0); + + // Calculate contribution from each lantern + for (int i = 0; i < 8; i++) { + vec3 lightDir = LIGHT_POSITIONS[i] - fragWorldPos; + float distance = length(lightDir); + lightDir = normalize(lightDir); + + // Distance attenuation + float attenuation = calculateAttenuation(distance); + + // Add light contribution + lighting += LIGHT_COLOR * LIGHT_INTENSITY * attenuation; + } + + // Combine ambient and dynamic lighting with surface color + vec3 finalColor = ambient + fragColor * lighting; + + // Clamp to prevent over-bright areas + finalColor = clamp(finalColor, 0.0, 1.0); + + outColor = vec4(finalColor, 1.0); } diff --git a/shaders/solid.frag.spv b/shaders/solid.frag.spv index 45f555f..b11bf63 100644 Binary files a/shaders/solid.frag.spv and b/shaders/solid.frag.spv differ diff --git a/src/services/impl/sdl_window_service.cpp b/src/services/impl/sdl_window_service.cpp index e25de35..22349f0 100644 --- a/src/services/impl/sdl_window_service.cpp +++ b/src/services/impl/sdl_window_service.cpp @@ -263,9 +263,34 @@ void SdlWindowService::PollEvents() { logger_->Trace("SdlWindowService", "PollEvents"); SDL_Event event; while (SDL_PollEvent(&event)) { - // Convert SDL event to application event and publish - PublishEvent(event); - HandleMouseGrabEvent(event); + // Check if this event should trigger mouse grab + bool isGrabTrigger = false; + if (window_ && mouseGrabConfig_.enabled && mouseGrabConfig_.grabOnClick && + event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && + event.button.button == grabMouseButton_) { + isGrabTrigger = true; + if (logger_) { + logger_->Info("SdlWindowService: Mouse grab triggered by click (button=" + + std::to_string(event.button.button) + ")"); + } + ApplyMouseGrab(true); + } + + // Handle release separately (doesn't suppress event) + if (window_ && mouseGrabConfig_.enabled && mouseGrabConfig_.releaseOnEscape && + event.type == SDL_EVENT_KEY_DOWN && + event.key.key == releaseKey_ && + !event.key.repeat) { + if (logger_) { + logger_->Info("SdlWindowService: Mouse grab released by escape key"); + } + ApplyMouseGrab(false); + } + + // Only publish event if it's not the grab-triggering click + if (!isGrabTrigger) { + PublishEvent(event); + } // Check for quit event if (event.type == SDL_EVENT_QUIT || event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED) { @@ -307,9 +332,11 @@ void SdlWindowService::ConfigureMouseGrabBindings() { } if (logger_) { - logger_->Trace("SdlWindowService", "ConfigureMouseGrabBindings", - "grabMouseButton=" + std::to_string(static_cast(grabMouseButton_)) + - ", releaseKey=" + std::to_string(static_cast(releaseKey_))); + logger_->Info("SdlWindowService: Mouse grab config: enabled=" + + std::string(mouseGrabConfig_.enabled ? "true" : "false") + + ", grabOnClick=" + std::string(mouseGrabConfig_.grabOnClick ? "true" : "false") + + ", grabMouseButton=" + std::to_string(static_cast(grabMouseButton_)) + + ", releaseKey=" + std::to_string(static_cast(releaseKey_))); } }