BabylonLodMesh.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. using System;
  2. using System.IO;
  3. using System.Collections.Generic;
  4. using System.Runtime.Serialization;
  5. using System.Net;
  6. using Vertice.Core;
  7. using BabylonExport.Core;
  8. using Newtonsoft.Json;
  9. namespace BabylonBinaryConverter
  10. {
  11. public enum VertexAttributes
  12. {
  13. Undefined = 0,
  14. Position = 2,
  15. Color = 4,
  16. Normal = 8,
  17. Uv1 = 16,
  18. Uv2 = 32,
  19. HPos = 64
  20. }
  21. public enum DataType
  22. {
  23. Byte,
  24. UByte,
  25. Int16,
  26. UInt16,
  27. Int32,
  28. UInt32,
  29. Int64,
  30. UInt64,
  31. Float,
  32. Double
  33. }
  34. [DataContract]
  35. public class IncrMeshData
  36. {
  37. [DataMember]
  38. public float[] positions { get; set; }
  39. [DataMember]
  40. public float[] colors { get; set; }
  41. [DataMember]
  42. public float[] normals { get; set; }
  43. [DataMember]
  44. public float[] uvs { get; set; }
  45. [DataMember]
  46. public float[] uvs2 { get; set; }
  47. [DataMember]
  48. public int[] indices { get; set; }
  49. [DataMember]
  50. public int[] matricesIndices { get; set; }
  51. [DataMember]
  52. public float[] matricesWeights { get; set; }
  53. [DataMember]
  54. public BabylonSubMesh[] subMeshes { get; set; }
  55. }
  56. [DataContract]
  57. public class AttrDesc
  58. {
  59. [DataMember]
  60. public int count;
  61. [DataMember]
  62. public int stride;
  63. [DataMember]
  64. public long offset;
  65. [DataMember]
  66. public DataType dataType;
  67. public AttrDesc()
  68. {
  69. count = 0;
  70. stride = 0;
  71. offset = 0;
  72. dataType = DataType.Float;
  73. }
  74. public AttrDesc(int _count, int _stride, long _offset, DataType _dataType)
  75. {
  76. count = _count;
  77. stride = _stride;
  78. offset = _offset;
  79. dataType = _dataType;
  80. }
  81. }
  82. [DataContract]
  83. public class BabylonLodMesh : BabylonMesh
  84. {
  85. [DataMember]
  86. public int lod { get; set; }
  87. [DataMember]
  88. public float distance { get; set; }
  89. [DataMember]
  90. public string delayLoadingFile { get; set; }
  91. [DataMember]
  92. public float[] boundingBoxMinimum { get; set; }
  93. [DataMember]
  94. public float[] boundingBoxMaximum { get; set; }
  95. [DataMember]
  96. public bool hasUVs { get; set; }
  97. [DataMember]
  98. public bool hasUVs2 { get; set; }
  99. [DataMember]
  100. public bool hasColors { get; set; }
  101. [DataMember]
  102. public bool hasMatricesIndices { get; set; }
  103. [DataMember]
  104. public bool hasMatricesWeights { get; set; }
  105. [DataMember]
  106. public AttrDesc positionsAttrDesc { get; set; }
  107. [DataMember]
  108. public AttrDesc colorsAttrDesc { get; set; }
  109. [DataMember]
  110. public AttrDesc normalsAttrDesc { get; set; }
  111. [DataMember]
  112. public AttrDesc uvsAttrDesc { get; set; }
  113. [DataMember]
  114. public AttrDesc uvs2AttrDesc { get; set; }
  115. [DataMember]
  116. public AttrDesc indicesAttrDesc { get; set; }
  117. [DataMember]
  118. public AttrDesc matricesIndicesAttrDesc { get; set; }
  119. [DataMember]
  120. public AttrDesc matricesWeightsAttrDesc { get; set; }
  121. [DataMember]
  122. public AttrDesc combinedAttrDesc { get; set; }
  123. [DataMember]
  124. public VertexAttributes vertexAttributes { get; set; }
  125. const string fileEXT = ".binarymesh.babylon";
  126. public BabylonLodMesh() : base()
  127. {
  128. lod = 0;
  129. distance = 0.0f;
  130. delayLoadingFile = "";
  131. positionsAttrDesc = new AttrDesc();
  132. colorsAttrDesc = new AttrDesc();
  133. normalsAttrDesc = new AttrDesc();
  134. uvsAttrDesc = new AttrDesc();
  135. uvs2AttrDesc = new AttrDesc();
  136. indicesAttrDesc = new AttrDesc();
  137. matricesIndicesAttrDesc = new AttrDesc();
  138. matricesWeightsAttrDesc = new AttrDesc();
  139. combinedAttrDesc = new AttrDesc();
  140. vertexAttributes = VertexAttributes.Undefined;
  141. }
  142. public void Convert(string srcPath, string dstPath, bool _combined = false, int _lod = 0, float _distance = 0.0f)
  143. {
  144. lod = _lod;
  145. distance = _distance;
  146. if (Path.GetExtension(delayLoadingFile).CompareTo(".babylonmeshdata") == 0)
  147. LoadMeshData(Path.Combine(srcPath, delayLoadingFile));
  148. if (string.IsNullOrEmpty(delayLoadingFile))
  149. delayLoadingFile = id + fileEXT;
  150. else
  151. delayLoadingFile = Path.GetFileNameWithoutExtension(delayLoadingFile) + fileEXT;
  152. string fullPath = Path.Combine(dstPath, delayLoadingFile);
  153. if (localMatrix == null)
  154. localMatrix = Matrix.Identity.ToArray();
  155. if (boundingBoxMinimum == null || boundingBoxMaximum == null)
  156. CalculateBoundingBox();
  157. if (!_combined)
  158. MultipleBuffers(fullPath);
  159. else
  160. VertexBuffer(fullPath);
  161. }
  162. private void LoadMeshData(string srcFilename)
  163. {
  164. try
  165. {
  166. string filename = WebUtility.UrlDecode(srcFilename);
  167. IncrMeshData meshData = JsonConvert.DeserializeObject<IncrMeshData>(File.ReadAllText(filename));
  168. positions = meshData.positions;
  169. colors = meshData.colors;
  170. normals = meshData.normals;
  171. uvs = meshData.uvs;
  172. uvs2 = meshData.uvs2;
  173. indices = meshData.indices;
  174. matricesIndices = meshData.matricesIndices;
  175. matricesWeights = meshData.matricesWeights;
  176. subMeshes = meshData.subMeshes;
  177. }
  178. catch (Exception ex)
  179. {
  180. Console.ForegroundColor = ConsoleColor.Red;
  181. Console.WriteLine();
  182. Console.WriteLine(ex.Message);
  183. Console.ForegroundColor = ConsoleColor.DarkCyan;
  184. Console.WriteLine(ex);
  185. Console.ResetColor();
  186. }
  187. }
  188. private void MultipleBuffers(string fullPath)
  189. {
  190. try
  191. {
  192. using (var stream = File.Open(WebUtility.UrlDecode(fullPath), FileMode.Create))
  193. {
  194. BinaryWriter writer = new BinaryWriter(stream);
  195. if (positions != null && positions.Length > 0)
  196. {
  197. positionsAttrDesc.count = positions.Length;
  198. positionsAttrDesc.stride = 3;
  199. positionsAttrDesc.offset = stream.Length;
  200. positionsAttrDesc.dataType = DataType.Float;
  201. for (int x = 0; x < positions.Length; x++)
  202. writer.Write(positions[x]);
  203. positions = null;
  204. }
  205. if (colors != null && colors.Length > 0)
  206. {
  207. colorsAttrDesc.count = colors.Length;
  208. colorsAttrDesc.stride = 3;
  209. colorsAttrDesc.offset = stream.Length;
  210. colorsAttrDesc.dataType = DataType.Float;
  211. for (int x = 0; x < colors.Length; x++)
  212. writer.Write(colors[x]);
  213. hasColors = true;
  214. colors = null;
  215. }
  216. if (normals != null && normals.Length > 0)
  217. {
  218. normalsAttrDesc.count = normals.Length;
  219. normalsAttrDesc.stride = 3;
  220. normalsAttrDesc.offset = stream.Length;
  221. normalsAttrDesc.dataType = DataType.Float;
  222. for (int x = 0; x < normals.Length; x++)
  223. writer.Write(normals[x]);
  224. normals = null;
  225. }
  226. if (uvs != null && uvs.Length > 0)
  227. {
  228. uvsAttrDesc.count = uvs.Length;
  229. uvsAttrDesc.stride = 2;
  230. uvsAttrDesc.offset = stream.Length;
  231. uvsAttrDesc.dataType = DataType.Float;
  232. for (int x = 0; x < uvs.Length; x++)
  233. writer.Write(uvs[x]);
  234. hasUVs = true;
  235. uvs = null;
  236. }
  237. if (uvs2 != null && uvs2.Length > 0)
  238. {
  239. uvs2AttrDesc.count = uvs2.Length;
  240. uvs2AttrDesc.stride = 2;
  241. uvs2AttrDesc.offset = stream.Length;
  242. uvs2AttrDesc.dataType = DataType.Float;
  243. for (int x = 0; x < uvs2.Length; x++)
  244. writer.Write(uvs2[x]);
  245. hasUVs2 = true;
  246. uvs2 = null;
  247. }
  248. if (indices != null && indices.Length > 0)
  249. {
  250. indicesAttrDesc.count = indices.Length;
  251. indicesAttrDesc.stride = 1;
  252. indicesAttrDesc.offset = stream.Length;
  253. indicesAttrDesc.dataType = DataType.Int32;
  254. for (int x = 0; x < indices.Length; x++)
  255. writer.Write(indices[x]);
  256. indices = null;
  257. }
  258. if (matricesIndices != null && matricesIndices.Length > 0)
  259. {
  260. matricesIndicesAttrDesc.count = matricesIndices.Length;
  261. matricesIndicesAttrDesc.stride = 1;
  262. matricesIndicesAttrDesc.offset = stream.Length;
  263. matricesIndicesAttrDesc.dataType = DataType.Int32;
  264. for (int x = 0; x < matricesIndices.Length; x++)
  265. writer.Write(matricesIndices[x]);
  266. hasMatricesIndices = true;
  267. matricesIndices = null;
  268. }
  269. if (matricesWeights != null && matricesWeights.Length > 0)
  270. {
  271. matricesWeightsAttrDesc.count = matricesWeights.Length;
  272. matricesWeightsAttrDesc.stride = 2;
  273. matricesWeightsAttrDesc.offset = stream.Length;
  274. matricesWeightsAttrDesc.dataType = DataType.Float;
  275. for (int x = 0; x < matricesWeights.Length; x++)
  276. writer.Write(matricesWeights[x]);
  277. hasMatricesWeights = true;
  278. matricesWeights = null;
  279. }
  280. }
  281. }
  282. catch (Exception ex)
  283. {
  284. Console.ForegroundColor = ConsoleColor.Red;
  285. Console.WriteLine();
  286. Console.WriteLine(ex.Message);
  287. Console.ForegroundColor = ConsoleColor.DarkCyan;
  288. Console.WriteLine(ex);
  289. Console.ResetColor();
  290. }
  291. }
  292. private void VertexBuffer(string fullPath)
  293. {
  294. combinedAttrDesc.count = positions.Length;
  295. combinedAttrDesc.stride = 0;
  296. combinedAttrDesc.offset = 0;
  297. vertexAttributes = VertexAttributes.Undefined;
  298. if (positions != null && positions.Length > 0)
  299. {
  300. vertexAttributes |= VertexAttributes.Position;
  301. combinedAttrDesc.stride += 3;
  302. }
  303. if (colors != null && colors.Length > 0)
  304. {
  305. vertexAttributes |= VertexAttributes.Color;
  306. combinedAttrDesc.stride += 4;
  307. }
  308. if (normals != null && normals.Length > 0)
  309. {
  310. vertexAttributes |= VertexAttributes.Normal;
  311. combinedAttrDesc.stride += 3;
  312. }
  313. if (uvs != null && uvs.Length > 0)
  314. {
  315. vertexAttributes |= VertexAttributes.Uv1;
  316. combinedAttrDesc.stride += 2;
  317. }
  318. if (uvs2 != null && uvs2.Length > 0)
  319. {
  320. vertexAttributes |= VertexAttributes.Uv2;
  321. combinedAttrDesc.stride += 2;
  322. }
  323. List<float> data = new List<float>();
  324. using (var stream = File.Open(WebUtility.UrlDecode(fullPath), FileMode.Create))
  325. {
  326. }
  327. }
  328. private void CalculateBoundingBox()
  329. {
  330. Vector3 min = new Vector3(0.0f, 0.0f, 0.0f);
  331. Vector3 max = new Vector3(0.0f, 0.0f, 0.0f);
  332. if (positions != null && positions.Length > 0)
  333. {
  334. Vector3 src = new Vector3(positions[0], positions[1], positions[2]);
  335. min = src;
  336. max = src;
  337. for (int x = 3; x < positions.Length; x += 3)
  338. {
  339. if (x + 2 < positions.Length)
  340. {
  341. src.X = positions[x + 0];
  342. src.Y = positions[x + 1];
  343. src.Z = positions[x + 2];
  344. VecMin(src, ref min);
  345. VecMax(src, ref max);
  346. }
  347. }
  348. }
  349. boundingBoxMinimum = min.ToArray();
  350. boundingBoxMaximum = max.ToArray();
  351. }
  352. private void VecMin(Vector3 src, ref Vector3 dst)
  353. {
  354. if (src.X < dst.X)
  355. dst.X = src.X;
  356. if (src.Y < dst.Y)
  357. dst.Y = src.Y;
  358. if (src.Z < dst.Z)
  359. dst.Z = src.Z;
  360. }
  361. private void VecMax(Vector3 src, ref Vector3 dst)
  362. {
  363. if (src.X > dst.X)
  364. dst.X = src.X;
  365. if (src.Y > dst.Y)
  366. dst.Y = src.Y;
  367. if (src.Z > dst.Z)
  368. dst.Z = src.Z;
  369. }
  370. }
  371. }