SimpleCustomLoaderSample.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using TriLibCore.Interfaces;
  5. using TriLibCore.Utils;
  6. using UnityEngine;
  7. namespace TriLibCore.Samples
  8. {
  9. /// <summary>
  10. /// This sample loads an OBJ model with a single texture from Strings contents as the data source.
  11. /// </summary>
  12. public class SimpleCustomLoaderSample : MonoBehaviour
  13. {
  14. /// <summary>
  15. /// This is the smile.png file data encoded as a Base64 String.
  16. /// </summary>
  17. private const string SmilePngData = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAJUExURQAAAP/yAP///1XtZyMAAAA+SURBVAjXY1gFBAyrQkNXMawMDc1iWBoaGsUwNTQ0jGGqoyOMAHNBxJTQUDGGqaIhQK4DYxhEMVgb2ACQUQBbZhuGX7UQtQAAAABJRU5ErkJggg==";
  18. /// <summary>
  19. /// This is the cube.obj file data as a String.
  20. /// </summary>
  21. private const string CubeObjData =
  22. @"mtllib cube.mtl
  23. g default
  24. v -0.500000 -0.500000 0.500000
  25. v 0.500000 -0.500000 0.500000
  26. v -0.500000 0.500000 0.500000
  27. v 0.500000 0.500000 0.500000
  28. v -0.500000 0.500000 -0.500000
  29. v 0.500000 0.500000 -0.500000
  30. v -0.500000 -0.500000 -0.500000
  31. v 0.500000 -0.500000 -0.500000
  32. vt 0.000000 0.000000
  33. vt 1.000000 0.000000
  34. vt 1.000000 1.000000
  35. vt 0.000000 1.000000
  36. vt 0.000000 1.000000
  37. vt 1.000000 1.000000
  38. vt 1.000000 0.000000
  39. vt 0.000000 0.000000
  40. vt 0.000000 0.000000
  41. vt 1.000000 0.000000
  42. vt 1.000000 1.000000
  43. vt 0.000000 1.000000
  44. vt 1.000000 0.000000
  45. vt 0.000000 0.000000
  46. vt 0.000000 1.000000
  47. vt 1.000000 1.000000
  48. vt 0.000000 0.000000
  49. vt 1.000000 0.000000
  50. vt 1.000000 1.000000
  51. vt 0.000000 1.000000
  52. vt 0.000000 1.000000
  53. vt 1.000000 1.000000
  54. vt 1.000000 0.000000
  55. vt 0.000000 0.000000
  56. vn 0.000000 0.000000 1.000000
  57. vn 0.000000 0.000000 1.000000
  58. vn 0.000000 0.000000 1.000000
  59. vn 0.000000 0.000000 1.000000
  60. vn 0.000000 1.000000 0.000000
  61. vn 0.000000 1.000000 0.000000
  62. vn 0.000000 1.000000 0.000000
  63. vn 0.000000 1.000000 0.000000
  64. vn 0.000000 0.000000 -1.000000
  65. vn 0.000000 0.000000 -1.000000
  66. vn 0.000000 0.000000 -1.000000
  67. vn 0.000000 0.000000 -1.000000
  68. vn 0.000000 -1.000000 0.000000
  69. vn 0.000000 -1.000000 0.000000
  70. vn 0.000000 -1.000000 0.000000
  71. vn 0.000000 -1.000000 0.000000
  72. vn 1.000000 0.000000 0.000000
  73. vn 1.000000 0.000000 0.000000
  74. vn 1.000000 0.000000 0.000000
  75. vn 1.000000 0.000000 0.000000
  76. vn -1.000000 0.000000 0.000000
  77. vn -1.000000 0.000000 0.000000
  78. vn -1.000000 0.000000 0.000000
  79. vn -1.000000 0.000000 0.000000
  80. s off
  81. g cube
  82. usemtl initialShadingGroup
  83. f 1/17/1 2/18/2 4/19/3 3/20/4
  84. f 3/1/5 4/2/6 6/3/7 5/4/8
  85. f 5/21/9 6/22/10 8/23/11 7/24/12
  86. f 7/5/13 8/6/14 2/7/15 1/8/16
  87. f 2/9/17 8/10/18 6/11/19 4/12/20
  88. f 7/13/21 1/14/22 3/15/23 5/16/24
  89. ";
  90. /// <summary>
  91. /// This is the Cube.mtl file data as a String.
  92. /// </summary>
  93. private const string CubeMtlData =
  94. @"newmtl initialShadingGroup
  95. illum 4
  96. Kd 1.00 1.00 1.00
  97. Ka 0.00 0.00 0.00
  98. Tf 1.00 1.00 1.00
  99. map_Kd smile.png
  100. Ni 1.00
  101. Ks 0.00 0.00 0.00
  102. Ns 18.00
  103. ";
  104. /// <summary>
  105. /// Cube.obj filename.
  106. /// </summary>
  107. private const string CubeObjFilename = "cube.obj";
  108. /// <summary>
  109. /// Cube.mtl filename.
  110. /// </summary>
  111. private const string CubeMtlFilename = "cube.mtl";
  112. /// <summary>
  113. /// Smile.png filename.
  114. /// </summary>
  115. private const string SmilePngFilename = "smile.png";
  116. /// <summary>
  117. /// Uses the Cube.obj data bytes to load the model.
  118. /// </summary>
  119. private void Start()
  120. {
  121. var cubeObjBytes = Encoding.UTF8.GetBytes(CubeObjData);
  122. SimpleCustomAssetLoader.LoadModelFromByteData(cubeObjBytes, FileUtils.GetFileExtension(CubeObjFilename, false), OnError, OnProgress, OnModelFullyLoad, CustomDataReceivingCallback, CustomFilenameReceivingCallback, CustomTextureReceivingCallback, CubeObjFilename, gameObject);
  123. }
  124. /// <summary>
  125. /// Event triggered when the loader needs to retrieve the data Stream for a given Texture.
  126. /// </summary>
  127. /// <param name="texture">The source Texture.</param>
  128. /// <returns>The Texture data Stream.</returns>
  129. private Stream CustomTextureReceivingCallback(ITexture texture)
  130. {
  131. var textureShortFilename = FileUtils.GetShortFilename(texture.Filename);
  132. if (textureShortFilename == SmilePngFilename)
  133. {
  134. var smilePngBytes = Convert.FromBase64String(SmilePngData);
  135. return new MemoryStream(smilePngBytes);
  136. }
  137. return null;
  138. }
  139. /// <summary>
  140. /// Event triggered when the loader needs to retrieve the full file-system filename to a given file.
  141. /// This event is optional, so we simply return the filename back.
  142. /// </summary>
  143. /// <param name="filename">The file name.</param>
  144. /// <returns>The full file-system filename.</returns>
  145. private string CustomFilenameReceivingCallback(string filename)
  146. {
  147. return filename;
  148. }
  149. /// <summary>
  150. /// Event triggered when the loader has to retrieve the data Stream for a given external resource.
  151. /// </summary>
  152. /// <param name="filename">The external resource filename.</param>
  153. /// <returns>The external resource data Stream.</returns>
  154. private Stream CustomDataReceivingCallback(string filename)
  155. {
  156. var externalDataShortFilename = FileUtils.GetShortFilename(filename);
  157. if (externalDataShortFilename == CubeMtlFilename)
  158. {
  159. var cubeMtlBytes = Encoding.UTF8.GetBytes(CubeMtlData);
  160. return new MemoryStream(cubeMtlBytes);
  161. }
  162. return null;
  163. }
  164. /// <summary>
  165. /// Event triggered when the model and all the resources have been fully loaded.
  166. /// </summary>
  167. /// <param name="assetLoaderContext"></param>
  168. private void OnModelFullyLoad(AssetLoaderContext assetLoaderContext)
  169. {
  170. if (assetLoaderContext.RootGameObject != null)
  171. {
  172. Debug.Log("Model successfully loaded.");
  173. }
  174. }
  175. /// <summary>
  176. /// Event triggered when the model loading progress changes.
  177. /// </summary>
  178. /// <param name="assetLoaderContext"></param>
  179. /// <param name="progress">The model loading progress in the 0-1 float range.</param>
  180. private void OnProgress(AssetLoaderContext assetLoaderContext, float progress)
  181. {
  182. Debug.Log($"Progress: {progress:P}");
  183. }
  184. /// <summary>
  185. /// Event triggered when any model loading error occurs.
  186. /// </summary>
  187. /// <param name="contextualizedError">The error containing the related context.</param>
  188. private void OnError(IContextualizedError contextualizedError)
  189. {
  190. Debug.LogError($"There was an error loading your model: {contextualizedError}");
  191. }
  192. }
  193. }