Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
bevy_symbios_shape
Bevy integration for symbios-shape — a CGA Shape Grammar engine for procedural architecture.
Converts grammar outputs (ShapeModel / Terminal nodes) into Bevy entity hierarchies with procedural or asset-based meshes.
Features
- Plugin:
BevySymbiosShapePluginregistersShapeRegistry,ShapeMeshCache,LastDerivedModel, andSnapPlanesresources, plus an observer forSpawnShapeRequestevents. - Asset routing: Register GLTF scenes and materials by string ID; unregistered terminals fall back to procedural meshes.
- Procedural meshes:
build_profiled_meshgenerates geometry for tapered prisms, triangles, trapezoids, and arbitrary polygons based on the terminal'sFaceProfile. - Round cross-sections: register an asset ID with
register_round_meshand its terminals bake as elliptical prisms — cylinders, frusta, and cones — so columns, silos, and spires read as round while the grammar keeps working in axis-aligned boxes. - Coordinate translation:
scope_to_transformhandles the f64→f32 downcast and corner-to-centroid offset betweensymbios-shapescopes and Bevy transforms. - Spawn extension:
commands.spawn_shape(...)derives a grammar and spawns the full terminal hierarchy in one call. - Event-driven spawning: trigger
SpawnShapeRequestand observeSpawnShapeSpawned/SpawnShapeFailedfor decoupled call sites. - Cross-spawn mesh cache:
ShapeMeshCachededuplicates procedural meshes acrossspawn_shapecalls (with hit/miss/eviction counters) and is bounded — least-recently-used entries are evicted past its capacity, so long-lived re-rolling sessions cannot grow it without limit. - Mass properties: terminals whose grammar carries
Mat(id, density)get aTerminalMasscomponent (mass / centroid / inertia) for downstream physics, IK, and LOD. - Occlusion labels: terminals derived under
Label("class")get aTerminalLabelcomponent, so ECS systems can select the same groups the grammar'sIfClear/IfInsideconditionals reasoned about. - Snap planes:
RegSnap("label")recordings are surfaced via theSnapPlanesresource. - Spatial queries:
LastDerivedModelplus the re-exportedTerminalQuery/obb_overlapgive downstream systems OBB collision tests against spawned terminals.
Quick start
use *;
use *;
use ;
Modules
| Module | Purpose |
|---|---|
cache |
ShapeMeshCache — persistent procedural mesh cache shared across spawns |
events |
SpawnShapeRequest / SpawnShapeSpawned / SpawnShapeFailed events + observer |
label |
TerminalLabel Component — the occlusion class stamped by the grammar's Label("…") |
mass |
TerminalMass Component — mass / centroid / inertia from upstream MassProperties |
mesh |
build_profiled_mesh / build_profiled_mesh_with / build_tapered_cuboid — meshing |
query |
LastDerivedModel resource holding the most recently derived ShapeModel |
registry |
ShapeRegistry — asset routing table (mesh IDs → scenes, material IDs → materials) |
snap |
SnapPlane / SnapPlanes resource exposing RegSnap recordings |
spawner |
SpawnShapeExt — Commands extension trait for one-call grammar derivation + spawning |
transform |
scope_to_transform — f64 scope to f32 Bevy Transform with corner-to-centroid offset |
Asset registration
Register GLTF scenes and materials before spawning so the grammar can resolve them:
Terminals whose mesh_id is not registered get a procedural mesh colored by a stable hash of the ID. Material fallback order is: registered handle → default_material → generated grey.
Round cross-sections
The grammar stays OBB-pure — every scope is an axis-aligned box — but a terminal's rendering can be round. Opt an asset ID in and the mesher inscribes an elliptical prism in the scope's footprint:
// Grammar: Column --> Extrude(0.6) Taper(0.14) Mat("Marble") I("Column")
registry.register_round_mesh; // or register_round_material("Marble")
registry.set_round_segments; // default 24, clamped to [3, 256]
| Profile | Rendered as |
|---|---|
Rectangle |
cylinder (circular when the footprint is square, elliptical otherwise) |
Taper(t) |
frustum — the top ring shrinks by t |
Taper(1.0) |
cone (the top cap is dropped) |
Triangle / Trapezoid / Polygon |
unchanged — flat panels have no cross-section to round |
Side UVs wrap the circumference in world units (so texel density matches flat walls) unless the ID is also registered as a stretch target. Because roundness is a rendering choice, splits, occlusion queries, and mass properties are all computed on the original box.
Event-driven spawning
For decoupled call sites — e.g. a UI button that requests a building without holding the mesh/material asset registries — trigger [SpawnShapeRequest]:
use Arc;
// Observe the result anywhere:
The plugin's built-in observer performs the derivation and spawn, then triggers SpawnShapeSpawned(root_entity) on success or SpawnShapeFailed(message) on derivation failure.
Cargo features
| Feature | Default | Effect |
|---|---|---|
egui |
off | Pulls in bevy_egui for downstream inspector/editor UIs. |
mutation |
off | Enables the mutation module: MaterialMutationPlugin, TextureConfigStore, and the MutateMaterialsRequest / MaterialTextureMutated event pair. Drives procedural-texture evolution via bevy_symbios_texture and symbios-genetics. |
Mesh cache capacity
The cache defaults to DEFAULT_MESH_CACHE_CAPACITY (8192) entries and
evicts least-recently-used meshes beyond it:
let mut cache = with_capacity;
cache.set_capacity; // opt out of eviction entirely
println!;
Eviction drops the cached handle, not the GPU mesh — anything still
spawned keeps its geometry alive. A steadily climbing evictions() means
the working set exceeds the ceiling; raise it, or accept the re-upload
churn.
Examples
# The 0.3 language: attributes, styles, guards, rhythm groups, Pick,
# ShapeL, Scatter, Label — plus round columns. Keys 1/2/3 switch the
# prosperity register, R re-rolls the seed, C toggles roundness.
# Click-to-evolve buildings with procedural textures.
License
MIT