VoxelData.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. using UnityEngine;
  2. using UnityEngine.Assertions;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. #if UNITY_EDITOR
  7. namespace VoxelImporter
  8. {
  9. public class VoxelData
  10. {
  11. [System.Diagnostics.DebuggerDisplay("Position({x}, {y}, {z}), Palette({palette})")]
  12. public struct Voxel
  13. {
  14. public Voxel(int x, int y, int z, int palette, VoxelBase.Face visible = VoxelBase.Face.forward | VoxelBase.Face.up | VoxelBase.Face.right | VoxelBase.Face.left | VoxelBase.Face.down | VoxelBase.Face.back)
  15. {
  16. this.x = x;
  17. this.y = y;
  18. this.z = z;
  19. this.palette = palette;
  20. this.visible = visible;
  21. }
  22. public IntVector3 position { get { return new IntVector3(x, y, z); } set { x = value.x; y = value.y; z = value.z; } }
  23. public int x;
  24. public int y;
  25. public int z;
  26. public int palette;
  27. public VoxelBase.Face visible;
  28. }
  29. #region FaceArea
  30. public struct FaceArea
  31. {
  32. public IntVector3 min;
  33. public IntVector3 max;
  34. public int palette;
  35. public int material;
  36. public IntVector3 size { get { return max - min + IntVector3.one; } }
  37. public Vector3 minf { get { return new Vector3(min.x, min.y, min.z); } }
  38. public Vector3 maxf { get { return new Vector3(max.x, max.y, max.z); } }
  39. public IntVector3 Get(VoxelBase.VoxelVertexIndex index)
  40. {
  41. switch (index)
  42. {
  43. case VoxelBase.VoxelVertexIndex.XYZ: return new IntVector3(max.x, max.y, max.z);
  44. case VoxelBase.VoxelVertexIndex._XYZ: return new IntVector3(min.x, max.y, max.z);
  45. case VoxelBase.VoxelVertexIndex.X_YZ: return new IntVector3(max.x, min.y, max.z);
  46. case VoxelBase.VoxelVertexIndex.XY_Z: return new IntVector3(max.x, max.y, min.z);
  47. case VoxelBase.VoxelVertexIndex._X_YZ: return new IntVector3(min.x, min.y, max.z);
  48. case VoxelBase.VoxelVertexIndex._XY_Z: return new IntVector3(min.x, max.y, min.z);
  49. case VoxelBase.VoxelVertexIndex.X_Y_Z: return new IntVector3(max.x, min.y, min.z);
  50. case VoxelBase.VoxelVertexIndex._X_Y_Z: return new IntVector3(min.x, min.y, min.z);
  51. default: Assert.IsFalse(false); return IntVector3.zero;
  52. }
  53. }
  54. }
  55. public class FaceAreaTable
  56. {
  57. public List<FaceArea> forward = new List<FaceArea>();
  58. public List<FaceArea> up = new List<FaceArea>();
  59. public List<FaceArea> right = new List<FaceArea>();
  60. public List<FaceArea> left = new List<FaceArea>();
  61. public List<FaceArea> down = new List<FaceArea>();
  62. public List<FaceArea> back = new List<FaceArea>();
  63. public void Merge(FaceAreaTable src)
  64. {
  65. forward.AddRange(src.forward);
  66. up.AddRange(src.up);
  67. right.AddRange(src.right);
  68. left.AddRange(src.left);
  69. down.AddRange(src.down);
  70. back.AddRange(src.back);
  71. }
  72. public void ReplacePalette(int[] paletteTable)
  73. {
  74. for (int i = 0; i < forward.Count; i++)
  75. {
  76. var faceArea = forward[i];
  77. faceArea.palette = paletteTable[faceArea.palette];
  78. forward[i] = faceArea;
  79. }
  80. for (int i = 0; i < up.Count; i++)
  81. {
  82. var faceArea = up[i];
  83. faceArea.palette = paletteTable[faceArea.palette];
  84. up[i] = faceArea;
  85. }
  86. for (int i = 0; i < right.Count; i++)
  87. {
  88. var faceArea = right[i];
  89. faceArea.palette = paletteTable[faceArea.palette];
  90. right[i] = faceArea;
  91. }
  92. for (int i = 0; i < left.Count; i++)
  93. {
  94. var faceArea = left[i];
  95. faceArea.palette = paletteTable[faceArea.palette];
  96. left[i] = faceArea;
  97. }
  98. for (int i = 0; i < down.Count; i++)
  99. {
  100. var faceArea = down[i];
  101. faceArea.palette = paletteTable[faceArea.palette];
  102. down[i] = faceArea;
  103. }
  104. for (int i = 0; i < back.Count; i++)
  105. {
  106. var faceArea = back[i];
  107. faceArea.palette = paletteTable[faceArea.palette];
  108. back[i] = faceArea;
  109. }
  110. }
  111. }
  112. #endregion
  113. #region VoxelTable
  114. private DataTable3<int> voxelTable;
  115. public List<IntVector3> vertexList;
  116. private FlagTable3 outsideTable;
  117. public void CreateVoxelTable()
  118. {
  119. #region voxelTable
  120. {
  121. voxelTable = new DataTable3<int>(voxelSize.x, voxelSize.y, voxelSize.z);
  122. if (voxels != null)
  123. {
  124. for (int i = 0; i < voxels.Length; i++)
  125. {
  126. voxelTable.Set(voxels[i].position, i);
  127. }
  128. }
  129. }
  130. #endregion
  131. #region vertexList
  132. {
  133. vertexList = new List<IntVector3>();
  134. bool[,,] doneTable = new bool[voxelSize.x + 1, voxelSize.y + 1, voxelSize.z + 1];
  135. Action<IntVector3> AddPoint = (pos) =>
  136. {
  137. if (pos.x < 0 || pos.y < 0 || pos.z < 0) return;
  138. if (!doneTable[pos.x, pos.y, pos.z])
  139. {
  140. doneTable[pos.x, pos.y, pos.z] = true;
  141. vertexList.Add(pos);
  142. }
  143. };
  144. if (voxels != null)
  145. {
  146. for (int i = 0; i < voxels.Length; i++)
  147. {
  148. AddPoint(new IntVector3(voxels[i].x, voxels[i].y, voxels[i].z));
  149. AddPoint(new IntVector3(voxels[i].x + 1, voxels[i].y, voxels[i].z));
  150. AddPoint(new IntVector3(voxels[i].x, voxels[i].y + 1, voxels[i].z));
  151. AddPoint(new IntVector3(voxels[i].x, voxels[i].y, voxels[i].z + 1));
  152. AddPoint(new IntVector3(voxels[i].x + 1, voxels[i].y + 1, voxels[i].z));
  153. AddPoint(new IntVector3(voxels[i].x + 1, voxels[i].y, voxels[i].z + 1));
  154. AddPoint(new IntVector3(voxels[i].x, voxels[i].y + 1, voxels[i].z + 1));
  155. AddPoint(new IntVector3(voxels[i].x + 1, voxels[i].y + 1, voxels[i].z + 1));
  156. }
  157. }
  158. }
  159. #endregion
  160. #region outsideTable
  161. {
  162. outsideTable = new FlagTable3(voxelSize.x, voxelSize.y, voxelSize.z);
  163. List<IntVector3> findList = new List<IntVector3>(voxelSize.x * voxelSize.y * voxelSize.z);
  164. Action<int, int, int> AddFindList = (x, y, z) =>
  165. {
  166. if (x < 0 || x >= voxelSize.x || y < 0 || y >= voxelSize.y || z < 0 || z >= voxelSize.z) return;
  167. if (outsideTable.Get(x, y, z)) return;
  168. if (VoxelTableContains(x, y, z) >= 0) return;
  169. findList.Add(new IntVector3(x, y, z));
  170. outsideTable.Set(x, y, z, true);
  171. };
  172. for (int x = 0; x < voxelSize.x; x++)
  173. {
  174. for (int y = 0; y < voxelSize.y; y++)
  175. {
  176. AddFindList(x, y, 0);
  177. AddFindList(x, y, voxelSize.z - 1);
  178. }
  179. }
  180. for (int x = 0; x < voxelSize.x; x++)
  181. {
  182. for (int z = 0; z < voxelSize.z; z++)
  183. {
  184. AddFindList(x, 0, z);
  185. AddFindList(x, voxelSize.y - 1, z);
  186. }
  187. }
  188. for (int z = 0; z < voxelSize.z; z++)
  189. {
  190. for (int y = 0; y < voxelSize.y; y++)
  191. {
  192. AddFindList(0, y, z);
  193. AddFindList(voxelSize.x - 1, y, z);
  194. }
  195. }
  196. for (int i = 0; i < findList.Count; i++)
  197. {
  198. var pos = findList[i];
  199. AddFindList(pos.x + 1, pos.y, pos.z);
  200. AddFindList(pos.x - 1, pos.y, pos.z);
  201. AddFindList(pos.x, pos.y + 1, pos.z);
  202. AddFindList(pos.x, pos.y - 1, pos.z);
  203. AddFindList(pos.x, pos.y, pos.z + 1);
  204. AddFindList(pos.x, pos.y, pos.z - 1);
  205. }
  206. }
  207. #endregion
  208. updateVoxelTableLastTimeTicks = DateTime.Now.Ticks;
  209. }
  210. public int VoxelTableContains(IntVector3 pos)
  211. {
  212. if (!voxelTable.Contains(pos))
  213. return -1;
  214. else
  215. return voxelTable.Get(pos);
  216. }
  217. public int VoxelTableContains(int x, int y, int z)
  218. {
  219. if (!voxelTable.Contains(x, y, z))
  220. return -1;
  221. else
  222. return voxelTable.Get(x, y, z);
  223. }
  224. public bool OutsideTableContains(IntVector3 pos)
  225. {
  226. if (pos.x < 0 || pos.x >= voxelSize.x ||
  227. pos.y < 0 || pos.y >= voxelSize.y ||
  228. pos.z < 0 || pos.z >= voxelSize.z)
  229. return true;
  230. else
  231. return outsideTable.Get(pos);
  232. }
  233. public bool OutsideTableContains(int x, int y, int z)
  234. {
  235. if (x < 0 || x >= voxelSize.x ||
  236. y < 0 || y >= voxelSize.y ||
  237. z < 0 || z >= voxelSize.z)
  238. return true;
  239. else
  240. return outsideTable.Get(x, y, z);
  241. }
  242. #endregion
  243. #region Chunk
  244. public DataTable3<IntVector3> chunkTable;
  245. public struct ChunkArea
  246. {
  247. public IntVector3 min;
  248. public IntVector3 max;
  249. public Vector3 minf { get { return new Vector3(min.x, min.y, min.z); } }
  250. public Vector3 maxf { get { return new Vector3(max.x, max.y, max.z); } }
  251. public Vector3 centerf { get { return Vector3.Lerp(minf, maxf, 0.5f); } }
  252. }
  253. public struct ChunkData
  254. {
  255. public string name;
  256. public ChunkArea area;
  257. }
  258. public DataTable3<int> chunkIndexTable;
  259. public List<ChunkData> chunkDataList;
  260. #endregion
  261. #region Material
  262. public struct VoxMaterial
  263. {
  264. public enum Type
  265. {
  266. diffuse,
  267. metal,
  268. glass,
  269. emissive,
  270. }
  271. public Type materialType;
  272. public float materialWeight;
  273. public uint propertyBits;
  274. public float[] normalizedPropertyValues;
  275. public float GetNormalizedPropertyValues(int index)
  276. {
  277. int count = 0;
  278. for (int i = 0; i < index; i++)
  279. {
  280. if((propertyBits & (1<<i)) != 0)
  281. count++;
  282. }
  283. if ((propertyBits & (1 << index)) != 0 && normalizedPropertyValues != null && count < normalizedPropertyValues.Length)
  284. return normalizedPropertyValues[count];
  285. else
  286. return 0f;
  287. }
  288. }
  289. #endregion
  290. public Voxel[] voxels;
  291. public Color[] palettes;
  292. public IntVector3 voxelSize;
  293. public Dictionary<int, VoxMaterial> materials;
  294. public long updateVoxelTableLastTimeTicks;
  295. }
  296. }
  297. #endif