AssetContainer: изоляция и повторное использование наборов ресурсов

AssetContainer в Babylon.js представляет собой мощный инструмент для управления группами объектов сцены. Он позволяет создавать, хранить и повторно использовать наборы ресурсов без непосредственного добавления их на сцену. Это особенно важно при работе с большими сценами, где требуется оптимизация памяти и контроль над загрузкой объектов.


Основные концепции AssetContainer

AssetContainer — это контейнер, который может содержать:

  • Meshes (сети)
  • Materials (материалы)
  • Textures (текстуры)
  • Skeletons (скелеты)
  • Particle Systems (системы частиц)
  • Cameras (камеры, если необходимо)
  • Lights (освещение)

Контейнер сам по себе не рендерится, пока его содержимое не будет добавлено на сцену с помощью методов addAllToScene() или отдельных addToScene(mesh).


Создание AssetContainer

Контейнер создаётся на основе сцены:

const container = new BABYLON.AssetContainer(scene);

После создания в него можно добавлять объекты, либо загружать через ассет-менеджер:

BABYLON.SceneLoader.Append("models/", "house.glb", scene, function (scene) {
    const houseContainer = new BABYLON.AssetContainer(scene);
    houseContainer.meshes.push(scene.meshes[0]); // Добавление загруженного объекта
});

Использование AssetContainer позволяет полностью отделить загрузку и подготовку ресурсов от их непосредственного отображения на сцене.


Управление объектами в контейнере

Добавление объектов вручную:

const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2}, scene);
const box = BABYLON.MeshBuilder.CreateBox("box", {size: 1}, scene);

const container = new BABYLON.AssetContainer(scene);
container.meshes.push(sphere, box);

На этом этапе объекты существуют, но не видны на сцене. Для их отображения используется:

container.addAllToScene();

Для выборочного добавления можно использовать:

container.addToScene(sphere);

Удаление объектов с сцены выполняется методами:

container.removeAllFromScene(); // удаляет все объекты, добавленные из контейнера
container.removeFromScene(sphere); // удаляет конкретный объект

Повторное использование и клоны

Контейнер позволяет многократное использование одного набора ресурсов. Например, если есть сложная модель здания, её можно один раз загрузить в контейнер и создавать клоны на сцене:

const houseClone = container.instantiateModelsToScene("houseClone");

Клоны будут иметь отдельные экземпляры объектов, но сохранят ссылки на материалы и текстуры из контейнера, что экономит память.


Оптимизация производительности

Использование AssetContainer позволяет:

  1. Ленивую загрузку ресурсов: объекты загружаются в память, но не отображаются, пока не потребуется.
  2. Пакетное управление: добавление и удаление группы объектов за один вызов.
  3. Контроль жизненного цикла объектов: можно полностью удалить контейнер с его ресурсами, освобождая память.
container.dispose(); // полностью очищает все объекты и освобождает память

Особенно полезно при динамическом подгружении частей сцены, например, уровней или модулей игры.


Интеграция с AssetManager

AssetManager в Babylon.js упрощает работу с внешними ресурсами, которые можно потом сохранять в AssetContainer:

const assetsManager = new BABYLON.AssetsManager(scene);
const meshTask = assetsManager.addMeshTask("task", "", "models/", "tree.glb");

meshTask.onSucc ess = function(task) {
    const treeContainer = new BABYLON.AssetContainer(scene);
    treeContainer.meshes.push(...task.loadedMeshes);
    // можно добавить в сцену или хранить для повторного использования
};

assetsManager.load();

Это позволяет разграничивать загрузку, подготовку и отображение ресурсов, создавая модульные и легко управляемые сцены.


Особенности работы с анимациями и скелетами

Если объекты в контейнере имеют Skeleton или анимацию, при добавлении их на сцену можно управлять как:

container.addAllToScene();
scene.beginAnimation(container.skeletons[0], 0, 100, true);

Клонирование объектов автоматически создаёт связи с оригинальными скелетами, что позволяет воспроизводить анимацию без повторного создания всех костей.


Примеры практического применения

  • Игровые уровни: отдельные контейнеры для каждой комнаты, которые подгружаются и удаляются по мере движения игрока.
  • Модульные сцены: здания, машины, деревья — отдельные AssetContainer для каждого типа объекта.
  • Эффекты и частицы: Particle Systems и динамические объекты можно предварительно подготовить и активировать при событии.

Рекомендации по использованию

  • Хранить в контейнере только связанные объекты, чтобы изолировать функциональные модули сцены.
  • Использовать instantiateModelsToScene() для повторного использования без дублирования памяти.
  • При удалении объектов с сцены всегда контролировать их жизненный цикл через методы контейнера, чтобы избежать утечек памяти.
  • Комбинировать AssetContainer с AssetManager для эффективной асинхронной загрузки.

Использование AssetContainer делает управление сценами Babylon.js гибким, модульным и высокопроизводительным, предоставляя полную контроль над ресурсами, их загрузкой и отображением.