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
 
(7 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="csharp" 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="csharp">
</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="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:
 
<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.");
	}
}