flutter3d
Showcase Changelog 38 packages API reference

Loading a level

since 0.7.0 Widgets and the rest

LevelLoader is the bridge between a level document and something drawable: brushes become mesh nodes, lights become light nodes, and the result is a LoadedLevel with its own scene, collision world and a list of anything that went wrong along the way.

Step 1: A document #

A floor and a light, built in code rather than read from a file.

static Level _document() => Level(
  name: 'room',
  brushes: <Brush>[
    Brush(centre: Vector3(0, -0.5, 0), size: Vector3(4, 1, 4)),
  ],
  lights: <LevelLight>[
    LevelLight(position: Vector3(0, 3, 0), intensity: 5.0, range: 10.0),
  ],
);

Step 2: Build it #

LevelLoader.build does everything load does except finding the document, which is what lets a level built in memory — an editor's unsaved document, a page like this one — go through the same path a bundled level does.

_loaded = await const LevelLoader().build(
  _document(),
  device: context.device,
  registry: EntityRegistry(const <EntityKind>[]),
);

Step 3: Share repeated meshes #

SharedMeshes uploads a shape once and hands the same DeviceMesh back to anything that asks for it again, so three torch posts of the same size cost one upload.

// Three torch posts that all ask the cache for the same box, uploaded
// once and reused by all three nodes.
_shared = SharedMeshes(context.device);
for (var i = 0; i < 3; i++) {
  final mesh = _shared.box(Vector3(0.2, 1.0, 0.2));
  final post = MeshNode(
    mesh,
    Material(name: 'post', baseColor: Vector4(0.4, 0.3, 0.2, 1.0)),
  )..setPosition(-1.0 + i.toDouble(), 0.0, 1.5);
  _loaded.scene.add(post);
}

A clean document loads with an empty issues list; a level with a missing texture or an unknown entity type would still load, with the problem named there instead of stopping the level from playing.