BabylonLodMesh.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  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 subMeshesAttrDesc { get; set; }
  123. [DataMember]
  124. public AttrDesc combinedAttrDesc { get; set; }
  125. [DataMember]
  126. public VertexAttributes vertexAttributes { get; set; }
  127. const string fileEXT = ".binarymesh.babylon";
  128. public BabylonLodMesh() : base()
  129. {
  130. lod = 0;
  131. distance = 0.0f;
  132. delayLoadingFile = "";
  133. positionsAttrDesc = new AttrDesc();
  134. colorsAttrDesc = new AttrDesc();
  135. normalsAttrDesc = new AttrDesc();
  136. uvsAttrDesc = new AttrDesc();
  137. uvs2AttrDesc = new AttrDesc();
  138. indicesAttrDesc = new AttrDesc();
  139. matricesIndicesAttrDesc = new AttrDesc();
  140. matricesWeightsAttrDesc = new AttrDesc();
  141. subMeshesAttrDesc = new AttrDesc();
  142. combinedAttrDesc = new AttrDesc();
  143. vertexAttributes = VertexAttributes.Undefined;
  144. }
  145. public void Convert(string srcPath, string dstPath, bool _combined = false, int _lod = 0, float _distance = 0.0f)
  146. {
  147. lod = _lod;
  148. distance = _distance;
  149. if (Path.GetExtension(delayLoadingFile).CompareTo(".babylonmeshdata") == 0)
  150. LoadMeshData(Path.Combine(srcPath, delayLoadingFile));
  151. if (string.IsNullOrEmpty(delayLoadingFile))
  152. //delayLoadingFile = name + fileEXT;
  153. delayLoadingFile = id + fileEXT;
  154. else
  155. delayLoadingFile = Path.GetFileNameWithoutExtension(delayLoadingFile) + fileEXT;
  156. string fullPath = Path.Combine(dstPath, delayLoadingFile);
  157. if (localMatrix == null)
  158. localMatrix = Matrix.Identity.ToArray();
  159. CalculateBoundingBox();
  160. if (!_combined)
  161. WriteMultipleBuffers(fullPath);
  162. else
  163. VertexBuffer(fullPath);
  164. }
  165. private void LoadMeshData(string srcFilename)
  166. {
  167. try
  168. {
  169. string filename = WebUtility.UrlDecode(srcFilename);
  170. IncrMeshData incrMeshData = JsonConvert.DeserializeObject<IncrMeshData>(File.ReadAllText(filename));
  171. positions = incrMeshData.positions;
  172. colors = incrMeshData.colors;
  173. normals = incrMeshData.normals;
  174. uvs = incrMeshData.uvs;
  175. uvs2 = incrMeshData.uvs2;
  176. indices = incrMeshData.indices;
  177. matricesIndices = incrMeshData.matricesIndices;
  178. matricesWeights = incrMeshData.matricesWeights;
  179. subMeshes = incrMeshData.subMeshes;
  180. }
  181. catch (Exception ex)
  182. {
  183. Console.ForegroundColor = ConsoleColor.Red;
  184. Console.WriteLine();
  185. Console.WriteLine(ex.Message);
  186. Console.ForegroundColor = ConsoleColor.DarkCyan;
  187. Console.WriteLine(ex);
  188. Console.ResetColor();
  189. }
  190. }
  191. private void WriteMultipleBuffers(string fullPath)
  192. {
  193. try
  194. {
  195. using (var stream = File.Open(WebUtility.UrlDecode(fullPath), FileMode.Create))
  196. {
  197. BinaryWriter writer = new BinaryWriter(stream);
  198. if (positions != null && positions.Length > 0)
  199. {
  200. positionsAttrDesc.count = positions.Length;
  201. positionsAttrDesc.stride = 3;
  202. positionsAttrDesc.offset = stream.Length;
  203. positionsAttrDesc.dataType = DataType.Float;
  204. for (int x = 0; x < positions.Length; x++)
  205. writer.Write(positions[x]);
  206. positions = null;
  207. }
  208. if (colors != null && colors.Length > 0)
  209. {
  210. colorsAttrDesc.count = colors.Length;
  211. colorsAttrDesc.stride = 3;
  212. colorsAttrDesc.offset = stream.Length;
  213. colorsAttrDesc.dataType = DataType.Float;
  214. for (int x = 0; x < colors.Length; x++)
  215. writer.Write(colors[x]);
  216. hasColors = true;
  217. colors = null;
  218. }
  219. if (normals != null && normals.Length > 0)
  220. {
  221. normalsAttrDesc.count = normals.Length;
  222. normalsAttrDesc.stride = 3;
  223. normalsAttrDesc.offset = stream.Length;
  224. normalsAttrDesc.dataType = DataType.Float;
  225. for (int x = 0; x < normals.Length; x++)
  226. writer.Write(normals[x]);
  227. normals = null;
  228. }
  229. if (uvs != null && uvs.Length > 0)
  230. {
  231. uvsAttrDesc.count = uvs.Length;
  232. uvsAttrDesc.stride = 2;
  233. uvsAttrDesc.offset = stream.Length;
  234. uvsAttrDesc.dataType = DataType.Float;
  235. for (int x = 0; x < uvs.Length; x++)
  236. writer.Write(uvs[x]);
  237. hasUVs = true;
  238. writer.Flush();
  239. uvs = null;
  240. }
  241. if (uvs2 != null && uvs2.Length > 0)
  242. {
  243. uvs2AttrDesc.count = uvs2.Length;
  244. uvs2AttrDesc.stride = 2;
  245. uvs2AttrDesc.offset = stream.Length;
  246. uvs2AttrDesc.dataType = DataType.Float;
  247. for (int x = 0; x < uvs2.Length; x++)
  248. writer.Write(uvs2[x]);
  249. hasUVs2 = true;
  250. writer.Flush();
  251. uvs2 = null;
  252. }
  253. if (indices != null && indices.Length > 0)
  254. {
  255. indicesAttrDesc.count = indices.Length;
  256. indicesAttrDesc.stride = 1;
  257. indicesAttrDesc.offset = stream.Length;
  258. indicesAttrDesc.dataType = DataType.Int32;
  259. for (int x = 0; x < indices.Length; x++)
  260. writer.Write(indices[x]);
  261. indices = null;
  262. }
  263. if (matricesIndices != null && matricesIndices.Length > 0)
  264. {
  265. matricesIndicesAttrDesc.count = matricesIndices.Length;
  266. matricesIndicesAttrDesc.stride = 1;
  267. matricesIndicesAttrDesc.offset = stream.Length;
  268. matricesIndicesAttrDesc.dataType = DataType.Int32;
  269. for (int x = 0; x < matricesIndices.Length; x++)
  270. writer.Write(matricesIndices[x]);
  271. hasMatricesIndices = true;
  272. matricesIndices = null;
  273. }
  274. if (matricesWeights != null && matricesWeights.Length > 0)
  275. {
  276. matricesWeightsAttrDesc.count = matricesWeights.Length;
  277. matricesWeightsAttrDesc.stride = 2;
  278. matricesWeightsAttrDesc.offset = stream.Length;
  279. matricesWeightsAttrDesc.dataType = DataType.Float;
  280. for (int x = 0; x < matricesWeights.Length; x++)
  281. writer.Write(matricesWeights[x]);
  282. hasMatricesWeights = true;
  283. matricesWeights = null;
  284. }
  285. if(subMeshes != null && subMeshes.Length > 0)
  286. {
  287. subMeshesAttrDesc.count = subMeshes.Length;
  288. subMeshesAttrDesc.stride = 5;
  289. subMeshesAttrDesc.offset = stream.Length;
  290. subMeshesAttrDesc.dataType = DataType.Int32;
  291. int[] smData = new int[5];
  292. for (int x = 0; x < subMeshes.Length; x++)
  293. {
  294. smData[0] = subMeshes[x].materialIndex;
  295. smData[1] = subMeshes[x].verticesStart;
  296. smData[2] = subMeshes[x].verticesCount;
  297. smData[3] = subMeshes[x].indexStart;
  298. smData[4] = subMeshes[x].indexCount;
  299. for (int y = 0; y < smData.Length; y++)
  300. writer.Write(smData[y]);
  301. }
  302. subMeshes = null;
  303. }
  304. }
  305. }
  306. catch (Exception ex)
  307. {
  308. Console.ForegroundColor = ConsoleColor.Red;
  309. Console.WriteLine();
  310. Console.WriteLine(ex.Message);
  311. Console.ForegroundColor = ConsoleColor.DarkCyan;
  312. Console.WriteLine(ex);
  313. Console.ResetColor();
  314. }
  315. }
  316. private void VertexBuffer(string fullPath)
  317. {
  318. combinedAttrDesc.count = positions.Length;
  319. combinedAttrDesc.stride = 0;
  320. combinedAttrDesc.offset = 0;
  321. vertexAttributes = VertexAttributes.Undefined;
  322. if (positions != null && positions.Length > 0)
  323. {
  324. vertexAttributes |= VertexAttributes.Position;
  325. combinedAttrDesc.stride += 3;
  326. }
  327. if (colors != null && colors.Length > 0)
  328. {
  329. vertexAttributes |= VertexAttributes.Color;
  330. combinedAttrDesc.stride += 4;
  331. }
  332. if (normals != null && normals.Length > 0)
  333. {
  334. vertexAttributes |= VertexAttributes.Normal;
  335. combinedAttrDesc.stride += 3;
  336. }
  337. if (uvs != null && uvs.Length > 0)
  338. {
  339. vertexAttributes |= VertexAttributes.Uv1;
  340. combinedAttrDesc.stride += 2;
  341. }
  342. if (uvs2 != null && uvs2.Length > 0)
  343. {
  344. vertexAttributes |= VertexAttributes.Uv2;
  345. combinedAttrDesc.stride += 2;
  346. }
  347. List<float> data = new List<float>();
  348. using (var stream = File.Open(WebUtility.UrlDecode(fullPath), FileMode.Create))
  349. {
  350. }
  351. }
  352. private void CalculateBoundingBox()
  353. {
  354. Vector3 min = new Vector3(0.0f, 0.0f, 0.0f);
  355. Vector3 max = new Vector3(0.0f, 0.0f, 0.0f);
  356. if (positions != null && positions.Length > 0)
  357. {
  358. Vector3 src = new Vector3(positions[0], positions[1], positions[2]);
  359. min = src;
  360. max = src;
  361. for (int x = 3; x < positions.Length; x += 3)
  362. {
  363. if (x + 2 < positions.Length)
  364. {
  365. src.X = positions[x + 0];
  366. src.Y = positions[x + 1];
  367. src.Z = positions[x + 2];
  368. VecMin(src, ref min);
  369. VecMax(src, ref max);
  370. }
  371. }
  372. }
  373. boundingBoxMinimum = min.ToArray();
  374. boundingBoxMaximum = max.ToArray();
  375. }
  376. private void VecMin(Vector3 src, ref Vector3 dst)
  377. {
  378. if (src.X < dst.X)
  379. dst.X = src.X;
  380. if (src.Y < dst.Y)
  381. dst.Y = src.Y;
  382. if (src.Z < dst.Z)
  383. dst.Z = src.Z;
  384. }
  385. private void VecMax(Vector3 src, ref Vector3 dst)
  386. {
  387. if (src.X > dst.X)
  388. dst.X = src.X;
  389. if (src.Y > dst.Y)
  390. dst.Y = src.Y;
  391. if (src.Z > dst.Z)
  392. dst.Z = src.Z;
  393. }
  394. }
  395. }