18 Babylonjs入門進階 使用Assets Manager加載多個模型

爲了方便開發者加載多個模型,Babylon.js從1.14版本引入了AssetsManager類。
此類可用於將模型導入場景活加載文本和二進制文件。
注意:導入的模型具有旋轉四元數設置,因此使用rotation設置旋轉會發現會旋轉到意想不到的位置,如果使用rotation請將rotationQuaternion設置爲空。

使用AssetsManager

初始化和創建任務

要使用它,首先要先通過場景進行實例化:

var assetsManager = new BABYLON.AssetsManager(scene);

然後,可以通過管理器的addMeshTask方法添加任務:

var meshTask = assetsManager.addMeshTask("skull task", "", "scenes/", "skull.babylon");

每個任務都有一個成功回調和錯誤回調:

meshTask.onSuccess = function (task) {
    task.loadedMeshes[0].position = BABYLON.Vector3.Zero();
}
meshTask.onError = function (task, message, exception) {
    console.log(message, exception);
}

你也可以使用相同的方式加載文本addTextFileTask和二進制文件addBinaryFileTask

var textTask = assetsManager.addTextFileTask("text task", "msg.txt");
textTask.onSuccess = function(task) {
    console.log(task.text);
}

var binaryTask = assetsManager.addBinaryFileTask("binary task", "grass.jpg");
binaryTask.onSuccess = function (task) {
    // Do something with task.data
}

管理器也支持加載圖像addImageTask

var imageTask = assetsManager.addImageTask("image task", "img.jpg");
imageTask.onSuccess = function(task) {
    console.log(task.image.width);
}

管理器也可以通過addTextureTask來創建加載紋理任務:

var textureTask = assetsManager.addTextureTask("image task", "img.jpg");
textureTask.onSuccess = function(task) {
    material.diffuseTexture = task.texture;
}

任務狀態和錯誤處理

每個任務都有一個狀態對象,表示當前任務的執行狀態。狀態由枚舉表示,BABYLON.AssetTaskState有4種狀態:

  • INIT - 在任務開始執行之前
  • RUNNING - 當任務開始執行但尚未完成時
  • DONE - 當任務成功完成執行時
  • ERROR - 任務失敗時

如果任務具有錯誤狀態(BABYLON.AssetTaskState.ERROR),則將向該任務添加新對象:task.errorObject。錯誤對象定義了2個變量,兩個都是可選的:

  • message - 一個很快解釋錯誤的字符串(例如“請求返回404”)
  • exception - 如果在執行期間拋出異常,異常對象將包含堆棧跟蹤信息

這樣,通過管理器也可以訪問錯誤:

assetsManager.onTaskErrorObservable.add(function(task) {
    console.log('task failed', task.errorObject.message, task.errorObject.exception);
});

管理器回調和觀察者模式

管理器自身擁有四個回調:

  • onFinish
  • onProgress
  • onTaskSuccess
  • onTaskError
assetsManager.onProgress = function(remainingCount, totalCount, lastFinishedTask) {
    engine.loadingUIText = 'We are loading the scene. ' + remainingCount + ' out of ' + totalCount + ' items still need to be loaded.';
};

assetsManager.onFinish = function(tasks) {
    engine.runRenderLoop(function() {
        scene.render();
    });
};

管理器還允許你使用觀察者回調來處理onFinish,onProgress,onTaskSuccess和onTaskError:

  • onTaskSuccessObservable - 當單個任務成功完成時,將執行已註冊的觀察者回調。
  • onTaskErrorObservable - 當單個任務失敗時,將執行已註冊的觀察者回調。
  • onProgressObservable - 當單個任務成功完成或失敗時,將執行已註冊的觀察者回調。
  • onTasksDoneObservable - 當所有任務執行完成(成功或失敗!)時,將執行已註冊的觀察者回調
assetsManager.onTaskSuccessObservable.add(function(task) {
    console.log('task successful', task)
});
assetsManager.onTasksDoneObservable.add(function(tasks) {
    var errors = tasks.filter(function(task) {return task.taskState === BABYLON.AssetTaskState.ERROR});
    var successes = tasks.filter(function(task) {return task.taskState !== BABYLON.AssetTaskState.ERROR});
});

開始任務

設置好任務以後,開啓必須調用開始:

assetsManager.load();

可用任務

你可以使用管理器去實現加載7種類型數據的任務。
每個任務都使用以下屬性擴展AbstractAssetTask類(並實現IAssetTask接口):

onSuccess: (task: IAssetTask) => void;
onError: (task: IAssetTask, message?: string, exception?: any) => void;

isCompleted: boolean = false;
name: string;
taskState: AssetTaskState;
errorObject: { message?: string; exception?: any; };

注意,加載的任務數據類型必須與創建的任務數據類型對應。例如,CubeTextureAssetTask的構造函數簽名採用與類BABYLON.CubeTexture相同的變量。變量的順序可能會有所不同。

MeshAssetTask

MeshAssetTask用於加載外部的模型(.babylon,.obj,.gltf等)。
構造函數配置指定:

constructor(name: string, meshesNames: any, rootUrl: string, sceneFilename: string)

額外屬性:

public loadedMeshes: Array<AbstractMesh>;
public loadedParticleSystems: Array<ParticleSystem>;
public loadedSkeletons: Array<Skeleton>;

TextFileAssetTask

用於異步加載(文本)文件。
構造函數配置指定:

constructor(name: string, url: string)

額外屬性:

public url: string;
public text: string;

BinaryFileAssetTask

此任務用於加載二進制文件。它與TextFileAssetTask的主要區別在於數據將存儲在ArrayBuffer中
構造函數配置指定:

constructor(name: string, url: string)

額外屬性:

public url: string;
public data: ArrayBuffer;

ImageAssetTask

此功能將加載圖像(.png,.jpg,.gif)。它將創建一個HTMLImageElement對象
構造函數配置指定:

constructor(name: string, url: string)

額外屬性:

public url: string;
public image: HTMLImageElement;

TextureAssetTask

這將從提供​​的單個URL創建一個新的BABYLON.Texture。
構造函數配置指定:

constructor(name: string, url: string, noMipmap?: boolean, invertY?: boolean, samplingMode: number = BABYLON.Texture.TRILINEAR_SAMPLINGMODE)

額外屬性:

public texture: Texture;

CubeTextureAssetTask

與TextureAssetTask相同,但對於立方體紋理
構造函數配置指定:

constructor(name: string, url: string, extensions?: string[], noMipmap?: boolean, files?: string[])

額外屬性:

public texture: CubeTexture;

HDRCubeTextureAssetTask

與CubeTextureAssetTask相同,但適用於HDR立方體紋理
構造函數配置指定:

constructor(name: string, url: string, size?: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false, usePMREMGenerator = false)

額外屬性:

public texture: HDRCubeTexture;

EquiRectangularCubeTextureAssetTask

與CubeTextureAssetTask相同,但對於Equirectangular立方體紋理
構造函數配置指定:

constructor(name: string, url: string, size: number, noMipmap = false, useInGammaSpace = true)

額外屬性:

public texture: EquiRectangularCubeTexture;

使用加載屏幕

默認情況下,AssetsManager將在加載資源時顯示加載屏幕:
在這裏插入圖片描述
如果要禁用加載屏幕,則必須設置useDefaultLoadingScreen爲false:

assetsManager.useDefaultLoadingScreen = false;

如果ShowLoadingScreen設置爲true(默認情況下),則在使用SceneLoader加載場景時也會顯示加載屏幕。

BABYLON.SceneLoader.ShowLoadingScreen = false;

同樣,您也可以使用以下功能手動顯示或隱藏加載屏幕:

engine.displayLoadingUI();
engine.hideLoadingUI();

使用loadingUIText設置顯示加載文本:

engine.loadingUIText = "text";

使用loadingUIBackgroundColor方法控制背景顏色:

engine.loadingUIBackgroundColor = "red";
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章