SceneLoader.ImportMesh и ImportMeshAsync

Для работы с 3D-графикой в Babylon.js важным аспектом является загрузка и обработка объектов в сцене. Одной из ключевых функций библиотеки является SceneLoader.ImportMesh и её асинхронный аналог SceneLoader.ImportMeshAsync, которые позволяют загружать и добавлять 3D-модели и их элементы в сцену. Эти методы являются неотъемлемой частью процесса работы с внешними файлами форматов, таких как .babylon, .obj, .glTF и других.

Синхронная загрузка с использованием SceneLoader.ImportMesh

Метод SceneLoader.ImportMesh позволяет загружать меши из внешних файлов и добавлять их в сцену. Этот метод выполняет синхронную загрузку, что означает, что выполнение программы будет приостановлено до завершения загрузки всех данных.

Сигнатура метода:

SceneLoader.ImportMesh(meshesNames, rootUrl, sceneFilename, scene, onSuccess, onProgress, onError);

Параметры:

  • meshesNames (строка или массив строк) — имена мешей, которые необходимо загрузить. Если передать null или пустую строку, то будут загружены все меши из файла.
  • rootUrl (строка) — базовый URL для загрузки ресурса. Это путь, по которому будет осуществляться поиск файлов.
  • sceneFilename (строка) — имя файла или URL, в котором хранятся данные сцены.
  • scene (объект Scene) — объект сцены, в которую будут добавлены загруженные меши.
  • onSuccess (функция) — функция, которая будет вызвана после успешной загрузки. В неё передаётся массив загруженных мешей, а также материалы и текстуры.
  • onProgress (функция, необязательный параметр) — функция, которая вызывается во время загрузки. Используется для отображения прогресса загрузки.
  • onError (функция, необязательный параметр) — функция, которая вызывается в случае ошибки при загрузке.

Пример использования:

BABYLON.SceneLoader.ImportMesh("", "assets/models/", "car.babylon", scene, function (meshes, particleSystems, skeletons) {
    var car = meshes[0];
    car.position = new BABYLON.Vector3(0, 0, 0);
});

В этом примере из директории assets/models/ загружается модель автомобиля car.babylon. После загрузки объект car будет добавлен в сцену в позиции (0, 0, 0).

Преимущества:

  • Простота в использовании для базовых задач.
  • Синхронная загрузка подходит для небольших проектов или случаев, когда важно получить все данные перед началом работы.

Ограничения:

  • Синхронная природа метода может привести к блокировке основного потока, особенно при загрузке больших файлов или при низкой скорости интернета.

Асинхронная загрузка с использованием SceneLoader.ImportMeshAsync

Для предотвращения блокировки основного потока, Babylon.js предлагает асинхронный аналог — SceneLoader.ImportMeshAsync. Этот метод позволяет загружать меши асинхронно, не блокируя выполнение программы, что особенно полезно для работы с большими сценами или множеством файлов.

Сигнатура метода:

SceneLoader.ImportMeshAsync(meshesNames, rootUrl, sceneFilename, scene, onProgress, onError);

Параметры:

  • meshesNames (строка или массив строк) — имена мешей для загрузки. Как и в случае с синхронным методом, можно указать null, чтобы загрузить все меши.
  • rootUrl (строка) — базовый URL для поиска файлов.
  • sceneFilename (строка) — имя или URL файла сцены.
  • scene (объект Scene) — сцена, в которую будут добавлены меши.
  • onProgress (функция, необязательный параметр) — функция для отслеживания прогресса загрузки.
  • onError (функция, необязательный параметр) — функция для обработки ошибок.

Метод возвращает объект Promise, который резолвится в момент завершения загрузки, что позволяет использовать асинхронные конструкции, такие как await, для упрощения работы с этим методом.

Пример использования:

async function loadModel() {
    try {
        const result = await BABYLON.SceneLoader.ImportMeshAsync("", "assets/models/", "car.babylon", scene);
        const car = result.meshes[0];
        car.position = new BABYLON.Vector3(0, 0, 0);
    } catch (error) {
        console.error("Ошибка загрузки:", error);
    }
}

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

Преимущества:

  • Асинхронная загрузка позволяет избежать блокировки основного потока, что делает работу с большими сценами и файлами более эффективной.
  • Использование Promise и async/await упрощает код и делает его более читаемым.

Ограничения:

  • Необходимо использовать конструкции Promise и async/await, что может потребовать дополнительных усилий при работе с устаревшими браузерами или проектами, где не поддерживается асинхронный код.

Загрузка нескольких мешей

Метод ImportMesh и его асинхронный аналог позволяют загружать несколько мешей из одного файла. В случае с ImportMesh необходимо передавать имена всех объектов, которые нужно загрузить, в виде строки или массива строк. В случае с асинхронным методом можно использовать аналогичный подход.

Пример синхронной загрузки нескольких мешей:

BABYLON.SceneLoader.ImportMesh(["car", "tree"], "assets/models/", "scene.babylon", scene, function (meshes) {
    meshes[0].position = new BABYLON.Vector3(0, 0, 0);
    meshes[1].position = new BABYLON.Vector3(5, 0, 0);
});

Аналогичный пример с асинхронной загрузкой:

async function loadModels() {
    try {
        const result = await BABYLON.SceneLoader.ImportMeshAsync(["car", "tree"], "assets/models/", "scene.babylon", scene);
        result.meshes[0].position = new BABYLON.Vector3(0, 0, 0);
        result.meshes[1].position = new BABYLON.Vector3(5, 0, 0);
    } catch (error) {
        console.error("Ошибка загрузки:", error);
    }
}

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

Загрузка и обработка ошибок

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

Пример обработки ошибок при синхронной загрузке:

BABYLON.SceneLoader.ImportMesh("", "assets/models/", "car.babylon", scene, function (meshes) {
    // Успешная загрузка
}, null, function (error) {
    console.error("Ошибка загрузки:", error);
});

Пример обработки ошибок при асинхронной загрузке:

async function loadModel() {
    try {
        const result = await BABYLON.SceneLoader.ImportMeshAsync("", "assets/models/", "car.babylon", scene);
    } catch (error) {
        console.error("Ошибка загрузки:", error);
    }
}

Правильная обработка ошибок позволяет сделать загрузку более надёжной и обеспечивать обратную связь с пользователем в случае проблем.

Заключение

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