VoxelEditorCommon.cs 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. #define PreviewObjectHide
  2. using UnityEngine;
  3. using UnityEngine.Assertions;
  4. using UnityEditor;
  5. using System;
  6. using System.IO;
  7. using System.Collections.Generic;
  8. namespace VoxelImporter
  9. {
  10. public class VoxelEditorCommon
  11. {
  12. public VoxelBase objectTarget { get; private set; }
  13. public VoxelBaseCore objectCore { get; private set; }
  14. public Material vertexColorMaterial { get; private set; }
  15. public Material vertexColorTransparentMaterial { get; private set; }
  16. public Material vertexColorTransparentZwriteMaterial { get; private set; }
  17. public Material unlitColorMaterial { get; private set; }
  18. public Material unlitTextureMaterial { get; private set; }
  19. public Texture2D blackTransparentTexture { get; private set; }
  20. public List<Rect> editorRectList { get; private set; }
  21. #region GUIStyle
  22. public GUIStyle guiStyleAlphaBox { get; private set; }
  23. public GUIStyle guiStyleToggleLeft { get; private set; }
  24. public GUIStyle guiStyleToggleRight { get; private set; }
  25. public GUIStyle guiStyleLabel { get; private set; }
  26. public GUIStyle guiStyleActiveButton { get; private set; }
  27. #endregion
  28. //Animation
  29. private float animationTime;
  30. public float AnimationPower { get { return 1f - ((Mathf.Cos((Time.realtimeSinceStartup - animationTime) * Mathf.PI * 2f) + 1f) / 2f); } }
  31. #region SelectionRect
  32. public struct SelectionRect
  33. {
  34. public void Reset()
  35. {
  36. Enable = false;
  37. start = IntVector2.zero;
  38. end = IntVector2.zero;
  39. }
  40. public void SetStart(IntVector2 add)
  41. {
  42. Enable = true;
  43. start = add;
  44. end = add;
  45. }
  46. public void SetEnd(IntVector2 add)
  47. {
  48. end = add;
  49. }
  50. public bool Enable { get; private set; }
  51. public int SizeX { get { return max.x - min.x + 1; } }
  52. public int SizeY { get { return max.y - min.y + 1; } }
  53. public IntVector2 min { get { return IntVector2.Min(start, end); } }
  54. public IntVector2 max { get { return IntVector2.Max(start, end); } }
  55. public Rect rect { get { return new Rect(min.x, min.y, max.x - min.x, max.y - min.y); } }
  56. public IntVector2 start;
  57. public IntVector2 end;
  58. }
  59. public SelectionRect selectionRect;
  60. #endregion
  61. //Tool
  62. public static Tool lastTool;
  63. //Fill
  64. public long fillVoxelDataLastTimeTicks;
  65. public DataTable3<List<IntVector3>> fillVoxelTable;
  66. public DataTable3<VoxelData.FaceAreaTable> fillVoxelFaceAreaTable;
  67. public DataTable3<Dictionary<int, List<IntVector3>>> fillVoxelFaceTable;
  68. public DataTable3<Dictionary<int, VoxelData.FaceAreaTable>> fillVoxelFaceFaceAreaTable;
  69. //Mesh
  70. public Mesh[] silhouetteMesh;
  71. public Mesh[] previewMesh;
  72. public Mesh[] cursorMesh;
  73. #region Icon
  74. public GameObject iconRoot;
  75. public RenderTexture iconTexture;
  76. public GameObject iconModel;
  77. public MeshRenderer iconModelRenderer;
  78. public GameObject iconCamera;
  79. public Camera iconCameraCamera;
  80. #endregion
  81. public VoxelEditorCommon(VoxelBase objectTarget, VoxelBaseCore objectCore)
  82. {
  83. this.objectTarget = objectTarget;
  84. this.objectCore = objectCore;
  85. vertexColorMaterial = new Material(Shader.Find("Voxel Importer/VertexColor"));
  86. vertexColorMaterial.hideFlags = HideFlags.DontSave;
  87. vertexColorTransparentMaterial = new Material(Shader.Find("Voxel Importer/VertexColor-Transparent"));
  88. vertexColorTransparentMaterial.hideFlags = HideFlags.DontSave;
  89. vertexColorTransparentZwriteMaterial = new Material(Shader.Find("Voxel Importer/VertexColor-Transparent-Zwrite"));
  90. vertexColorTransparentZwriteMaterial.hideFlags = HideFlags.DontSave;
  91. unlitColorMaterial = new Material(Shader.Find("Voxel Importer/Unlit/Color"));
  92. unlitColorMaterial.hideFlags = HideFlags.DontSave;
  93. unlitTextureMaterial = new Material(Shader.Find("Voxel Importer/Unlit/Transparent"));
  94. unlitTextureMaterial.hideFlags = HideFlags.DontSave;
  95. blackTransparentTexture = CreateColorTexture(new Color(0, 0, 0, 0.3f));
  96. editorRectList = new List<Rect>();
  97. animationTime = Time.realtimeSinceStartup;
  98. }
  99. public void ClearCache()
  100. {
  101. ClearSilhouetteMeshMesh();
  102. ClearPreviewMesh();
  103. ClearCursorMesh();
  104. fillVoxelTable = null;
  105. fillVoxelFaceAreaTable = null;
  106. fillVoxelFaceTable = null;
  107. fillVoxelFaceFaceAreaTable = null;
  108. }
  109. public Texture2D CreateColorTexture(Color color)
  110. {
  111. Texture2D tex = new Texture2D(4, 4);
  112. tex.hideFlags = HideFlags.DontSave;
  113. for (int x = 0; x < tex.width; x++)
  114. {
  115. for (int y = 0; y < tex.height; y++)
  116. {
  117. tex.SetPixel(x, y, color);
  118. }
  119. }
  120. tex.Apply();
  121. return tex;
  122. }
  123. public Texture2D LoadTexture2DAssetAtPath(string path)
  124. {
  125. var result = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
  126. if (result == null)
  127. {
  128. var fileName = Path.GetFileName(path);
  129. var guids = AssetDatabase.FindAssets("t:Texture2D");
  130. for (int i = 0; i < guids.Length; i++)
  131. {
  132. var assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
  133. if (Path.GetFileName(assetPath) == fileName)
  134. {
  135. if (assetPath.IndexOf("VoxelImporter") >= 0)
  136. {
  137. result = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
  138. break;
  139. }
  140. }
  141. }
  142. }
  143. return result;
  144. }
  145. public void ClearSilhouetteMeshMesh()
  146. {
  147. if (silhouetteMesh != null)
  148. {
  149. for (int i = 0; i < silhouetteMesh.Length; i++)
  150. {
  151. MonoBehaviour.DestroyImmediate(silhouetteMesh[i]);
  152. }
  153. silhouetteMesh = null;
  154. }
  155. }
  156. public void ClearPreviewMesh()
  157. {
  158. if (previewMesh != null)
  159. {
  160. for (int i = 0; i < previewMesh.Length; i++)
  161. {
  162. MonoBehaviour.DestroyImmediate(previewMesh[i]);
  163. }
  164. previewMesh = null;
  165. }
  166. }
  167. public void ClearCursorMesh()
  168. {
  169. if (cursorMesh != null)
  170. {
  171. for (int i = 0; i < cursorMesh.Length; i++)
  172. {
  173. MonoBehaviour.DestroyImmediate(cursorMesh[i]);
  174. }
  175. cursorMesh = null;
  176. }
  177. }
  178. public bool CheckMousePositionEditorRects()
  179. {
  180. for (int i = 0; i < editorRectList.Count; i++)
  181. {
  182. if (editorRectList[i].Contains(Event.current.mousePosition))
  183. {
  184. return false;
  185. }
  186. }
  187. return true;
  188. }
  189. public IntVector3? GetMousePositionVoxel()
  190. {
  191. IntVector3? result = null;
  192. if (objectCore.voxelData == null || objectTarget.voxelData.voxels == null)
  193. return result;
  194. if (!CheckMousePositionEditorRects())
  195. return result;
  196. Ray localRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
  197. {
  198. Matrix4x4 mat = objectTarget.transform.worldToLocalMatrix;
  199. localRay.direction = mat.MultiplyVector(localRay.direction);
  200. localRay.origin = mat.MultiplyPoint(localRay.origin);
  201. }
  202. {
  203. var boundsBase = objectCore.GetVoxelBounds(IntVector3.zero);
  204. float lengthMin = float.MaxValue;
  205. for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++)
  206. {
  207. if (objectTarget.voxelData.voxels[i].visible == 0)
  208. continue;
  209. Vector3 position = new Vector3(objectTarget.voxelData.voxels[i].x, objectTarget.voxelData.voxels[i].y, objectTarget.voxelData.voxels[i].z);
  210. Vector3 offset = Vector3.Scale(position, objectTarget.importScale);
  211. var bounds = boundsBase;
  212. bounds.center += offset;
  213. float length;
  214. if (bounds.IntersectRay(localRay, out length))
  215. {
  216. if (!result.HasValue || length < lengthMin)
  217. {
  218. result = objectTarget.voxelData.voxels[i].position;
  219. lengthMin = length;
  220. }
  221. }
  222. }
  223. }
  224. return result;
  225. }
  226. public bool GetMousePositionVoxelFace(out IntVector3 result, out VoxelBase.Face face)
  227. {
  228. result = IntVector3.zero;
  229. face = 0;
  230. if (objectCore.voxelData == null || objectTarget.voxelData.voxels == null)
  231. return false;
  232. if (!CheckMousePositionEditorRects())
  233. return false;
  234. Ray localRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
  235. {
  236. Matrix4x4 mat = objectTarget.transform.worldToLocalMatrix;
  237. localRay.direction = mat.MultiplyVector(localRay.direction);
  238. localRay.origin = mat.MultiplyPoint(localRay.origin);
  239. }
  240. {
  241. var boundsBase = objectCore.GetVoxelBounds(IntVector3.zero);
  242. float lengthMin = float.MaxValue;
  243. for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++)
  244. {
  245. if (objectTarget.voxelData.voxels[i].visible == 0)
  246. continue;
  247. Vector3 position = new Vector3(objectTarget.voxelData.voxels[i].x, objectTarget.voxelData.voxels[i].y, objectTarget.voxelData.voxels[i].z);
  248. Vector3 offset = Vector3.Scale(position, objectTarget.importScale);
  249. var bounds = boundsBase;
  250. bounds.center += offset;
  251. float length;
  252. if (bounds.IntersectRay(localRay, out length))
  253. {
  254. if (length < lengthMin)
  255. {
  256. result = objectTarget.voxelData.voxels[i].position;
  257. lengthMin = length;
  258. #region Face
  259. {
  260. const float Threshold = 0.001f;
  261. var posP = localRay.GetPoint(length);
  262. if (Mathf.Abs(bounds.min.x - posP.x) < Threshold)
  263. face = VoxelBase.Face.left;
  264. else if (Mathf.Abs(bounds.max.x - posP.x) < Threshold)
  265. face = VoxelBase.Face.right;
  266. else if (Mathf.Abs(bounds.min.y - posP.y) < Threshold)
  267. face = VoxelBase.Face.down;
  268. else if (Mathf.Abs(bounds.max.y - posP.y) < Threshold)
  269. face = VoxelBase.Face.up;
  270. else if (Mathf.Abs(bounds.min.z - posP.z) < Threshold)
  271. face = VoxelBase.Face.back;
  272. else if (Mathf.Abs(bounds.max.z - posP.z) < Threshold)
  273. face = VoxelBase.Face.forward;
  274. else
  275. Assert.IsTrue(false);
  276. }
  277. #endregion
  278. }
  279. }
  280. }
  281. }
  282. return face != 0;
  283. }
  284. private void CheckFillVoxelTableCheck()
  285. {
  286. if (fillVoxelDataLastTimeTicks != objectTarget.voxelData.updateVoxelTableLastTimeTicks)
  287. {
  288. fillVoxelTable = null;
  289. fillVoxelFaceAreaTable = null;
  290. fillVoxelFaceTable = null;
  291. fillVoxelFaceFaceAreaTable = null;
  292. fillVoxelDataLastTimeTicks = objectTarget.voxelData.updateVoxelTableLastTimeTicks;
  293. }
  294. }
  295. public List<IntVector3> GetFillVoxel(IntVector3 pos)
  296. {
  297. if (objectTarget.voxelData == null) return null;
  298. if (objectTarget.voxelData.VoxelTableContains(pos) < 0) return null;
  299. CheckFillVoxelTableCheck();
  300. if (fillVoxelTable == null)
  301. {
  302. fillVoxelTable = new DataTable3<List<IntVector3>>(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z);
  303. }
  304. if (!fillVoxelTable.Contains(pos))
  305. {
  306. List<IntVector3> searchList = new List<IntVector3>();
  307. int posPalette = 0;
  308. var doneTable = new FlagTable3(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z);
  309. {
  310. var index = objectTarget.voxelData.VoxelTableContains(pos);
  311. posPalette = objectTarget.voxelData.voxels[index].palette;
  312. searchList.Clear();
  313. searchList.Add(pos);
  314. doneTable.Set(pos, true);
  315. }
  316. var result = new List<IntVector3>();
  317. for (int j = 0; j < searchList.Count; j++)
  318. {
  319. var p = searchList[j];
  320. var index = objectTarget.voxelData.VoxelTableContains(p);
  321. if (index < 0) continue;
  322. if (objectTarget.voxelData.voxels[index].palette == posPalette)
  323. {
  324. result.Add(p);
  325. for (int x = p.x - 1; x <= p.x + 1; x++)
  326. {
  327. for (int y = p.y - 1; y <= p.y + 1; y++)
  328. {
  329. for (int z = p.z - 1; z <= p.z + 1; z++)
  330. {
  331. if (x >= 0 && y >= 0 && z >= 0 &&
  332. x < objectTarget.voxelData.voxelSize.x && y < objectTarget.voxelData.voxelSize.y && z < objectTarget.voxelData.voxelSize.z &&
  333. !doneTable.Get(x, y, z))
  334. {
  335. doneTable.Set(x, y, z, true);
  336. var indexTmp = objectTarget.voxelData.VoxelTableContains(x, y, z);
  337. if (indexTmp >= 0 && objectTarget.voxelData.voxels[indexTmp].palette == posPalette)
  338. searchList.Add(new IntVector3(x, y, z));
  339. }
  340. }
  341. }
  342. }
  343. }
  344. }
  345. for (int j = 0; j < result.Count; j++)
  346. {
  347. fillVoxelTable.Set(result[j], result);
  348. }
  349. }
  350. var fillVoxel = fillVoxelTable.Get(pos);
  351. return fillVoxel;
  352. }
  353. public VoxelData.FaceAreaTable GetFillVoxelFaceAreaTable(IntVector3 pos)
  354. {
  355. if (objectTarget.voxelData == null) return null;
  356. if (objectTarget.voxelData.VoxelTableContains(pos) < 0) return null;
  357. CheckFillVoxelTableCheck();
  358. if (fillVoxelFaceAreaTable == null)
  359. {
  360. fillVoxelFaceAreaTable = new DataTable3<VoxelData.FaceAreaTable>(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z);
  361. }
  362. if (!fillVoxelFaceAreaTable.Contains(pos))
  363. {
  364. var list = GetFillVoxel(pos);
  365. if (list == null) return null;
  366. var voxels = new List<VoxelData.Voxel>();
  367. for (int i = 0; i < list.Count; i++)
  368. {
  369. var index = objectTarget.voxelData.VoxelTableContains(list[i]);
  370. var voxel = objectTarget.voxelData.voxels[index];
  371. voxel.palette = -1;
  372. voxels.Add(voxel);
  373. }
  374. var faceAreaTable = objectCore.Edit_CreateMeshOnly_FaceArea(voxels, true);
  375. for (int i = 0; i < list.Count; i++)
  376. {
  377. fillVoxelFaceAreaTable.Set(list[i], faceAreaTable);
  378. }
  379. }
  380. var fillVoxelFaceArea = fillVoxelFaceAreaTable.Get(pos);
  381. return fillVoxelFaceArea;
  382. }
  383. public List<IntVector3> GetFillVoxelFace(IntVector3 pos, VoxelBase.Face face)
  384. {
  385. if (objectTarget.voxelData == null) return null;
  386. if (objectTarget.voxelData.VoxelTableContains(pos) < 0) return null;
  387. CheckFillVoxelTableCheck();
  388. if (fillVoxelFaceTable == null)
  389. {
  390. fillVoxelFaceTable = new DataTable3<Dictionary<int, List<IntVector3>>>(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z);
  391. }
  392. if (!fillVoxelFaceTable.Contains(pos) ||
  393. !fillVoxelFaceTable.Get(pos).ContainsKey((int)face))
  394. {
  395. List<IntVector3> searchList = new List<IntVector3>();
  396. var doneTable = new FlagTable3(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z);
  397. {
  398. searchList.Clear();
  399. searchList.Add(pos);
  400. doneTable.Set(pos, true);
  401. }
  402. var result = new List<IntVector3>();
  403. for (int j = 0; j < searchList.Count; j++)
  404. {
  405. var p = searchList[j];
  406. var index = objectTarget.voxelData.VoxelTableContains(p);
  407. if (index < 0) continue;
  408. if ((objectTarget.voxelData.voxels[index].visible & face) != 0)
  409. {
  410. result.Add(p);
  411. int xOffset = (face & (VoxelBase.Face.up | VoxelBase.Face.down | VoxelBase.Face.forward | VoxelBase.Face.back)) != 0 ? 1 : 0;
  412. int yOffset = (face & (VoxelBase.Face.right | VoxelBase.Face.left | VoxelBase.Face.forward | VoxelBase.Face.back)) != 0 ? 1 : 0;
  413. int zOffset = (face & (VoxelBase.Face.right | VoxelBase.Face.left | VoxelBase.Face.up | VoxelBase.Face.down)) != 0 ? 1 : 0;
  414. for (int x = p.x - xOffset; x <= p.x + xOffset; x++)
  415. {
  416. for (int y = p.y - yOffset; y <= p.y + yOffset; y++)
  417. {
  418. for (int z = p.z - zOffset; z <= p.z + zOffset; z++)
  419. {
  420. if (x >= 0 && y >= 0 && z >= 0 &&
  421. x < objectTarget.voxelData.voxelSize.x && y < objectTarget.voxelData.voxelSize.y && z < objectTarget.voxelData.voxelSize.z &&
  422. !doneTable.Get(x, y, z))
  423. {
  424. doneTable.Set(x, y, z, true);
  425. var indexTmp = objectTarget.voxelData.VoxelTableContains(x, y, z);
  426. if (indexTmp >= 0)
  427. searchList.Add(new IntVector3(x, y, z));
  428. }
  429. }
  430. }
  431. }
  432. }
  433. }
  434. Dictionary<int, List<IntVector3>> data;
  435. if (fillVoxelFaceTable.Contains(pos))
  436. data = fillVoxelFaceTable.Get(pos);
  437. else
  438. data = new Dictionary<int, List<IntVector3>>();
  439. data[(int)face] = result;
  440. fillVoxelFaceTable.Set(pos, data);
  441. for (int j = 0; j < result.Count; j++)
  442. {
  443. if (fillVoxelFaceTable.Contains(result[j]))
  444. data = fillVoxelFaceTable.Get(result[j]);
  445. else
  446. data = new Dictionary<int, List<IntVector3>>();
  447. data[(int)face] = result;
  448. fillVoxelFaceTable.Set(result[j], data);
  449. }
  450. }
  451. var fillVoxel = fillVoxelFaceTable.Get(pos)[(int)face];
  452. return fillVoxel;
  453. }
  454. public VoxelData.FaceAreaTable GetFillVoxelFaceFaceAreaTable(IntVector3 pos, VoxelBase.Face face)
  455. {
  456. if (objectTarget.voxelData == null) return null;
  457. if (objectTarget.voxelData.VoxelTableContains(pos) < 0) return null;
  458. CheckFillVoxelTableCheck();
  459. if (fillVoxelFaceFaceAreaTable == null)
  460. {
  461. fillVoxelFaceFaceAreaTable = new DataTable3<Dictionary<int, VoxelData.FaceAreaTable>>(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z);
  462. }
  463. if (!fillVoxelFaceFaceAreaTable.Contains(pos) ||
  464. !fillVoxelFaceFaceAreaTable.Get(pos).ContainsKey((int)face))
  465. {
  466. var list = GetFillVoxelFace(pos, face);
  467. if (list == null) return null;
  468. var voxels = new List<VoxelData.Voxel>();
  469. for (int i = 0; i < list.Count; i++)
  470. {
  471. var index = objectTarget.voxelData.VoxelTableContains(list[i]);
  472. var voxel = objectTarget.voxelData.voxels[index];
  473. voxel.palette = -1;
  474. voxel.visible = face;
  475. voxels.Add(voxel);
  476. }
  477. var faceAreaTable = objectCore.Edit_CreateMeshOnly_FaceArea(voxels, true);
  478. Dictionary<int, VoxelData.FaceAreaTable> data;
  479. if (fillVoxelFaceFaceAreaTable.Contains(pos))
  480. data = fillVoxelFaceFaceAreaTable.Get(pos);
  481. else
  482. data = new Dictionary<int, VoxelData.FaceAreaTable>();
  483. data[(int)face] = faceAreaTable;
  484. fillVoxelFaceFaceAreaTable.Set(pos, data);
  485. for (int i = 0; i < list.Count; i++)
  486. {
  487. if (fillVoxelFaceFaceAreaTable.Contains(list[i]))
  488. data = fillVoxelFaceFaceAreaTable.Get(list[i]);
  489. else
  490. data = new Dictionary<int, VoxelData.FaceAreaTable>();
  491. data[(int)face] = faceAreaTable;
  492. fillVoxelFaceFaceAreaTable.Set(list[i], data);
  493. }
  494. }
  495. var fillVoxelFaceArea = fillVoxelFaceFaceAreaTable.Get(pos)[(int)face];
  496. return fillVoxelFaceArea;
  497. }
  498. public struct VertexPower
  499. {
  500. public IntVector3 position;
  501. public float power;
  502. }
  503. public List<VertexPower> GetMousePositionVertex(float radius)
  504. {
  505. List<VertexPower> result = new List<VertexPower>();
  506. if (objectTarget.voxelData == null || objectTarget.voxelData.voxels == null)
  507. return result;
  508. if (!CheckMousePositionEditorRects())
  509. return result;
  510. var boundsList = new List<Bounds>();
  511. var vertexList = new List<VertexPower>();
  512. {
  513. Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
  514. ray.origin = objectTarget.transform.worldToLocalMatrix.MultiplyPoint3x4(ray.origin);
  515. ray.direction = objectTarget.transform.worldToLocalMatrix.MultiplyVector(ray.direction);
  516. bool[,,] doneTable = new bool[objectTarget.voxelData.voxelSize.x + 1, objectTarget.voxelData.voxelSize.y + 1, objectTarget.voxelData.voxelSize.z + 1];
  517. {
  518. Ray rayRadius = HandleUtility.GUIPointToWorldRay(new Vector2(Event.current.mousePosition.x + radius, Event.current.mousePosition.y));
  519. rayRadius.origin = objectTarget.transform.worldToLocalMatrix.MultiplyPoint3x4(rayRadius.origin);
  520. rayRadius.direction = objectTarget.transform.worldToLocalMatrix.MultiplyVector(rayRadius.direction);
  521. Func<IntVector3, bool> AddVertex = (pos) =>
  522. {
  523. if (doneTable[pos.x, pos.y, pos.z])
  524. return true;
  525. doneTable[pos.x, pos.y, pos.z] = true;
  526. var posL = objectCore.GetVoxelRatePosition(pos, Vector3.zero);
  527. var posP = ray.origin + ray.direction * Vector3.Dot(posL - ray.origin, ray.direction);
  528. var posR = rayRadius.origin + rayRadius.direction * (Vector3.Dot(posP - rayRadius.origin, rayRadius.direction));
  529. var distanceL = (posL - posP).sqrMagnitude;
  530. var distanceR = (posR - posP).sqrMagnitude;
  531. if (distanceL < distanceR)
  532. {
  533. vertexList.Add(new VertexPower() { position = pos, power = distanceL / distanceR });
  534. return true;
  535. }
  536. return false;
  537. };
  538. for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++)
  539. {
  540. if (objectTarget.voxelData.voxels[i].visible == 0) continue;
  541. var pos = objectTarget.voxelData.voxels[i].position;
  542. bool enable = false;
  543. if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.left | VoxelBase.Face.down | VoxelBase.Face.back)) != 0)
  544. if (AddVertex(new IntVector3(pos.x, pos.y, pos.z))) enable = true;
  545. if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.right | VoxelBase.Face.down | VoxelBase.Face.back)) != 0)
  546. if (AddVertex(new IntVector3(pos.x + 1, pos.y, pos.z))) enable = true;
  547. if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.left | VoxelBase.Face.up | VoxelBase.Face.back)) != 0)
  548. if (AddVertex(new IntVector3(pos.x, pos.y + 1, pos.z))) enable = true;
  549. if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.left | VoxelBase.Face.down | VoxelBase.Face.forward)) != 0)
  550. if (AddVertex(new IntVector3(pos.x, pos.y, pos.z + 1))) enable = true;
  551. if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.right | VoxelBase.Face.up | VoxelBase.Face.back)) != 0)
  552. if (AddVertex(new IntVector3(pos.x + 1, pos.y + 1, pos.z))) enable = true;
  553. if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.right | VoxelBase.Face.down | VoxelBase.Face.forward)) != 0)
  554. if (AddVertex(new IntVector3(pos.x + 1, pos.y, pos.z + 1))) enable = true;
  555. if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.left | VoxelBase.Face.up | VoxelBase.Face.forward)) != 0)
  556. if (AddVertex(new IntVector3(pos.x, pos.y + 1, pos.z + 1))) enable = true;
  557. if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.right | VoxelBase.Face.up | VoxelBase.Face.forward)) != 0)
  558. if (AddVertex(new IntVector3(pos.x + 1, pos.y + 1, pos.z + 1))) enable = true;
  559. if (enable)
  560. {
  561. if ((ray.direction.x < 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.right) != 0)) ||
  562. (ray.direction.x > 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.left) != 0)) ||
  563. (ray.direction.y < 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.up) != 0)) ||
  564. (ray.direction.y > 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.down) != 0)) ||
  565. (ray.direction.z < 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.forward) != 0)) ||
  566. (ray.direction.z > 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.back) != 0)))
  567. {
  568. boundsList.Add(objectCore.GetVoxelBounds(pos));
  569. }
  570. }
  571. }
  572. }
  573. }
  574. {
  575. for (int i = 0; i < vertexList.Count; i++)
  576. {
  577. var pos = objectCore.GetVoxelRatePosition(vertexList[i].position, Vector3.zero);
  578. Ray ray = HandleUtility.GUIPointToWorldRay(HandleUtility.WorldToGUIPoint(objectTarget.transform.localToWorldMatrix.MultiplyPoint3x4(pos)));
  579. ray.origin = objectTarget.transform.worldToLocalMatrix.MultiplyPoint3x4(ray.origin);
  580. ray.direction = objectTarget.transform.worldToLocalMatrix.MultiplyVector(ray.direction);
  581. float length = (pos - ray.origin).magnitude - 0.1f;
  582. bool enable = true;
  583. for (int j = 0; j < boundsList.Count; j++)
  584. {
  585. float distance;
  586. if (boundsList[j].IntersectRay(ray, out distance))
  587. {
  588. if (distance < length)
  589. {
  590. enable = false;
  591. break;
  592. }
  593. }
  594. }
  595. if (enable)
  596. {
  597. result.Add(vertexList[i]);
  598. }
  599. }
  600. }
  601. return result;
  602. }
  603. public List<IntVector3> GetSelectionRectVoxel()
  604. {
  605. List<IntVector3> result = new List<IntVector3>();
  606. if (selectionRect.Enable &&
  607. objectTarget.voxelData != null && objectTarget.voxelData.voxels != null)
  608. {
  609. var localToWorldMatrix = objectTarget.transform.localToWorldMatrix;
  610. for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++)
  611. {
  612. var local = objectCore.GetVoxelCenterPosition(objectTarget.voxelData.voxels[i].position);
  613. var world = localToWorldMatrix.MultiplyPoint(local);
  614. var screen = HandleUtility.WorldToGUIPoint(world);
  615. if (selectionRect.rect.Contains(screen))
  616. {
  617. result.Add(objectTarget.voxelData.voxels[i].position);
  618. }
  619. }
  620. }
  621. return result;
  622. }
  623. public Dictionary<IntVector3, VoxelBase.Face> GetSelectionRectVoxelFace()
  624. {
  625. Dictionary<IntVector3, VoxelBase.Face> result = new Dictionary<IntVector3, VoxelBase.Face>();
  626. if (selectionRect.Enable &&
  627. objectTarget.voxelData != null && objectTarget.voxelData.vertexList != null)
  628. {
  629. var localToWorldMatrix = objectTarget.transform.localToWorldMatrix;
  630. FlagTable3 containsTable = new FlagTable3(objectTarget.voxelData.voxelSize.x + 1, objectTarget.voxelData.voxelSize.y + 1, objectTarget.voxelData.voxelSize.z + 1);
  631. for (int i = 0; i < objectTarget.voxelData.vertexList.Count; i++)
  632. {
  633. var local = objectCore.GetVoxelRatePosition(objectTarget.voxelData.vertexList[i], Vector3.zero);
  634. var world = localToWorldMatrix.MultiplyPoint3x4(local);
  635. var screen = HandleUtility.WorldToGUIPoint(world);
  636. if (selectionRect.rect.Contains(screen))
  637. containsTable.Set(objectTarget.voxelData.vertexList[i], true);
  638. }
  639. containsTable.AllAction((x, y, z) =>
  640. {
  641. Action<int, int, int, VoxelBase.Face> AddFace = (xx, yy, zz, face) =>
  642. {
  643. var pos = new IntVector3(xx, yy, zz);
  644. var index = objectTarget.voxelData.VoxelTableContains(pos);
  645. if (index < 0) return;
  646. if ((objectTarget.voxelData.voxels[index].visible & face) == 0) return;
  647. VoxelBase.Face combineFace;
  648. if (!result.TryGetValue(pos, out combineFace))
  649. {
  650. result.Add(pos, face);
  651. }
  652. else
  653. {
  654. combineFace |= face;
  655. result[pos] = combineFace;
  656. }
  657. };
  658. #region Left
  659. if (containsTable.Get(x, y + 1, z) &&
  660. containsTable.Get(x, y, z + 1) &&
  661. containsTable.Get(x, y + 1, z + 1))
  662. {
  663. AddFace(x, y, z, VoxelBase.Face.left);
  664. AddFace(x - 1, y, z, VoxelBase.Face.right);
  665. }
  666. #endregion
  667. #region Down
  668. if (containsTable.Get(x + 1, y, z) &&
  669. containsTable.Get(x, y, z + 1) &&
  670. containsTable.Get(x + 1, y, z + 1))
  671. {
  672. AddFace(x, y, z, VoxelBase.Face.down);
  673. AddFace(x, y - 1, z, VoxelBase.Face.up);
  674. }
  675. #endregion
  676. #region Back
  677. if (containsTable.Get(x + 1, y, z) &&
  678. containsTable.Get(x, y + 1, z) &&
  679. containsTable.Get(x + 1, y + 1, z))
  680. {
  681. AddFace(x, y, z, VoxelBase.Face.back);
  682. AddFace(x, y, z - 1, VoxelBase.Face.forward);
  683. }
  684. #endregion
  685. });
  686. }
  687. return result;
  688. }
  689. public List<IntVector3> GetSelectionRectVertex()
  690. {
  691. List<IntVector3> result = new List<IntVector3>();
  692. if (selectionRect.Enable &&
  693. objectTarget.voxelData != null && objectTarget.voxelData.vertexList != null)
  694. {
  695. var localToWorldMatrix = objectTarget.transform.localToWorldMatrix;
  696. for (int i = 0; i < objectTarget.voxelData.vertexList.Count; i++)
  697. {
  698. var local = objectCore.GetVoxelRatePosition(objectTarget.voxelData.vertexList[i], Vector3.zero);
  699. var world = localToWorldMatrix.MultiplyPoint3x4(local);
  700. var screen = HandleUtility.WorldToGUIPoint(world);
  701. if (selectionRect.rect.Contains(screen))
  702. {
  703. result.Add(objectTarget.voxelData.vertexList[i]);
  704. }
  705. }
  706. }
  707. return result;
  708. }
  709. public Rect ResizeSceneViewRect(Rect rect)
  710. {
  711. var sv = SceneView.currentDrawingSceneView;
  712. if (rect.x + rect.width >= sv.position.width)
  713. rect.x -= (rect.x + rect.width) - sv.position.width;
  714. if (rect.y + rect.height >= sv.position.height)
  715. rect.y -= (rect.y + rect.height) - sv.position.height;
  716. if (rect.x < 0)
  717. rect.x -= rect.x;
  718. if (rect.y < 0)
  719. rect.y -= rect.y;
  720. return rect;
  721. }
  722. public void GUIStyleReady()
  723. {
  724. if (guiStyleAlphaBox == null)
  725. guiStyleAlphaBox = new GUIStyle(GUI.skin.box);
  726. guiStyleAlphaBox.normal.textColor = Color.white;
  727. guiStyleAlphaBox.fontStyle = FontStyle.Bold;
  728. guiStyleAlphaBox.alignment = TextAnchor.UpperCenter;
  729. guiStyleAlphaBox.normal.background = blackTransparentTexture;
  730. if (guiStyleToggleLeft == null)
  731. guiStyleToggleLeft = new GUIStyle(GUI.skin.toggle);
  732. guiStyleToggleLeft.normal.textColor = Color.white;
  733. guiStyleToggleLeft.onNormal.textColor = Color.white;
  734. guiStyleToggleLeft.hover.textColor = Color.white;
  735. guiStyleToggleLeft.onHover.textColor = Color.white;
  736. guiStyleToggleLeft.focused.textColor = Color.white;
  737. guiStyleToggleLeft.onFocused.textColor = Color.white;
  738. guiStyleToggleLeft.active.textColor = Color.white;
  739. guiStyleToggleLeft.onActive.textColor = Color.white;
  740. if (guiStyleToggleRight == null)
  741. guiStyleToggleRight = new GUIStyle(GUI.skin.toggle);
  742. guiStyleToggleRight.normal.textColor = Color.white;
  743. guiStyleToggleRight.onNormal.textColor = Color.white;
  744. guiStyleToggleRight.hover.textColor = Color.white;
  745. guiStyleToggleRight.onHover.textColor = Color.white;
  746. guiStyleToggleRight.focused.textColor = Color.white;
  747. guiStyleToggleRight.onFocused.textColor = Color.white;
  748. guiStyleToggleRight.active.textColor = Color.white;
  749. guiStyleToggleRight.onActive.textColor = Color.white;
  750. guiStyleToggleRight.padding.left = 2;
  751. guiStyleToggleRight.overflow.left = -149;
  752. if (guiStyleLabel == null)
  753. guiStyleLabel = new GUIStyle(GUI.skin.label);
  754. guiStyleLabel.normal.textColor = Color.white;
  755. if (guiStyleActiveButton == null)
  756. guiStyleActiveButton = new GUIStyle(GUI.skin.button);
  757. guiStyleActiveButton.normal = guiStyleActiveButton.active;
  758. }
  759. #region Icon
  760. public void InitializeIcon()
  761. {
  762. const string IconRootObjectName = "Tmp#VoxelImporterIcon";
  763. {
  764. var objects = Resources.FindObjectsOfTypeAll<GameObject>();
  765. for (int i = 0; i < objects.Length; i++)
  766. {
  767. if (objects[i].name == IconRootObjectName)
  768. iconRoot = objects[i];
  769. }
  770. }
  771. if (iconRoot == null)
  772. {
  773. #if PreviewObjectHide
  774. iconRoot = UnityEditor.EditorUtility.CreateGameObjectWithHideFlags(IconRootObjectName, HideFlags.HideAndDontSave);
  775. #else
  776. iconRoot = new GameObject(IconRootObjectName);
  777. iconRoot.hideFlags = HideFlags.DontSave;
  778. #endif
  779. }
  780. iconRoot.SetActive(false);
  781. int blankLayer;
  782. for (blankLayer = 31; blankLayer > 0; blankLayer--)
  783. {
  784. if (string.IsNullOrEmpty(LayerMask.LayerToName(blankLayer)))
  785. break;
  786. }
  787. if (blankLayer < 0)
  788. blankLayer = 31;
  789. iconRoot.layer = blankLayer;
  790. iconTexture = new RenderTexture(128, 128, 16, RenderTextureFormat.ARGB32);
  791. iconTexture.hideFlags = HideFlags.DontSave;
  792. iconTexture.Create();
  793. CreateIconObject();
  794. }
  795. public void CreateIconObject(Transform transform = null, Mesh mesh = null, Material[] materials = null)
  796. {
  797. if (iconRoot == null) return;
  798. if (transform != null)
  799. {
  800. iconRoot.transform.position = transform.position;
  801. iconRoot.transform.rotation = transform.rotation;
  802. iconRoot.transform.localScale = Vector3.one;
  803. }
  804. else
  805. {
  806. iconRoot.transform.position = Vector3.zero;
  807. iconRoot.transform.rotation = Quaternion.identity;
  808. iconRoot.transform.localScale = Vector3.one;
  809. }
  810. {
  811. const string IconModelName = "IconModel";
  812. var iconModelTransform = iconRoot.transform.Find(IconModelName);
  813. if (iconModelTransform != null)
  814. iconModel = iconModelTransform.gameObject;
  815. if (iconModel == null)
  816. {
  817. #if PreviewObjectHide
  818. iconModel = UnityEditor.EditorUtility.CreateGameObjectWithHideFlags(IconModelName, HideFlags.HideAndDontSave);
  819. #else
  820. iconModel = new GameObject(IconModelName);
  821. iconModel.hideFlags = HideFlags.DontSave;
  822. #endif
  823. }
  824. iconModel.transform.SetParent(iconRoot.transform);
  825. iconModel.transform.localPosition = new Vector3(0f, 0f, 0f);
  826. iconModel.layer = iconRoot.layer;
  827. MeshFilter meshFilter = iconModel.GetComponent<MeshFilter>();
  828. if (meshFilter == null)
  829. meshFilter = iconModel.AddComponent<MeshFilter>();
  830. meshFilter.sharedMesh = mesh;
  831. iconModelRenderer = iconModel.GetComponent<MeshRenderer>();
  832. if (iconModelRenderer == null)
  833. iconModelRenderer = iconModel.AddComponent<MeshRenderer>();
  834. if (materials != null)
  835. iconModelRenderer.sharedMaterials = materials;
  836. }
  837. {
  838. const string IconCameraName = "IconCamera";
  839. var iconCameraTransform = iconRoot.transform.Find(IconCameraName);
  840. if (iconCameraTransform != null)
  841. iconCamera = iconCameraTransform.gameObject;
  842. if (iconCamera == null)
  843. {
  844. #if PreviewObjectHide
  845. iconCamera = UnityEditor.EditorUtility.CreateGameObjectWithHideFlags(IconCameraName, HideFlags.HideAndDontSave);
  846. #else
  847. iconCamera = new GameObject(IconCameraName);
  848. iconCamera.hideFlags = HideFlags.DontSave;
  849. #endif
  850. iconCameraCamera = iconCamera.AddComponent<Camera>();
  851. }
  852. else
  853. {
  854. iconCameraCamera = iconCamera.GetComponent<Camera>();
  855. }
  856. iconCamera.transform.SetParent(iconRoot.transform);
  857. iconCamera.layer = iconRoot.layer;
  858. if (mesh != null)
  859. {
  860. var rot = Quaternion.AngleAxis(180f, Vector3.up);
  861. iconCamera.transform.localRotation = rot;
  862. iconCamera.transform.localPosition = mesh.bounds.center + iconCamera.transform.worldToLocalMatrix.MultiplyVector(iconCamera.transform.forward) * mesh.bounds.size.z * 5f;
  863. }
  864. else
  865. {
  866. iconCamera.transform.localPosition = Vector3.zero;
  867. iconCamera.transform.localRotation = Quaternion.identity;
  868. }
  869. iconCameraCamera.orthographic = true;
  870. if (mesh != null)
  871. {
  872. iconCameraCamera.orthographicSize = Mathf.Max(mesh.bounds.size.x, Mathf.Max(mesh.bounds.size.y, mesh.bounds.size.z)) * 0.6f;
  873. iconCameraCamera.farClipPlane = Mathf.Max(mesh.bounds.size.x, Mathf.Max(mesh.bounds.size.y, mesh.bounds.size.z)) * 5f;
  874. }
  875. iconCameraCamera.clearFlags = CameraClearFlags.Color;
  876. iconCameraCamera.backgroundColor = new Color(0f, 0f, 0f, 0f);
  877. iconCameraCamera.cullingMask = 1 << iconRoot.layer;
  878. iconCameraCamera.targetTexture = iconTexture;
  879. }
  880. }
  881. public bool IsReadyIcon()
  882. {
  883. return iconRoot != null && iconModelRenderer != null && iconModelRenderer.sharedMaterials != null;
  884. }
  885. public Texture2D IconObjectRender()
  886. {
  887. if (iconRoot == null) return null;
  888. Texture2D tex = null;
  889. iconRoot.SetActive(true);
  890. iconCameraCamera.Render();
  891. {
  892. RenderTexture save = RenderTexture.active;
  893. RenderTexture.active = iconTexture;
  894. tex = new Texture2D(iconTexture.width, iconTexture.height, TextureFormat.ARGB32, iconTexture.useMipMap);
  895. tex.hideFlags = HideFlags.DontSave;
  896. tex.ReadPixels(new Rect(0, 0, iconTexture.width, iconTexture.height), 0, 0);
  897. tex.Apply();
  898. RenderTexture.active = save;
  899. }
  900. iconRoot.SetActive(false);
  901. return tex;
  902. }
  903. #endregion
  904. }
  905. }