BeyondImmersion.Bannou.SceneComposer 2.0.1-preview.manual.20260117173007

This is a prerelease version of BeyondImmersion.Bannou.SceneComposer.
dotnet add package BeyondImmersion.Bannou.SceneComposer --version 2.0.1-preview.manual.20260117173007
                    
NuGet\Install-Package BeyondImmersion.Bannou.SceneComposer -Version 2.0.1-preview.manual.20260117173007
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BeyondImmersion.Bannou.SceneComposer" Version="2.0.1-preview.manual.20260117173007" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BeyondImmersion.Bannou.SceneComposer" Version="2.0.1-preview.manual.20260117173007" />
                    
Directory.Packages.props
<PackageReference Include="BeyondImmersion.Bannou.SceneComposer" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BeyondImmersion.Bannou.SceneComposer --version 2.0.1-preview.manual.20260117173007
                    
#r "nuget: BeyondImmersion.Bannou.SceneComposer, 2.0.1-preview.manual.20260117173007"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BeyondImmersion.Bannou.SceneComposer@2.0.1-preview.manual.20260117173007
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BeyondImmersion.Bannou.SceneComposer&version=2.0.1-preview.manual.20260117173007&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=BeyondImmersion.Bannou.SceneComposer&version=2.0.1-preview.manual.20260117173007&prerelease
                    
Install as a Cake Tool

Bannou SceneComposer SDK

Engine-agnostic scene composition SDK for Bannou. Provides hierarchical scene editing, undo/redo, multi-selection, and transform gizmo logic without engine dependencies.

Overview

The SceneComposer SDK provides a complete solution for building scene editors:

  • Hierarchical scene graph with node creation, deletion, and reparenting
  • Command-based undo/redo with compound operations for grouping
  • Multi-selection with add/remove/toggle modes
  • Transform operations in local or world coordinate space
  • Validation system for scene and node integrity
  • Engine bridge pattern for integration with any game engine
  • Service client pattern for persistence and checkout/commit workflow

Architecture

                    ISceneComposerBridge
                           |
                           v
+-----------------+   +-----------+   +----------------+
| SceneComposer   |-->| Commands  |-->| Engine Bridge  |
|  - Selection    |   | - Create  |   | (Stride/Unity) |
|  - CommandStack |   | - Delete  |   +----------------+
|  - Validation   |   | - Move    |
+-----------------+   | - etc.    |
        |             +-----------+
        v
+------------------+
| ISceneService    |
| - Checkout/Commit|
| - Persistence    |
+------------------+

The SDK is designed in layers:

  1. Engine-agnostic core (this package) - All editing logic
  2. Engine-specific bridge (separate package) - Renders to your engine
  3. Service integration (optional) - Backend persistence

Project Structure

Bannou.SceneComposer/
├── Abstractions/           # Core interfaces
│   ├── ISceneComposer.cs       # Main orchestrator interface
│   ├── ISceneComposerBridge.cs # Engine integration interface
│   └── ISceneServiceClient.cs  # Backend persistence interface
├── Commands/               # Undo/redo command system
│   ├── IEditorCommand.cs       # Command interface
│   ├── NodeCommands.cs         # Create, delete, reparent, etc.
│   └── CommandStack.cs         # Undo/redo stack management
├── SceneGraph/             # Hierarchical scene structure
│   ├── ComposerScene.cs        # Scene container
│   └── ComposerSceneNode.cs    # Node with transform, asset, children
├── Selection/              # Multi-selection system
│   └── SelectionManager.cs     # Selection state and events
├── Math/                   # Engine-agnostic math types
│   ├── Vector3.cs              # 3D vector (double precision)
│   ├── Quaternion.cs           # Rotation quaternion
│   ├── Transform.cs            # Position + Rotation + Scale
│   ├── Ray.cs                  # Origin + Direction for picking
│   └── Color.cs                # RGBA color
├── Gizmo/                  # Transform gizmo logic
│   ├── GizmoController.cs      # Drag handling logic
│   └── GizmoTypes.cs           # Mode/axis enumerations
├── Validation/             # Scene validation
│   └── SceneValidator.cs       # Validates scene and node integrity
├── Events/                 # Event argument types
│   └── SceneEvents.cs          # Scene/selection/dirty state events
├── Assets/                 # Asset management interfaces
│   └── IAssetBundleManager.cs  # Bundle loading abstraction
└── SceneComposer.cs        # Main orchestrator implementation

Quick Start

using BeyondImmersion.Bannou.SceneComposer;
using BeyondImmersion.Bannou.SceneComposer.SceneGraph;

// Create a scene composer with your engine bridge
ISceneComposerBridge bridge = new YourEngineBridge();
var composer = new SceneComposer(bridge);

// Create a new scene
var scene = composer.NewScene(SceneType.Region, "My Level");

// Create nodes
var player = composer.CreateNode(NodeType.Actor, "Player");
var weapon = composer.CreateNode(NodeType.Model, "Sword", parent: player);

// Transform a node
composer.TranslateNode(player, new Vector3(10, 0, 5), CoordinateSpace.World);

// Undo/Redo
composer.Undo();
composer.Redo();

Features

Scene Graph

Hierarchical node management with transform inheritance:

// Create nodes with parent relationships
var parent = composer.CreateNode(NodeType.Group, "Parent");
var child = composer.CreateNode(NodeType.Model, "Child", parent: parent);

// Reparent nodes
composer.ReparentNode(child, newParent: otherParent, insertIndex: 0);

// Duplicate with hierarchy
var clone = composer.DuplicateNode(parent, deepClone: true);

// Delete with or without children
composer.DeleteNode(parent, deleteChildren: true);

Transform Operations

Transform in local or world coordinates:

// Set local transform
composer.SetLocalTransform(node, new Transform(
    position: new Vector3(1, 2, 3),
    rotation: Quaternion.FromEuler(0, 45, 0),
    scale: Vector3.One));

// Translate in world space
composer.TranslateNode(node, delta: new Vector3(5, 0, 0), CoordinateSpace.World);

// Rotate multiple nodes around a pivot
composer.RotateNodes(selectedNodes, rotation, CoordinateSpace.World, pivot: center);

// Scale multiple nodes from a pivot
composer.ScaleNodes(selectedNodes, new Vector3(2, 2, 2), pivot: center);

Command System

Full undo/redo with compound operations:

// Individual commands are automatically tracked
composer.CreateNode(NodeType.Model, "Object1");
composer.CreateNode(NodeType.Model, "Object2");
composer.Undo(); // Removes Object2
composer.Undo(); // Removes Object1

// Group multiple operations as one undo step
using (composer.BeginCompoundOperation("Create Grid"))
{
    for (int x = 0; x < 10; x++)
    for (int y = 0; y < 10; y++)
    {
        composer.CreateNode(NodeType.Model, $"Cell_{x}_{y}");
    }
}
composer.Undo(); // Removes all 100 cells at once

Multi-Selection

Select and operate on multiple nodes:

// Selection modes
composer.Select(node1, SelectionMode.Replace);  // Clear and select one
composer.Select(node2, SelectionMode.Add);      // Add to selection
composer.Select(node2, SelectionMode.Toggle);   // Toggle in/out

// Select multiple
composer.Select(nodeList, SelectionMode.Replace);

// Select all in scene
composer.SelectAll();

// Clear selection
composer.ClearSelection();

// Check selection
if (composer.HasSelection)
{
    var selected = composer.SelectedNodes;
}

Asset Binding

Bind visual assets to nodes:

// Bind asset from a bundle
composer.BindAsset(node, new AssetReference(
    bundleId: "characters",
    assetId: "warrior_model",
    variantId: "high_poly"));

// Clear asset
composer.ClearAsset(node);

Persistence (with Service Client)

Checkout/commit workflow for collaborative editing:

// Load scene from service
var scene = await composer.LoadSceneAsync("scene-123");

// Checkout for exclusive editing
if (await composer.CheckoutAsync())
{
    // Make changes...
    composer.CreateNode(NodeType.Model, "NewObject");

    // Commit changes
    await composer.CommitAsync("Added new object");
}

// Or discard changes
await composer.DiscardAsync();

Validation

Validate scene integrity:

// Validate entire scene
var result = composer.ValidateScene();
if (!result.IsValid)
{
    foreach (var error in result.Errors)
    {
        Console.WriteLine($"{error.Severity}: {error.Message}");
    }
}

// Validate specific node
var nodeResult = composer.ValidateNode(node);

Implementing a Bridge

Create your engine bridge by implementing ISceneComposerBridge:

public class MyEngineBridge : ISceneComposerBridge
{
    public void CreateEntity(string nodeId, NodeType nodeType, Transform transform, AssetReference? asset)
    {
        // Create entity in your engine
        var entity = new GameObject();
        entity.name = nodeId;
        ApplyTransform(entity, transform);
        _entities[nodeId] = entity;
    }

    public void DestroyEntity(string nodeId)
    {
        if (_entities.TryGetValue(nodeId, out var entity))
        {
            Destroy(entity);
            _entities.Remove(nodeId);
        }
    }

    public void UpdateEntityTransform(string nodeId, Transform worldTransform)
    {
        var entity = _entities[nodeId];
        entity.transform.position = worldTransform.Position.ToEngine();
        entity.transform.rotation = worldTransform.Rotation.ToEngine();
        entity.transform.localScale = worldTransform.Scale.ToEngine();
    }

    public void SetEntityParent(string nodeId, string? parentId)
    {
        var entity = _entities[nodeId];
        var parent = parentId != null ? _entities[parentId] : null;
        entity.transform.SetParent(parent?.transform);
    }

    public Task SetEntityAssetAsync(string nodeId, AssetReference asset, CancellationToken ct = default)
    {
        // Load and assign asset
        return Task.CompletedTask;
    }

    // ... implement other methods
}

Events

Subscribe to scene changes:

// Scene modifications (node created, deleted, transformed, etc.)
composer.SceneModified += (sender, e) =>
{
    Console.WriteLine($"{e.ModificationType}: {e.Description}");
};

// Selection changes
composer.SelectionChanged += (sender, e) =>
{
    Console.WriteLine($"Selected: {e.CurrentSelection.Count} nodes");
};

// Dirty state (unsaved changes)
composer.DirtyStateChanged += (sender, e) =>
{
    windowTitle = e.IsDirty ? "Scene Editor *" : "Scene Editor";
};

// Undo/redo availability
composer.UndoRedoStateChanged += (sender, e) =>
{
    undoButton.Enabled = e.CanUndo;
    redoButton.Enabled = e.CanRedo;
};

Engine Bridges

Package Engine Notes
BeyondImmersion.Bannou.SceneComposer.Stride Stride Engine 4.3 Windows, bundle loading, LRU cache
BeyondImmersion.Bannou.SceneComposer.Godot Godot 4.3+ Cross-platform, res:// paths

Dependencies

  • .NET 8.0 or later
  • No external dependencies (pure .NET)

Installation

dotnet add package BeyondImmersion.Bannou.SceneComposer

For Stride engine integration:

dotnet add package BeyondImmersion.Bannou.SceneComposer.Stride

For Godot 4.x engine integration:

dotnet add package BeyondImmersion.Bannou.SceneComposer.Godot

License

MIT License

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on BeyondImmersion.Bannou.SceneComposer:

Package Downloads
BeyondImmersion.Bannou.SceneComposer.Stride

Stride engine extension for the Bannou SceneComposer SDK. Provides ISceneComposerBridge implementation, asset loaders, and gizmo rendering for Stride-based games. Note: Full functionality requires Windows.

BeyondImmersion.Bannou.SceneComposer.Godot

Godot 4.x engine extension for the Bannou SceneComposer SDK. Provides ISceneComposerBridge implementation, asset loading, and gizmo rendering for Godot-based games.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.1-preview.manual... 82 1/17/2026
2.0.1-preview.14 50 3/2/2026
2.0.1-preview.13 46 2/24/2026
2.0.1-preview.11 63 1/29/2026
2.0.1-preview.10 63 1/22/2026
2.0.1-preview.9 50 1/19/2026
2.0.0 130 1/17/2026
1.0.0 130 1/16/2026
0.1.0-preview.manual... 59 1/16/2026