Rust library for generating evenly distributed sample points on a sphere, with surface topology (Delaunay wireframe, Voronoi cells, pathfinding), Perlin terrain, and Godot 4 integration.
Coordinates are Y-up, right-handed, matching Godot 4's default 3D frame.
| Crate / path | Role |
|---|---|
fibonacci_sphere (root) |
Core library — points, topology, terrain, geography |
examples/sphere_lattice_visualizer |
Bevy desktop app for comparing distribution methods |
extensions/fibonacci_sphere_gd |
Godot 4 GDExtension (cdylib) |
godot/ |
Godot 4 demo project |
docs/ |
Architecture, Godot API, project guide |
fibonacci/
├── src/ # Core library
├── tests/ # Integration tests
├── examples/sphere_lattice_visualizer/
├── extensions/fibonacci_sphere_gd/
├── godot/
└── docs/
├── architecture.md # Workspace layout and dependencies
├── godot.md # GDExtension API
└── description.md # Project guide (Python devs)
See docs/architecture.md for how the core library, visualizer, and Godot extension relate.
use fibonacci_sphere::{DistributionMethod, PerlinNoiseConfig, SphereLattice};
let lattice = SphereLattice::generate(DistributionMethod::CanonicalMidpoint, 100, 1.0)?;
let points = lattice.points();
let flat = lattice.positions_flat(); // [x0,y0,z0, x1,y1,z1, ...]
let mut rng = rand::rngs::StdRng::seed_from_u64(42);
let terrain = lattice.generate_terrain(PerlinNoiseConfig::default(), &mut rng);
let areas = lattice.terrain_area_polygons(&terrain);
let mesh = lattice.combined_terrain_mesh(&terrain, Default::default());SphereLattice is the main handle: generated SpherePoints,
method, radius, wireframe, routing graph, terrain, and geography queries.
| Module | Responsibility |
|---|---|
methods |
Six distribution algorithms, ε lookup tables, MethodInfo |
point |
SpherePoint, golden-ratio constant, spherical ↔ Cartesian |
topology |
Spherical Delaunay, Voronoi cells, SurfaceGraph, pathfinding |
terrain |
Perlin and other assigners, area polygons, border kinds (coastline, etc.) |
render |
Combined terrain meshes, coastline segments, line ribbon meshes |
geography |
Pole/equator angular distances, vertices within angular bands |
neighbors |
Closest-neighbor queries and distance binning |
error |
SphereError |
| Variant | Typical use |
|---|---|
CanonicalMidpoint |
Default — fast golden-angle spiral |
Canonical |
Baseline Fibonacci lattice (north pole at index 0) |
OffsetPacking |
Optimized minimum neighbor distance (Roberts 2018) |
OffsetPackingWithPoles |
Offset packing with explicit ±Y pole samples |
OffsetAverageNeighbor |
More uniform local neighbor spacing |
LatitudeLongitude |
Lat–long grid baseline |
Each method exposes MethodInfo via method.info() or method.format_description().
Wireframe edges come from spherical Delaunay triangulation (stereographic projection + planar Delaunay). The same graph powers routing and Voronoi terrain areas.
let edges = lattice.wireframe_edges();
let graph = lattice.surface_graph();
let path = graph.shortest_path(from_index, to_index)?;
// Terrain-filtered routing (requires generated terrain)
let path = graph.shortest_path_with_allowed_terrain(
from_index, to_index, terrain.as_slice(), &[TerrainType::Land, TerrainType::Mountain],
)?;- Edge weights are geodesic arc length on the sphere.
- Prefer
surface_graph()in hot loops;SphereLattice::shortest_surface_pathrebuilds the graph each call.
TerrainType: Land, Water, DeepWater, Mountain, Ice, IceMountain.
PerlinNoiseConfig drives elevation bands and optional polar ice
caps grown by flood fill from each pole (north_polar_ice_distance, south_polar_ice_distance in
radians, plus resistance and polar_ice_latitude_cost). Within a flooded cap, temperate terrain
becomes Ice / IceMountain. Voronoi cells become TerrainAreaPolygon
with AreaBorderKind per edge (Coastline = sea-level crossing). For
rendering, render provides build_combined_terrain_mesh,
coastline_segment_positions, and build_line_ribbon_mesh.
| Feature | Effect |
|---|---|
default |
Enables terrain — points, topology, Perlin terrain, geography, pathfinding |
terrain |
Perlin terrain, Voronoi areas, filtered routing (noise, rand deps) |
Build points-only without terrain deps:
cargo build -p fibonacci_sphere --no-default-featuresInteractive comparison of distribution methods with Delaunay wireframe, Voronoi terrain fill (combined meshes by terrain type), coastline borders, and Perlin controls.
sphere_lattice_visualizer uses Bevy and links against system libraries for audio, windowing,
input, and Vulkan. The core library and Godot extension do not need these packages.
On Debian/Ubuntu/WSL:
./scripts/linux/setup-bevy-deps.shManual install (same packages as the script):
sudo apt install build-essential pkg-config libasound2-dev libudev-dev \
libx11-dev libxcursor-dev libxi-dev libxrandr-dev \
libwayland-dev libxkbcommon-dev libvulkan-dev| Package | Purpose |
|---|---|
build-essential |
C/C++ linker (cc) for native build scripts |
pkg-config |
Locate system libraries during build.rs |
libasound2-dev |
ALSA audio |
libudev-dev |
Input and device enumeration |
libx11-dev, libxcursor-dev, libxi-dev, libxrandr-dev |
X11 windowing |
libwayland-dev, libxkbcommon-dev |
Wayland and keyboard |
libvulkan-dev |
Vulkan rendering (WGPU) |
See also Bevy Linux setup.
Running the GUI on WSL requires WSLg (Windows 11) or an X server. Building does not require a display.
cargo run -p sphere_lattice_visualizer --release| Key | Action |
|---|---|
| M | Cycle distribution method |
| + / - | Point count ±10 |
| [ / ] | Radius ±0.1 |
| H | Toggle Delaunay wireframe |
| B | Toggle Voronoi area borders |
| C | Toggle Voronoi terrain fill |
| , / . | Perlin mountain threshold ±0.05 |
| 9 / 0 | Deep water threshold ±0.05 |
| ; / ' | Perlin spacing factor ±0.1 |
| 1 / 2 | North polar ice distance ±0.05 rad |
| 3 / 4 | South polar ice distance ±0.05 rad |
| R | New terrain seed |
| Drag / scroll | Orbit / zoom |
Source: examples/sphere_lattice_visualizer/src/.
Consumers: download fibonacci_sphere-<version>.zip or fibonacci_sphere-demo-<version>.zip from
GitHub Releases. See docs/godot.md.
Development: build the extension from the repo root:
cargo build -p fibonacci_sphere_gd --releaseOpen godot/project.godot in Godot 4.3+, then run godot/demo/main.tscn.
The dev project loads libraries from target/ via godot/fibonacci_sphere.gdextension.
Release zips use the packaged layout under addons/fibonacci_sphere/.
The demo adds terrain polygons, coastline ribbons, click-to-route with terrain-type checkboxes, and
Perlin hotkeys. Regeneration uses batch Rust APIs (generate_with_terrain, get_terrain_mesh_data,
MultiMesh points). Method cycling uses M (same as Bevy). See docs/godot.md
for the full API.
cargo test -p fibonacci_sphere
cargo test --workspaceIntegration smoke test: tests/integration.rs (SphereLattice routing facade).
All text files use CRLF on every platform, except godot/** (LF — Godot always saves LF) and
POSIX shell hooks/scripts (LF). See .gitattributes and
.editorconfig. After cloning:
git config core.autocrlf false
git add --renormalize .GitHub Actions (.github/workflows/rust.yml) runs on every push to main and every pull request
targeting main: format check, Clippy, build, and test. The required check name is Rust / build.
Local scripts are split by platform — see scripts/README.md. Use the set
that matches where your files and cargo live:
| Environment | CI check | Git hooks |
|---|---|---|
Linux / WSL with Linux cargo |
./scripts/linux/ci-check.sh |
./scripts/linux/setup-git-hooks.sh |
Windows with Windows cargo |
scripts\windows\ci-check.cmd |
scripts\windows\setup-git-hooks.cmd |
See LICENSE.md.