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

Configure Feed

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

globe: drop dead state and useless signature params

- visibility: remove [filter_visible_indexed] (never called, identical
to [filter_visible] with List.filteri whose index is ignored).
- heatmap: drop [lat_bins]/[lon_bins]/[max_count] record fields; they
were computed into [t] but never read externally (no accessors in
mli) or internally. The normalization uses [max_count] only as a
local for density scaling.
- camera: [tween_speed] was declared mutable but only ever read.
- orbit: [trail.head_idx] was stored but never read — [add_trail] uses
the parameter to size the VAO so the field was pure vestige. Also
drop the [~proj ~vw] labels on [draw_trails]: projection/view
uniforms are already bound by the caller before the trail pass.
- scene: [canvas_el] was stored on [t] but never accessed via
[t.canvas_el]; resize/camera-attach closures use the constructor
parameter directly.

+9 -17
+2 -2
lib/heatmap.ml
··· 15 15 density : float; (** Normalized density [0, 1]. *) 16 16 } 17 17 18 - type t = { cells : cell array; lat_bins : int; lon_bins : int; max_count : int } 18 + type t = { cells : cell array } 19 19 20 20 (** Convert a GL position (Y=up) to lat/lon in degrees. *) 21 21 let gl_to_latlon (pos : Math.Vec3.t) = ··· 61 61 let count = grid.(idx) in 62 62 { lat; lon; count; density = Float.of_int count /. max_f }) 63 63 in 64 - { cells; lat_bins; lon_bins; max_count } 64 + { cells } 65 65 66 66 (** Get only non-empty cells. *) 67 67 let active_cells t = Array.to_list t.cells |> List.filter (fun c -> c.count > 0)
-4
lib/visibility.ml
··· 37 37 let filter_visible ~camera_pos positions = 38 38 List.filter (is_visible ~camera_pos) positions 39 39 40 - (** Filter with indices preserved. Returns [(index, position)] pairs. *) 41 - let filter_visible_indexed ~camera_pos positions = 42 - List.filteri (fun _i pos -> is_visible ~camera_pos pos) positions 43 - 44 40 (** {1 Level of detail} *) 45 41 46 42 type lod = Full | Dot_only | Hidden
+1 -1
lib/webgl/camera.ml
··· 18 18 mutable last_y : float; 19 19 mutable auto_rotate : bool; 20 20 mutable target : target option; 21 - mutable tween_speed : float; 21 + tween_speed : float; 22 22 } 23 23 24 24 let theta t = t.theta
+6 -8
lib/webgl/orbit.ml
··· 83 83 type trail = { 84 84 vao : Gl.vertex_array_object; 85 85 num_points : int; 86 - head_idx : int; 87 86 color : Globe.Color.t; 88 87 } 89 - (** A trail: array of positions ordered past→future. [head_idx] marks where the 90 - satellite currently is (0-based). Points before head_idx are the past trail; 91 - after are the prediction. *) 88 + (** A trail: array of positions rendered past→future from a single VAO. *) 92 89 93 90 type dot = { pos : Globe.Math.Vec3.t; color : Globe.Color.t } 94 91 ··· 175 172 Gl.enable_vertex_attrib_array gl 1; 176 173 Gl.vertex_attrib_pointer gl 1 1 Gl.float false 16 12; 177 174 Gl.bind_vertex_array gl None; 178 - t.trails <- { vao; num_points = n; head_idx = n - 1; color } :: t.trails 175 + t.trails <- { vao; num_points = n; color } :: t.trails 179 176 end 180 177 181 178 let add_line gl t positions ~color = ··· 220 217 Gl.draw_arrays gl Gl.points 0 1; 221 218 Gl.bind_vertex_array gl None 222 219 223 - let draw_trails gl t ~proj ~vw trails = 220 + (* Projection/view uniforms are bound by [draw] before calling this helper. *) 221 + let draw_trails gl t trails = 224 222 List.iter 225 223 (fun (tr : trail) -> 226 224 let r, g, b = tr.color in ··· 240 238 Gl.uniform3f gl t.trail_u_camera cp.x cp.y cp.z; 241 239 Gl.uniform1f gl t.trail_u_far far; 242 240 (* Ghost orbits first (behind trails) *) 243 - draw_trails gl t ~proj ~vw t.ghosts; 241 + draw_trails gl t t.ghosts; 244 242 (* Active trails *) 245 - draw_trails gl t ~proj ~vw t.trails; 243 + draw_trails gl t t.trails; 246 244 (* Satellite dots *) 247 245 List.iter 248 246 (fun (d : dot) ->
-2
lib/webgl/scene.ml
··· 24 24 25 25 type t = { 26 26 gl : Gl.t; 27 - canvas_el : El.t; 28 27 camera : Camera.t; 29 28 earth : Earth.t; 30 29 stars : Stars.t; ··· 71 70 Gl.clear_color gl 0.0 0.0 0.02 1.0; 72 71 { 73 72 gl; 74 - canvas_el; 75 73 camera; 76 74 earth = Earth.v ~num_points gl; 77 75 stars = Stars.v gl;