SceneLoader как точка входа для модульных сцен

В Babylon.js SceneLoader является мощным инструментом для работы с внешними 3D-сценами и моделями. Он обеспечивает удобный механизм загрузки ресурсов в формате .gltf, .glb, .obj, .babylon и других, позволяя интегрировать готовые ассеты в основной рендеринг без необходимости вручную создавать каждый объект.

Основные методы SceneLoader

1. Append и ImportMesh

  • SceneLoader.Append добавляет содержимое внешнего файла в уже существующую сцену. Используется, когда необходимо расширить текущую сцену новыми объектами или анимациями, сохраняя ранее созданные элементы.

    BABYLON.SceneLoader.Append("/models/", "scene.glb", scene, function (scene) {
        scene.createDefaultCameraOrLight(true, true, true);
    });
  • SceneLoader.ImportMesh позволяет загружать только конкретные меши из файла. Это полезно для модульного подхода, когда сцена делится на отдельные части, а не загружается целиком.

    BABYLON.SceneLoader.ImportMesh(
        ["mesh1", "mesh2"],
        "/models/",
        "scene.glb",
        scene,
        function (meshes, particleSystems, skeletons, animationGroups) {
            console.log(meshes);
        }
    );

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

Асинхронная загрузка с Promises

С версии Babylon.js 4.0 методы SceneLoader поддерживают промисы, что упрощает интеграцию в современные проекты:

BABYLON.SceneLoader.AppendAsync("/models/", "scene.glb", scene)
    .then((scene) => {
        scene.createDefaultCameraOrLight(true, true, true);
    })
    .catch((error) => {
        console.error(error);
    });

Использование async/await делает код более читаемым:

async function loadScene() {
    try {
        await BABYLON.SceneLoader.AppendAsync("/models/", "scene.glb", scene);
    } catch (e) {
        console.error(e);
    }
}

Работа с прогрессом загрузки

Для крупных сцен важно отслеживать прогресс. SceneLoader предоставляет коллбэк onProgress:

BABYLON.SceneLoader.Append("/models/", "scene.glb", scene, 
    function(scene) {
        console.log("Сцена загружена");
    },
    function(event) {
        let percentage = 0;
        if (event.lengthComputable) {
            percentage = (event.loaded / event.total) * 100;
        }
        console.log(`Загрузка: ${percentage.toFixed(2)}%`);
    }
);

Модульная структура сцен

SceneLoader идеально подходит для модульного подхода. Сцена может состоять из нескольких отдельных файлов:

  • Основной мир (world.glb) — базовая геометрия и освещение.
  • Интерактивные объекты (props.glb) — отдельные меши с коллизиями и анимацией.
  • Персонажи (characters.glb) — меши с skeleton и animationGroups.

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

Кэширование и оптимизация

  • Кэширование сцен: Babylon.js хранит уже загруженные ресурсы в памяти, чтобы повторная загрузка одного и того же файла была мгновенной.
  • Асинхронная загрузка текстур и материалов: используйте SceneLoader.ImportMeshAsync для больших ассетов, чтобы избежать блокировки рендера.
  • Lazy-loading: модули сцены, которые находятся вне текущей видимой зоны, можно загружать по требованию.

Работа с анимациями

При использовании SceneLoader автоматически подгружаются AnimationGroup для объектов:

BABYLON.SceneLoader.ImportMesh(
    "",
    "/models/",
    "characters.glb",
    scene,
    function(meshes, particleSystems, skeletons, animationGroups) {
        animationGroups.forEach(group => group.start(true));
    }
);
  • AnimationGroup.start(loop) запускает все анимации группы.
  • Можно комбинировать анимации нескольких модулей, создавая сложные интерактивные сцены.

Настройка материалов и шейдеров после загрузки

После загрузки сцены через SceneLoader все меши доступны для модификации:

scene.meshes.forEach(mesh => {
    if(mesh.name.includes("Glass")) {
        mesh.material = new BABYLON.PBRMaterial("glassMat", scene);
        mesh.material.alpha = 0.5;
    }
});

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

События загрузки и взаимодействие с пользователем

SceneLoader предоставляет события для полного контроля над процессом:

  • onPluginActivatedObservable — информирует, какой плагин используется для конкретного формата.
  • onMeshLoadedObservable — вызывается после добавления каждого меша в сцену.
  • onSceneLoadedObservable — финальный коллбэк после полной загрузки сцены.

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

Итоговые преимущества использования SceneLoader

  • Модульность: сцены делятся на отдельные части, легко комбинируются и заменяются.
  • Асинхронность: загрузка не блокирует основной поток рендеринга.
  • Контроль и фильтрация: возможность загружать отдельные меши, анимации и материалы.
  • Поддержка прогресса: интеграция индикаторов загрузки и событий.
  • Оптимизация: кэширование и lazy-loading позволяют работать с большими сценами без падения FPS.

SceneLoader в Babylon.js служит основной точкой входа для модульных сцен, обеспечивая гибкость, расширяемость и высокую производительность при разработке сложных 3D-приложений.