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
Sem resumo de edição
 
(8 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
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="c#" line="1">
When loading a model from a file in TriLib 1, the following snippets are used:
 
<pre>
// TriLib 1 Code
// TriLib 1 Code
// --------------------
// --------------------
using (var assetLoader = new AssetLoader()) {
using (var assetLoader = new AssetLoader()) {
var assetLoaderOptions = AssetLoaderOptions.CreateInstance();  //Creates the AssetLoaderOptions instance.
var assetLoaderOptions = AssetLoaderOptions.CreateInstance();  //Creates the AssetLoaderOptions instance.
//AssetLoaderOptions let you specify options to load your model.
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.
//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.
var myGameObject = assetLoader.LoadFromFile("PATH TO MY FILE.FBX", assetLoaderOptions, wrapperGameObject); //Loads the model synchronously and stores the reference in myGameObject.
}
}
</syntaxhighlight><syntaxhighlight lang="c#">
</pre>
 
<pre>
// TriLib 1 Code
// TriLib 1 Code
// --------------------
// --------------------
using (var assetLoaderAsync = new AssetLoaderAsync()) {
using (var assetLoaderAsync = new AssetLoaderAsync()) {
var assetLoaderOptions = AssetLoaderOptions.CreateInstance();  //Creates the AssetLoaderOptions instance.
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.
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) {
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.
//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.
}); //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.
</pre>
 
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.
The first difference with TriLib 2 is that we don't have to specify whether we want to sync or async load our models. TriLib 2 will use async on platforms that support it and sync loading when there is no async support.


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.
* On TriLib 2, we don't have to instantiate an <code>AssetLoader</code> or <code>AssetLoaderAsync</code> class. All loading is now done using the <code>AssetLoader</code> static class.
* TriLib 2 no longer returns a Game Object or a Thread. Instead, it will produce an <code>AssetLoaderContext</code> object containing the loaded Game Object as the <code>RootGameObject</code> field and much more information regarding the model loading.
* TriLib 2 also uses <code>AssetLoaderOptions</code>, but these have changed to adopt a cleaner and file-format agnostic approach. The way we create the <code>AssetLoaderOptions</code> 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:<pre>
// TriLib 2 Code
// TriLib 2 Code
// --------------------
// --------------------
Linha 50: Linha 39:
var myGameObject = assetLoaderContext.RootGameObject;
var myGameObject = assetLoaderContext.RootGameObject;
}, null, null, null, null, assetLoaderOptions);
}, null, null, null, null, assetLoaderOptions);
</syntaxhighlight>
</pre>


==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="c#">
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:
 
<pre>
// TriLib 1 Code
// TriLib 1 Code
// --------------------
// --------------------
Linha 79: Linha 70:
});
});
}
}
</syntaxhighlight>TriLib 2 uses different approaches to load models from custom data sources.
</pre>


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.
TriLib 2 uses different approaches to load models from custom data sources:


The example below loads a model from a custom Stream and handles its external resources with custom ExternalDataMapper and TextureMapper classes.<syntaxhighlight lang="c#">
* First, TriLib 2 works with <code>Stream</code> data reading.
* Second, any external resource the model uses has to be loaded using a class inheriting the <code>ExternalDataMapper</code> class.
* Third, any external texture the model uses has to be loaded using a class inheriting the <code>TextureMapper</code> class.
 
The example below loads a model from a custom Stream and handles its external resources with custom <code>ExternalDataMapper</code> and <code>TextureMapper</code> classes.<pre>
// TriLib 2 Code
// TriLib 2 Code
// --------------------
// --------------------
Linha 91: Linha 86:
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#">
</pre>
 
Here are the Mappers used on the code above. One creates a <code>Steam</code> from external resource files, and the other creates a <code>TextureLoadingContext</code> from files:
 
<pre>
// TriLib 2 Code
// TriLib 2 Code
// --------------------
// --------------------
Linha 107: Linha 106:
}
}
}
}
</syntaxhighlight><syntaxhighlight lang="c#">
</pre>
 
<pre>
// TriLib 2 Code
// TriLib 2 Code
// --------------------
// --------------------
Linha 129: Linha 130:
}
}
}
}
</syntaxhighlight>
</pre>

Edição atual tal como às 09h04min de 18 de maio de 2024

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:

// TriLib 1 Code
// --------------------
using (var assetLoader = new AssetLoader()) {
	var assetLoaderOptions = AssetLoaderOptions.CreateInstance();   //Creates the AssetLoaderOptions instance.																
	var wrapperGameObject = gameObject;                             //Sets the game object where your model will be loaded into.														
	var myGameObject = assetLoader.LoadFromFile("PATH TO MY FILE.FBX", assetLoaderOptions, wrapperGameObject); //Loads the model synchronously and stores the reference in myGameObject.
}
// TriLib 1 Code
// --------------------
using (var assetLoaderAsync = new AssetLoaderAsync()) {
	var assetLoaderOptions = AssetLoaderOptions.CreateInstance();   //Creates the AssetLoaderOptions instance.
	
	var wrapperGameObject = gameObject;                             //Sets the game object where your model will be loaded into.
	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.
}

The first difference with TriLib 2 is that we don't have to specify whether we want to sync or async load our models. TriLib 2 will use async on platforms that support it and sync loading when there is no async support.

  • On TriLib 2, we don't have to instantiate an AssetLoader or AssetLoaderAsync class. All loading is now done using the AssetLoader static class.
  • TriLib 2 no longer returns a Game Object or a Thread. Instead, it will produce an AssetLoaderContext object containing the loaded Game Object 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:

// 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);

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:

// 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
	});
}

TriLib 2 uses different approaches to load models from custom data sources:

  • First, 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.

// 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);

Here are the Mappers used on the code above. One creates a Steam from external resource files, and the other creates a TextureLoadingContext from files:

// 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.");
	}
}
// 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.");
	}
}