bevy_symbios_shape 0.1.0

Bevy integration for Symbios Shape.
Documentation

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: BevySymbiosShapePlugin registers a ShapeRegistry resource for mapping grammar IDs to Bevy assets.
  • Asset routing: Register GLTF scenes and materials by string ID; unregistered terminals fall back to procedural meshes.
  • Procedural meshes: build_profiled_mesh generates geometry for tapered prisms, triangles, trapezoids, and arbitrary polygons based on the terminal's FaceProfile.
  • Coordinate translation: scope_to_transform handles the f64→f32 downcast and corner-to-centroid offset between symbios-shape scopes and Bevy transforms.
  • Spawn extension: commands.spawn_shape(...) derives a grammar and spawns the full terminal hierarchy in one call.

Quick start

use bevy::prelude::*;
use bevy_symbios_shape::prelude::*;
use symbios_shape::{Interpreter, Scope, grammar::parse_ops};

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, BevySymbiosShapePlugin))
        .add_systems(Startup, setup)
        .run();
}

fn setup(
    mut commands: Commands,
    registry: Res<ShapeRegistry>,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    let mut interp = Interpreter::new();
    interp.add_rule("Lot",    parse_ops("Extrude(12) Split(Y) { 3: Ground | ~1: Upper | 2: Roof }").unwrap());
    interp.add_rule("Ground", parse_ops(r#"I("GroundFloor")"#).unwrap());
    interp.add_rule("Upper",  parse_ops(r#"I("Floor")"#).unwrap());
    interp.add_rule("Roof",   parse_ops(r#"Taper(0.8) I("Roof")"#).unwrap());

    let footprint = Scope::new(
        symbios_shape::Vec3::ZERO,
        symbios_shape::Quat::IDENTITY,
        symbios_shape::Vec3::new(10.0, 0.0, 10.0),
    );

    commands
        .spawn_shape(&interp, footprint, "Lot", &registry, &mut meshes, &mut materials)
        .unwrap();
}

Modules

Module Purpose
mesh build_profiled_mesh / build_tapered_cuboid — procedural mesh generation
registry ShapeRegistry — asset routing table (mesh IDs → scenes, material IDs → materials)
spawner SpawnShapeExtCommands 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:

fn setup(mut registry: ResMut<ShapeRegistry>, asset_server: Res<AssetServer>) {
    registry.register_mesh("Window", asset_server.load("window.glb#Scene0"));
    registry.register_material("Brick", asset_server.load("brick_material.glb#Material0"));
    registry.default_material = Some(materials.add(StandardMaterial::default()));
}

Terminals whose mesh_id is not registered get a procedural mesh colored by a stable hash of the ID.

Examples

cargo run --example detailed_villa
cargo run --example medieval_castle

License

MIT