- Create ui_renderer.cpp/h with all raygui UI panel rendering functions
- Remove UI rendering code from renderer.cpp (421 lines moved)
- Remove UI state fields from RenderState, create separate UIState struct
- Remove raygui dependency from renderer module
- Update main.cpp to initialize UIState and call UI render functions
- Update documentation to reflect new module structure
- Improve separation of concerns between 3D rendering and UI overlays
- Replace wireframe spheres with proper billboard textures
- Spacecraft rendered as cyan circle with arrow (64x64 texture)
- Maneuver markers as directional arrow billboards
- Spacecraft billboards rotate to show velocity direction
- Programmatic texture generation (no external assets)
- Lazy texture loading when spacecraft/maneuvers present
- Proper texture cleanup on renderer shutdown
- Spacecraft rendered as cyan wireframe spheres (fixed size for visibility)
- Maneuver markers as colored cubes (direction-based colors: green=prograde, red=retrograde, etc.)
- Object list now includes spacecraft with '🚀 ' prefix
- Camera follow extended to support spacecraft tracking
- Spacecraft info panel displays local coordinates and maneuver counts
- Maneuver list panel shows pending/executed status with details
- Panel renamed from 'Bodies' to 'Objects'
Merge spacecraft management into simulation module:
- Move Spacecraft struct from maneuver.h to spacecraft.h
- Add spacecraft array to SimulationState (spacecraft, craft_count, max_craft)
- Remove separate SpacecraftState struct and related functions
- Update create_simulation() to require max_craft parameter
- Move spacecraft update logic into update_simulation()
- Make load_spacecraft_config() internal helper, called by load_system_config()
- Update all test files to use new API with 3-parameter create_simulation()
- Handle max_craft=0 case gracefully (no spacecraft allocation)
Test results: 26/27 passing (1 pre-existing SOI test unrelated to changes)
Changes:
- Add previous_selected_body to RenderState
- Detect when selected_body_index changes
- Recalculate camera_offset when switching to new body
- Maintains same camera distance/orientation to new body
Technical details:
- Body selection change detected via previous_selected_body comparison
- When switching to new body:
* Calculate new body position
* Set camera target to new body
* Use existing camera_offset (maintains distance)
* Update camera.position = body_pos + offset
- Allows seamless transitions between bodies at same zoom level
Result: Camera maintains perspective when switching between
celestial bodies, no jarring distance changes.
Changes:
1. Remove all keyboard shortcuts (B, I, F keys)
2. UI panels always shown (body list, info, simulation info)
3. Selecting a body automatically enables camera follow
4. render_info() now uses GuiWindowBox style matching other UI
UI improvements:
- render_info() now uses GuiWindowBox for consistent styling
- Positioned at bottom-left with smaller window (200x280)
- Window close buttons disabled (panels always shown)
- Updated help text to reflect new workflow
User experience:
- Simpler interaction - just select body from list to follow it
- All information always visible
- Consistent UI styling across all panels
Problems fixed:
1. Camera now maintains fixed distance to followed body
2. Camera uses proper up vector and cross products for rotation
Technical changes:
- Added camera_offset and was_following_body to RenderState
- Store offset when follow is first enabled
- Update camera position = body_pos + offset each frame
- Use cross products for proper orbital camera rotation:
- Calculate right vector from up x forward
- Rotate forward vector around right axis
- Update camera offset after each movement
- Zoom controls also update offset when following
Result: Camera maintains consistent perspective and distance
while tracking moving celestial bodies.
Features:
- Add camera_follow_body flag to RenderState
- Update update_camera() to follow selected body when enabled
- F key toggles camera follow (requires body selected)
- Camera still rotates and zooms around followed body
- Removed old focus_camera() function (superseded by new implementation)
- Updated help text to show F key for camera follow toggle
Technical details:
- Camera target updates to body position each frame when following
- Existing rotation/zoom controls work relative to new target position
- Maintains orbital camera control pattern
Issue: GuiListView() always returns 0 (known raygui bug), causing
body selection to never work.
Fix:
- Added body_list_scroll and body_list_active to RenderState for persistence
- Check body_list_active parameter changes instead of return value
- Initialize active state to -1 in main.cpp
Reference: https://github.com/raysan5/raygui/issues/448
- Add raygui as git submodule in ext/raygui/
- Update Makefile to include raygui headers
- Extend RenderState with UI fields (selected_body_index, show_body_list, show_body_info)
- Implement render_body_list_ui() for scrollable body list panel
- Implement render_body_info_ui() for detailed body information panel
- Add 'B' key toggle for body list panel
- Integrate UI rendering into main render loop
- Initialize UI state in main()
- Renamed src/bodies.h to src/simulation.h
- Renamed src/bodies.cpp to src/simulation.cpp
- Updated all include references in src/ and tests/
- Updated Makefile to reference simulation.cpp
- Updated documentation references
Claude
- Fix SOI calculation to use semi_major_axis instead of current distance
This caused incorrect SOI radii for eccentric orbits
- Fix orbit direction: change cross product from r×z to z×r for counter-clockwise orbits
- Add parent body change tracking to headless mode for debugging
- Add debug output enabling in test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extract argument parsing, headless simulation, and GUI simulation into
separate functions. Add initial state capture for comparison in headless mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add --readable (-r) flag for headless mode that displays:
- Positions in AU instead of meters
- Velocities in km/s instead of m/s
- Polar coordinates (r, θ) in AU and degrees
Changes:
- New command line flag: --readable / -r
- Helper functions for formatted output
- Polar angle calculated from atan2(y,x) and converted to 0-360°
- Periodic updates show: Body(r=X.XX AU, θ=Y.Y°)
- Initial/final states show full cartesian + polar coordinates
Makes verification much easier - can instantly see orbital positions
and confirm bodies return to starting angles after full orbits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add --headless/-h flag to run without graphics
- Add --days N flag to specify simulation duration
- Print initial state, periodic updates, and final state
- Useful for testing, debugging, and headless environments
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Orbital mechanics simulation with 2-body physics and SOI transitions.
Core Features:
- 2-body gravitational physics with sphere of influence transitions
- Real-time 3D visualization using raylib
- Configurable star systems via text files
- Interactive controls (camera, pause, speed)
Technical Implementation:
- C-style C++ (structs and functions, no classes)
- Modular architecture (physics, bodies, config loader, renderer)
- Euler integration for orbital mechanics
- SOI detection using Hill sphere approximation
Configuration System:
- Solar system with realistic data (Sun, 8 planets, 5 major moons)
- Binary star system example
- Easy to create custom systems via simple text format
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>