Reusable 3D Earth globe widget (pure OCaml + WebGL)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add Scene.projection and Scene.view frame accessors

Allows custom renderers (e.g. conjunction markers) to access the
per-frame projection and view matrices computed by begin_frame,
without recomputing them.

+31 -26
+14 -15
webgl/scene.ml
··· 5 5 6 6 (** Globe scene: canvas setup, render loop, and layer compositing. 7 7 8 - Bundles the WebGL boilerplate that every globe app needs: 9 - canvas/GL init, resize handling, camera, and the correct draw 10 - order for all layers (stars → earth → grid → orbits → coverage). *) 8 + Bundles the WebGL boilerplate that every globe app needs: canvas/GL init, 9 + resize handling, camera, and the correct draw order for all layers (stars → 10 + earth → grid → orbits → coverage). *) 11 11 12 12 open Brr 13 13 open Brr_canvas ··· 64 64 let camera t = t.camera 65 65 let orbit t = t.orbit 66 66 let coverage t = t.coverage 67 - 68 - let set_grid_spacing t spacing = 69 - t.grid <- Some (Grid.v ~spacing t.gl) 67 + let set_grid_spacing t spacing = t.grid <- Some (Grid.v ~spacing t.gl) 70 68 71 69 (* ------------------------------------------------------------------ *) 72 70 (* Per-frame matrices *) ··· 90 88 in 91 89 if projection_offset <> 0. then proj.(12) <- projection_offset; 92 90 let projection = Globe.Math.Mat4.to_float_array proj in 93 - let view = 94 - Globe.Math.Mat4.to_float_array (Camera.view_matrix t.camera) 95 - in 91 + let view = Globe.Math.Mat4.to_float_array (Camera.view_matrix t.camera) in 96 92 Gl.clear t.gl (Gl.color_buffer_bit lor Gl.depth_buffer_bit); 97 93 { projection; view; width = w; height = h } 98 94 95 + let projection f = f.projection 96 + let view f = f.view 97 + 99 98 (* ------------------------------------------------------------------ *) 100 99 (* Layer drawing with correct compositing order *) 101 100 (* ------------------------------------------------------------------ *) ··· 140 139 if layers.show_earth then 141 140 Earth.draw gl t.earth ~projection:p ~view:v ~dim:layers.earth_dim (); 142 141 (* 3. Grid overlay *) 143 - if layers.show_grid then 144 - (match t.grid with 145 - | Some grid -> 146 - Grid.draw gl grid ~projection:p ~view:v ~color:layers.grid_color 147 - ~alpha:layers.grid_alpha () 148 - | None -> ()); 142 + (if layers.show_grid then 143 + match t.grid with 144 + | Some grid -> 145 + Grid.draw gl grid ~projection:p ~view:v ~color:layers.grid_color 146 + ~alpha:layers.grid_alpha () 147 + | None -> ()); 149 148 (* 4. Orbit trails + satellite dots *) 150 149 if layers.show_orbits then 151 150 Orbit.draw gl t.orbit ~projection:p ~view:v ~dots:layers.orbit_dots;
+17 -11
webgl/scene.mli
··· 1 1 (** Globe scene: canvas setup, render loop, and layer compositing. 2 2 3 - Bundles the WebGL boilerplate that every globe app needs. 4 - Create a scene from a canvas element, then call {!begin_frame} 5 - and {!draw} each animation frame. *) 3 + Bundles the WebGL boilerplate that every globe app needs. Create a scene 4 + from a canvas element, then call {!begin_frame} and {!draw} each animation 5 + frame. *) 6 6 7 7 type t 8 8 (** Opaque scene state: GL context + all renderers. *) 9 9 10 10 val v : ?num_points:int -> ?grid_spacing:float -> Brr.El.t -> t 11 - (** [v ?num_points ?grid_spacing canvas_el] initializes a globe scene 12 - from a canvas element. Sets up GL context, resize handler, camera, 13 - and all renderers. *) 11 + (** [v ?num_points ?grid_spacing canvas_el] initializes a globe scene from a 12 + canvas element. Sets up GL context, resize handler, camera, and all 13 + renderers. *) 14 14 15 15 val gl : t -> Brr_canvas.Gl.t 16 16 (** [gl t] is the WebGL2 context. *) ··· 33 33 (** Per-frame projection and view matrices. *) 34 34 35 35 val begin_frame : t -> ?projection_offset:float -> float -> frame 36 - (** [begin_frame t ?projection_offset dt] updates the camera by [dt] 37 - seconds, computes projection/view matrices, and clears the frame. 38 - [projection_offset] shifts the projection center (for sidebar). *) 36 + (** [begin_frame t ?projection_offset dt] updates the camera by [dt] seconds, 37 + computes projection/view matrices, and clears the frame. [projection_offset] 38 + shifts the projection center (for sidebar). *) 39 + 40 + val projection : frame -> float array 41 + (** [projection frame] is the 4x4 projection matrix as a flat float array. *) 42 + 43 + val view : frame -> float array 44 + (** [view frame] is the 4x4 view matrix as a flat float array. *) 39 45 40 46 (** {1 Layer compositing} *) 41 47 ··· 57 63 (** [default_layers] has stars and earth on, everything else off. *) 58 64 59 65 val draw : t -> frame -> layers -> unit 60 - (** [draw t frame layers] renders all visible layers in the correct 61 - compositing order: stars → earth → grid → orbits → coverage. *) 66 + (** [draw t frame layers] renders all visible layers in the correct compositing 67 + order: stars → earth → grid → orbits → coverage. *)