vibe coding an orbital mechanics simulation to try out claude code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

8.8 KiB

Rendering System - Technical Reference

Overview

3D visualization system using raylib for interactive orbital mechanics simulation. Supports logarithmic distance scaling, orbit path rendering, spacecraft tracking, and maneuver planning visualization.

Core Data Structure

RenderState (renderer.h)

struct RenderState {
    Camera3D camera;
    double distance_scale;        // Scale factor for distances
    double size_scale;            // Scale factor for body sizes
    int selected_body_index;      // -1 = no selection
    int selected_craft_index;     // -1 = no selection
    int previous_selected_body;    // Previous selected body index
    int body_list_scroll;         // Scroll position for body list
    int body_list_active;         // Active item index in body list
    bool camera_follow_body;       // Whether camera follows selected body
    Vector3 camera_offset;        // Offset from target when following body
    bool was_following_body;      // Previous frame follow state
};

Coordinate Transformation

Simulation to Render Coordinates

The simulation uses an XY plane while rendering uses XZ plane (Y is up in raylib).

Transformation:

  • Simulation (X, Y, Z) → Render (X, -Z, Y)
  • 90-degree rotation around X-axis

Implementation:

Vector3 sim_to_render(Vec3 pos, double scale) {
    return (Vector3){
        (float)(pos.x * scale),
        (float)(-pos.z * scale),
        (float)(pos.y * scale)
    };
}

Scaling Factors

Distance Scale: 1e-9 (1 render unit = 1 billion meters)

  • Optimized for solar system scale
  • Used for position transformations

Size Scale: 1e-9 (same as distance scale)

  • Applied to body radii
  • Minimum visible radius: 0.5 units (ensures tiny bodies are visible)

Radius Scaling:

float scale_radius(double radius, double scale) {
    float scaled = (float)(radius * scale);
    float min_radius = 0.5f;
    return (scaled > min_radius) ? scaled : min_radius;
}

Camera System

Camera Setup

  • Position: (0, 50, 100) initially
  • Target: Origin (0, 0, 0)
  • Up vector: (0, 1, 0)
  • FOV: 45 degrees
  • Projection: Perspective

Camera Controls

Arrow Keys:

  • Left/Right: Orbit around target (horizontal rotation)
  • Up/Down: Zoom in/out (preserve viewing angle)

Camera Follow Mode:

  • Tracks selected body or spacecraft
  • Preserves relative offset when following
  • Updates target position each frame to follow moving objects
  • Maintains camera distance when switching between bodies

Camera Rotation Logic:

  • Uses camera's up vector for horizontal orbit
  • Rotates forward vector around up axis
  • Preserves camera distance from target

Follow State Transitions:

  1. Enable follow: Store current offset from target
  2. Body switch: Recalculate offset to maintain distance
  3. Frame update: Move camera to maintain offset from moving target

Object Rendering

Celestial Bodies

Rendering:

  • Wireframe spheres (DrawSphereWires)
  • Color from body's RGB values
  • Position scaled and transformed to render coordinates
  • Radius scaled with minimum visible size

Order: All bodies rendered after orbit paths

Spacecraft

Rendering:

  • Fixed-size wireframe spheres (5.0 units)
  • Cyan color (0, 255, 255)
  • Position scaled and transformed

Purpose: Visual marker for spacecraft tracking at solar system distances

Maneuver Markers

Rendering:

  • Cubes (DrawCube) colored by burn direction
  • Size based on delta-v magnitude (2-10 units, clamped)
  • Only shown for unexecuted maneuvers
  • Positioned at spacecraft location

Color Coding:

  • PROGRADE: Green (0, 255, 0)
  • RETROGRADE: Red (255, 0, 0)
  • NORMAL: Yellow (255, 255, 0)
  • ANTINORMAL: Orange (255, 165, 0)
  • RADIAL_IN: Magenta (255, 0, 255)
  • RADIAL_OUT: Cyan (0, 255, 255)
  • CUSTOM: White (255, 255, 255)

Render Order: Top layer, after spacecraft

Orbit Rendering

Orbital Basis Calculation

Components:

  • periapsis_dir: Normalized eccentricity vector (points toward periapsis)
  • normal: Normalized angular momentum vector (orbit plane normal)
  • q_vec: Cross product of normal and periapsis_dir (completes basis)

Purpose: Defines orbital plane for transforming orbital elements to Cartesian coordinates

Elliptical Orbits (e < 0.98)

Parameters:

  • Semi-major axis: a = -μ / (2 * specific_energy)
  • Semi-minor axis: b = a * sqrt(1 - e²)
  • Focus offset: c = a * e

Rendering:

  • 100 segments
  • Full orbit (0 to 2π)
  • Drawn as series of line segments in orbital basis

Parabolic Orbits (0.98 ≤ e ≤ 1.02)

Parameters:

  • Semi-latus rectum: p = h² / μ

Rendering:

  • 80 segments
  • True anomaly range: -π0.95 to π0.95 (avoid singularity at ±π)
  • Escape trajectory path

Hyperbolic Orbits (e > 1.02)

Parameters:

  • Semi-major axis: a = μ / (2 * (-specific_energy)) (negative for hyperbola)
  • Semi-latus rectum: p = a * (1 - e²)
  • Max true anomaly: acos(-1/e) * 0.95

Rendering:

  • 60 segments
  • Shows asymptotic behavior approaching true anomaly limit
  • Fast escape trajectory visualization

Orbit Color: Half-intensity body color (128 alpha)

Render Order

  1. Reference grid
  2. Orbit paths (for all bodies with parents)
  3. Bodies
  4. Spacecraft
  5. Maneuver markers

UI System (raygui)

Info Panel (Bottom-Left)

Content:

  • Simulation time (in days)
  • Body count
  • FPS
  • Controls reference
  • Config file name

Dimensions: 300×300 pixels

Objects List (Top-Left)

Content:

  • All celestial bodies (no prefix)
  • All spacecraft (🚀 prefix)
  • Scrollable list view

Interaction:

  • Clicking enables camera follow
  • Updates selected_body_index or selected_craft_index
  • Triggers camera offset calculation

Dimensions: 200×400 pixels

Info Panel (Top-Right)

Content (Body Selected):

  • Name, mass, radius
  • Position (global for root, local for children)
  • Velocity magnitude
  • Eccentricity, semi-major axis
  • Parent body name
  • SOI radius

Content (Spacecraft Selected):

  • Name, mass
  • Local position and velocity
  • Parent body name
  • Pending/Executed maneuver counts

Empty: Displays placeholder panel when nothing selected

Dimensions: 250×300 pixels

Maneuver List (Below Info Panel)

Content (Spacecraft Selected Only):

  • List of maneuvers for selected spacecraft
  • Status prefix: [PENDING] or [DONE]
  • Maneuver names

Details:

  • Next pending maneuver: name and delta-v
  • Last executed maneuver: name, delta-v, execution time
  • "No maneuvers defined" if none exist

Dimensions: 300×400 pixels Position: Y=320 (below info panel)

Rendering Pipeline

Main Loop Sequence

  1. BeginDrawing: Clear background to black
  2. BeginMode3D: Enter 3D rendering
  3. Draw Reference Grid: Subtle gray grid lines
  4. Render Orbit Paths: Calculate and draw all orbits
  5. Render Bodies: Draw all celestial bodies
  6. Render Spacecraft: Draw all spacecraft
  7. Render Maneuver Markers: Draw pending maneuver indicators
  8. EndMode3D: Exit 3D rendering
  9. Render UI Panels: Draw all raygui panels
  10. EndDrawing: Complete frame

Performance Considerations

  • 60 FPS target
  • Wireframe rendering for faster performance
  • Minimum visible size prevents tiny bodies
  • Fixed spacecraft marker size for visibility at distance
  • Clipped orbit segments to avoid infinite paths

Module Functions

Initialization

  • init_renderer(width, height, title) - Setup raylib window
  • close_renderer() - Cleanup raylib
  • setup_camera(render_state) - Initialize camera parameters

Camera

  • update_camera(render_state, sim) - Handle input and camera follow

Rendering

  • render_body(body, render_state) - Draw single celestial body
  • render_spacecraft(craft, render_state) - Draw spacecraft marker
  • render_maneuver_marker(craft, maneuver, render_state) - Draw burn indicator
  • render_simulation(sim, render_state) - Full scene rendering

UI

  • render_info(sim) - Bottom-left info panel
  • render_body_list_ui(sim, render_state) - Objects selection panel
  • render_body_info_ui(sim, render_state) - Top-right info panel
  • render_maneuver_list_ui(sim, render_state) - Maneuver list panel

Scaling

  • scale_position(pos, scale) - Transform simulation to render position
  • scale_radius(radius, scale) - Apply size scaling with minimum

Technical Notes

Raylib Integration

  • Header-only raygui for UI
  • raymath for vector operations
  • Perspective 3D camera
  • Wireframe sphere rendering

Color Handling

  • Body colors: float RGB (0.0-1.0) → byte RGB (0-255)
  • Orbit colors: 50% intensity, 50% alpha
  • Spacecraft: Fixed cyan
  • Maneuvers: Direction-based colors with alpha

Reference Grid

  • Subtle gray lines (20, 20, 20) for minor axes
  • Brighter axes (40, 40, 40) for X and Z zero lines
  • Extends from -500 to 500 in both directions
  • Helps orient user in 3D space

Memory Management

  • UI panels allocate temporary buffers for lists
  • List text freed after rendering
  • No persistent UI state allocation