Migrating from TriLib 1 to TriLib 2: mudanças entre as edições

De TriLib
Ir para navegação Ir para pesquisar
Sem resumo de edição
Linha 1: Linha 1:
The usage of TriLib 2 is very similar to TriLib 1, but some fundamental changes have been made.
The usage of TriLib 2 is very similar to TriLib 1, but some fundamental changes have been made.
==Loading a Model from a File==
==Loading a Model from a File==
When loading a model from a file in TriLib 1, the following snippets are used:<syntaxhighlight lang="csharp" line="1">
When loading a model from a file in TriLib 1, the following snippets are used:<source lang="csharp" line="1">
// TriLib 1 Code
// TriLib 1 Code
// --------------------
// --------------------
Linha 17: Linha 17:
var myGameObject = assetLoader.LoadFromFile("PATH TO MY FILE.FBX", assetLoaderOptions, wrapperGameObject); //Loads the model synchronously and stores the reference in myGameObject.
var myGameObject = assetLoader.LoadFromFile("PATH TO MY FILE.FBX", assetLoaderOptions, wrapperGameObject); //Loads the model synchronously and stores the reference in myGameObject.
}
}
</syntaxhighlight><syntaxhighlight lang="csharp">
</source ><source lang="csharp">
// TriLib 1 Code
// TriLib 1 Code
// --------------------
// --------------------
Linha 35: Linha 35:
}); //Loads the model asynchronously and returns the reference to the created Task/Thread.
}); //Loads the model asynchronously and returns the reference to the created Task/Thread.
}
}
</syntaxhighlight>The first difference on TriLib 2 is that we don't have to specify if we want to sync or async load our models since TriLib 2 will use async on platforms that support it and fallback to sync loading when there is no support.
</source >The first difference on TriLib 2 is that we don't have to specify if we want to sync or async load our models since TriLib 2 will use async on platforms that support it and fallback to sync loading when there is no support.


On TriLib 2, we don't have to instantiate an AssetLoader or AssetLoaderAsync class. All loading is done using the AssetLoader static class now.
On TriLib 2, we don't have to instantiate an AssetLoader or AssetLoaderAsync class. All loading is done using the AssetLoader static class now.
Linha 43: Linha 43:
TriLib 2 also uses AssetLoaderOptions, but these have changed to adopt a cleaner and file-format agnostic approach. The way we create the AssetLoaderOptions remains the same.
TriLib 2 also uses AssetLoaderOptions, but these have changed to adopt a cleaner and file-format agnostic approach. The way we create the AssetLoaderOptions remains the same.


Given these changes, a simple TriLib 2 model loading that matches the TriLib 1 samples above could be reproduced as:<syntaxhighlight lang="c#">
Given these changes, a simple TriLib 2 model loading that matches the TriLib 1 samples above could be reproduced as:<source lang="c#">
// TriLib 2 Code
// TriLib 2 Code
// --------------------
// --------------------
Linha 50: Linha 50:
var myGameObject = assetLoaderContext.RootGameObject;
var myGameObject = assetLoaderContext.RootGameObject;
}, null, null, null, null, assetLoaderOptions);
}, null, null, null, null, assetLoaderOptions);
</syntaxhighlight>
</source >


==Loading a Model from a Custom Source==
==Loading a Model from a Custom Source==
TriLib 1 allows loading models from byte arrays using a callback to retrieve the custom data, a callback to check if such data exists, and a callback to return custom external textures data from any external resource the model uses:<syntaxhighlight lang="csharp">
TriLib 1 allows loading models from byte arrays using a callback to retrieve the custom data, a callback to check if such data exists, and a callback to return custom external textures data from any external resource the model uses:<source  lang="csharp">
// TriLib 1 Code
// TriLib 1 Code
// --------------------
// --------------------
Linha 79: Linha 79:
});
});
}
}
</syntaxhighlight>TriLib 2 uses different approaches to load models from custom data sources.
</source >TriLib 2 uses different approaches to load models from custom data sources.


First, it doesn't work with byte arrays, specifically anymore. TriLib 2 works with Stream data reading.  Second, any external resource the model uses has to be loaded using a class inheriting the ExternalDataMapper class.  Third, any external texture the model uses has to be loaded using a class inheriting the TextureMapper class.
First, it doesn't work with byte arrays, specifically anymore. TriLib 2 works with Stream data reading.  Second, any external resource the model uses has to be loaded using a class inheriting the ExternalDataMapper class.  Third, any external texture the model uses has to be loaded using a class inheriting the TextureMapper class.


The example below loads a model from a custom Stream and handles its external resources with custom ExternalDataMapper and TextureMapper classes.<syntaxhighlight lang="c#">
The example below loads a model from a custom Stream and handles its external resources with custom ExternalDataMapper and TextureMapper classes.<source lang="c#">
// TriLib 2 Code
// TriLib 2 Code
// --------------------
// --------------------
Linha 91: Linha 91:
var modelPath = "PATH_TO_MY_MODEL.FBX";
var modelPath = "PATH_TO_MY_MODEL.FBX";
AssetLoader.LoadModelFromStream(File.OpenRead(modelPath), modelPath, null, OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions);
AssetLoader.LoadModelFromStream(File.OpenRead(modelPath), modelPath, null, OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions);
</syntaxhighlight>Here are the Mappers used on the code above. One creates Steams from external resource files and the other creates TextureLoadingContexts from files:<syntaxhighlight lang="c#">
</source >Here are the Mappers used on the code above. One creates Steams from external resource files and the other creates TextureLoadingContexts from files:<source lang="c#">
// TriLib 2 Code
// TriLib 2 Code
// --------------------
// --------------------
Linha 107: Linha 107:
}
}
}
}
</syntaxhighlight><syntaxhighlight lang="c#">
</source ><source lang="c#">
// TriLib 2 Code
// TriLib 2 Code
// --------------------
// --------------------
Linha 129: Linha 129:
}
}
}
}
</syntaxhighlight>
</source >

Edição das 12h39min de 28 de fevereiro de 2021

The usage of TriLib 2 is very similar to TriLib 1, but some fundamental changes have been made.

Loading a Model from a File

When loading a model from a file in TriLib 1, the following snippets are used:<source lang="csharp" line="1"> // TriLib 1 Code // -------------------- using (var assetLoader = new AssetLoader()) { var assetLoaderOptions = AssetLoaderOptions.CreateInstance(); //Creates the AssetLoaderOptions instance. //AssetLoaderOptions let you specify options to load your model. //(Optional) You can skip this object creation and it's parameter or pass null.

//You can modify assetLoaderOptions before passing it to LoadFromFile method. You can check the AssetLoaderOptions API reference at: //https://ricardoreis.net/trilib/manual/html/class_tri_lib_1_1_asset_loader_options.html

var wrapperGameObject = gameObject; //Sets the game object where your model will be loaded into. //(Optional) You can skip this object creation and it's parameter or pass null.

var myGameObject = assetLoader.LoadFromFile("PATH TO MY FILE.FBX", assetLoaderOptions, wrapperGameObject); //Loads the model synchronously and stores the reference in myGameObject. } </source ><source lang="csharp"> // TriLib 1 Code // -------------------- using (var assetLoaderAsync = new AssetLoaderAsync()) { var assetLoaderOptions = AssetLoaderOptions.CreateInstance(); //Creates the AssetLoaderOptions instance. //AssetLoaderOptions let you specify options to load your model. //(Optional) You can skip this object creation and it's parameter or pass null.

//You can modify assetLoaderOptions before passing it to LoadFromFile method. You can check the AssetLoaderOptions API reference at: //https://ricardoreis.net/trilib/manual/html/class_tri_lib_1_1_asset_loader_options.html

var wrapperGameObject = gameObject; //Sets the game object where your model will be loaded into. //(Optional) You can skip this object creation and it's parameter or pass null.

var thread = assetLoaderAsync.LoadFromFile("PATH TO MY FILE.FBX", assetLoaderOptions, wrapperGameObject, delegate(GameObject myGameObject) { //Here you can get the reference to the loaded model using myGameObject. }); //Loads the model asynchronously and returns the reference to the created Task/Thread. } </source >The first difference on TriLib 2 is that we don't have to specify if we want to sync or async load our models since TriLib 2 will use async on platforms that support it and fallback to sync loading when there is no support.

On TriLib 2, we don't have to instantiate an AssetLoader or AssetLoaderAsync class. All loading is done using the AssetLoader static class now.

TriLib 2 no longer returns a GameObject or a Thread when loading a model. Instead, it will produce an AssetLoaderContext object containing the loaded GameObject as the RootGameObject field and much more information regarding the model loading.

TriLib 2 also uses AssetLoaderOptions, but these have changed to adopt a cleaner and file-format agnostic approach. The way we create the AssetLoaderOptions remains the same.

Given these changes, a simple TriLib 2 model loading that matches the TriLib 1 samples above could be reproduced as:<source lang="c#"> // TriLib 2 Code // -------------------- var assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions(); AssetLoader.LoadModelFromFile("PATH TO MY FILE.FBX", null, delegate(AssetLoaderContext assetLoaderContext) { var myGameObject = assetLoaderContext.RootGameObject; }, null, null, null, null, assetLoaderOptions); </source >

Loading a Model from a Custom Source

TriLib 1 allows loading models from byte arrays using a callback to retrieve the custom data, a callback to check if such data exists, and a callback to return custom external textures data from any external resource the model uses:<source lang="csharp"> // TriLib 1 Code // -------------------- var modelData = File.ReadAllBytes("PATH_TO_MY_FILE.OBJ"); using (var assetLoader = new AssetLoader()) { var assetLoaderOptions = AssetLoaderOptions.CreateInstance(); var myGameObject = assetLoader.LoadFromMemory(modelData, "MY_FILE.OBJ", assetLoaderOptions, null, "PATH_TO", delegate(string path, int fileId, ref int fileSize) { //External data reading callback var resourceData = File.ReadAllBytes(path); //Reads all external file data fileSize = resourceData.Length; //Retrieves the external file size return resourceData; //Returns the external file data }, delegate(string path, int fileId) { //External data checking callback return File.Exists(path); //Returns true when the external file exists }, delegate (string path, string basePath) { //External texture data reading callback var finalPath = Path.Combine(basePath, path); //Combines the model base path with the texture path if (File.Exists(finalPath)) { //Checks if there is a file on the combined path return File.ReadAllBytes(finalPath); //Returns the file data } return null; //Returns null when the given file could not be found }, delegate (float progress) { //Progress handling callback Debug.Log("Loaded:" + progress); //Writes the model loading progress to the console }); } </source >TriLib 2 uses different approaches to load models from custom data sources.

First, it doesn't work with byte arrays, specifically anymore. TriLib 2 works with Stream data reading. Second, any external resource the model uses has to be loaded using a class inheriting the ExternalDataMapper class. Third, any external texture the model uses has to be loaded using a class inheriting the TextureMapper class.

The example below loads a model from a custom Stream and handles its external resources with custom ExternalDataMapper and TextureMapper classes.<source lang="c#"> // TriLib 2 Code // -------------------- var assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions(); assetLoaderOptions.ExternalDataMapper = ScriptableObject.CreateInstance<ExternalDataMapperSample>(); assetLoaderOptions.TextureMapper = ScriptableObject.CreateInstance<TextureMapperSample>(); var modelPath = "PATH_TO_MY_MODEL.FBX"; AssetLoader.LoadModelFromStream(File.OpenRead(modelPath), modelPath, null, OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions); </source >Here are the Mappers used on the code above. One creates Steams from external resource files and the other creates TextureLoadingContexts from files:<source lang="c#"> // TriLib 2 Code // -------------------- public class ExternalDataMapperSample : ExternalDataMapper { public override Stream Map(AssetLoaderContext assetLoaderContext, string originalFilename, out string finalPath) { finalPath = $"{assetLoaderContext.BasePath}/{FileUtils.GetFilename(originalFilename)}"; if (File.Exists(finalPath)) { Debug.Log($"Found external file at: {finalPath}"); return File.OpenRead(finalPath); } throw new Exception($"File {originalFilename} not found."); } } </source ><source lang="c#"> // TriLib 2 Code // -------------------- public class TextureMapperSample : TextureMapper { public override TextureLoadingContext Map(AssetLoaderContext assetLoaderContext, ITexture texture) { var finalPath = $"{assetLoaderContext.BasePath}/{FileUtils.GetFilename(texture.Filename)}"; if (File.Exists(finalPath)) { var textureLoadingContext = new TextureLoadingContext { Context = assetLoaderContext, Stream = File.OpenRead(finalPath), Texture = texture }; Debug.Log($"Found texture at: {finalPath}"); return textureLoadingContext; } throw new Exception($"Texture {texture.Filename} not found."); } } </source >