WallManager.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /*
  2. Copyright(c) 2021 Omar Duarte
  3. Unauthorized copying of this file, via any medium is strictly prohibited.
  4. Writen by Omar Duarte, 2021.
  5. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  7. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  8. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  9. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  10. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  11. THE SOFTWARE.
  12. */
  13. using UnityEngine;
  14. using System.Linq;
  15. namespace PluginMaster
  16. {
  17. #region DATA & SETTINGS
  18. [System.Serializable]
  19. public struct WallCellSize
  20. {
  21. [SerializeField] private string _name;
  22. [SerializeField] private float _size;
  23. public WallCellSize(string name, float size)
  24. {
  25. _name = name;
  26. _size = size;
  27. }
  28. public string name { get => _name; set => _name = value; }
  29. public float size { get => _size; set => _size = value; }
  30. }
  31. [System.Serializable]
  32. public class WallSettings : ModularToolBase, ISerializationCallbackReceiver
  33. {
  34. [SerializeField] private bool _autoCalculateAxes = true;
  35. public bool autoCalculateAxes
  36. {
  37. get => _autoCalculateAxes;
  38. set
  39. {
  40. if (_autoCalculateAxes == value) return;
  41. _autoCalculateAxes = value;
  42. OnDataChanged();
  43. }
  44. }
  45. public override void Copy(IToolSettings other)
  46. {
  47. base.Copy(other);
  48. var otherWallSettings = other as WallSettings;
  49. if (otherWallSettings == null) return;
  50. _autoCalculateAxes = otherWallSettings.autoCalculateAxes;
  51. }
  52. #region SIZES
  53. [SerializeField] private WallCellSize[] _sizes = null;
  54. private const string DEFAULT_SIZE_NAME = "Default";
  55. [SerializeField] private string _selectedSizeName = DEFAULT_SIZE_NAME;
  56. private System.Collections.Generic.Dictionary<string, float> _sizesDictionary
  57. = new System.Collections.Generic.Dictionary<string, float>() { { DEFAULT_SIZE_NAME, 1 } };
  58. public string selectedSizeName
  59. {
  60. get => _selectedSizeName;
  61. set
  62. {
  63. if (_selectedSizeName == value) return;
  64. _selectedSizeName = value;
  65. var newSize = moduleSize;
  66. AxesUtils.SetAxisValue(ref newSize, WallManager.wallLenghtAxis, _sizesDictionary[selectedSizeName]);
  67. moduleSize = newSize;
  68. DataChanged();
  69. }
  70. }
  71. public void SetSize(float value)
  72. {
  73. AxesUtils.SetAxisValue(ref _moduleSize, WallManager.wallLenghtAxis, value);
  74. DataChanged();
  75. }
  76. public void SaveSize(string name)
  77. {
  78. var size = AxesUtils.GetAxisValue(moduleSize, WallManager.wallLenghtAxis);
  79. if (_sizesDictionary.ContainsKey(name))
  80. _sizesDictionary[name] = size;
  81. else _sizesDictionary.Add(name, size);
  82. _selectedSizeName = name;
  83. DataChanged();
  84. }
  85. public string[] GetSizesNames() => _sizesDictionary.Keys.ToArray();
  86. public void DeleteSelectedSize()
  87. {
  88. _sizesDictionary.Remove(_selectedSizeName);
  89. selectedSizeName = DEFAULT_SIZE_NAME;
  90. }
  91. public int GetIndexOfSize(string name) => _sizesDictionary.Keys.Select((key, index) => new { key, index })
  92. .FirstOrDefault(pair => pair.key == name)?.index ?? -1;
  93. public int GetIndexOfSelectedSize() => GetIndexOfSize(selectedSizeName);
  94. public string GetSizeAt(int index) => _sizesDictionary.Keys.ElementAt(index);
  95. public void SelectSize(int index) => selectedSizeName = GetSizeAt(index);
  96. public void ResetSize()
  97. {
  98. var newSize = moduleSize;
  99. AxesUtils.SetAxisValue(ref newSize, WallManager.wallLenghtAxis, _sizesDictionary[selectedSizeName]);
  100. moduleSize = newSize;
  101. DataChanged();
  102. }
  103. #endregion
  104. public void OnBeforeSerialize()
  105. {
  106. _sizes = _sizesDictionary.Select(pair => new WallCellSize(pair.Key, pair.Value)).ToArray();
  107. }
  108. public void OnAfterDeserialize()
  109. {
  110. if (_sizes == null || _sizes.Length == 0) return;
  111. _sizesDictionary = _sizes.ToDictionary(origin => origin.name, origin => origin.size);
  112. }
  113. }
  114. [System.Serializable]
  115. public class WallManager : ToolManagerBase<WallSettings>
  116. {
  117. public enum ToolState
  118. {
  119. FIRST_WALL_PREVIEW,
  120. EDITING
  121. }
  122. public static ToolState state { get; set; } = ToolState.FIRST_WALL_PREVIEW;
  123. public static float wallThickness { get; set; } = 0.1f;
  124. public static float wallLength { get; set; } = 1f;
  125. public static AxesUtils.Axis wallLenghtAxis { get; set; } = AxesUtils.Axis.X;
  126. public static Vector3 startPoint { get; set; } = Vector3.zero;
  127. public static Vector3 endPoint { get; set; } = Vector3.zero;
  128. public static bool halfTurn { get; set; } = false;
  129. }
  130. #endregion
  131. public static partial class PWBIO
  132. {
  133. #region HANDLERS
  134. private static void WallInitializeOnLoad()
  135. {
  136. WallManager.settings.OnDataChanged += OnWallSettingsChanged;
  137. BrushSettings.OnBrushSettingsChanged += UpdateWallSettingsOnBrushChanged;
  138. SnapManager.settings.OnGridOriginChange += OnWallGridOriginChange;
  139. }
  140. private static void SetSnapStepToWallCellSize()
  141. {
  142. var cellSize = WallManager.settings.moduleSize + WallManager.settings.spacing;
  143. if (WallManager.settings.autoCalculateAxes)
  144. {
  145. WallManager.settings.SetUpwardAxis(AxesUtils.SignedAxis.UP);
  146. if (cellSize.x >= cellSize.z)
  147. {
  148. WallManager.wallLenghtAxis = AxesUtils.Axis.X;
  149. WallManager.settings.SetForwardAxis(AxesUtils.SignedAxis.FORWARD);
  150. }
  151. else
  152. {
  153. WallManager.wallLenghtAxis = AxesUtils.Axis.Z;
  154. WallManager.settings.SetForwardAxis(AxesUtils.SignedAxis.RIGHT);
  155. }
  156. WallManager.wallThickness = Mathf.Min(cellSize.x, cellSize.z);
  157. WallManager.wallLength = Mathf.Max(cellSize.x, cellSize.z);
  158. }
  159. else
  160. {
  161. WallManager.wallLenghtAxis = AxesUtils.Axis.X;
  162. WallManager.wallThickness = cellSize.z;
  163. WallManager.wallLength = cellSize.x;
  164. }
  165. cellSize.x = cellSize.z = WallManager.wallLength;
  166. SnapManager.settings.step = cellSize;
  167. UnityEditor.SceneView.RepaintAll();
  168. }
  169. private static void OnWallSettingsChanged()
  170. {
  171. repaint = true;
  172. BrushstrokeManager.UpdateWallBrushstroke(WallManager.wallLenghtAxis, cellsCount: 1,
  173. setNextIdx: false, deleteMode: false);
  174. SetSnapStepToWallCellSize();
  175. }
  176. public static void UpdateWallSettingsOnBrushChanged()
  177. {
  178. if (ToolManager.tool != ToolManager.PaintTool.WALL) return;
  179. WallManager.halfTurn = false;
  180. WallManager.settings.UpdateCellSize();
  181. SetSnapStepToWallCellSize();
  182. WallManager.state = WallManager.ToolState.FIRST_WALL_PREVIEW;
  183. }
  184. public static void OnWallGridOriginChange()
  185. {
  186. if (ToolManager.tool != ToolManager.PaintTool.WALL) return;
  187. repaint = true;
  188. BrushstrokeManager.UpdateWallBrushstroke(WallManager.wallLenghtAxis, cellsCount: 1,
  189. setNextIdx: false, deleteMode: false);
  190. SetSnapStepToWallCellSize();
  191. }
  192. #endregion
  193. public static void OnWallEnabled()
  194. {
  195. SnapManager.settings.radialGridEnabled = false;
  196. SnapManager.settings.gridOnY = true;
  197. SnapManager.settings.visibleGrid = true;
  198. SnapManager.settings.lockedGrid = true;
  199. SnapManager.settings.snappingOnX = true;
  200. SnapManager.settings.snappingOnZ = true;
  201. SnapManager.settings.snappingEnabled = true;
  202. UpdateWallSettingsOnBrushChanged();
  203. SnapManager.settings.DataChanged(repaint: true);
  204. WallManager.state = WallManager.ToolState.FIRST_WALL_PREVIEW;
  205. WallManager.halfTurn = false;
  206. }
  207. private static Vector3 _wallEnd = Vector3.zero;
  208. private static void WallToolDuringSceneGUI(UnityEditor.SceneView sceneView)
  209. {
  210. if (PaletteManager.selectedBrush == null) return;
  211. var mousePos2D = Event.current.mousePosition;
  212. var mouseRay = UnityEditor.HandleUtility.GUIPointToWorldRay(mousePos2D);
  213. var mousePos3D = Vector3.zero;
  214. var localMousePos3D = Vector3.zero;
  215. AxesUtils.Axis axis;
  216. int cellsCount = 1;
  217. bool rotateHalfTurn;
  218. if (GridRaycast(mouseRay, out RaycastHit gridHit))
  219. {
  220. mousePos3D = WallManager.state == WallManager.ToolState.FIRST_WALL_PREVIEW
  221. ? SnapWallPosition(gridHit.point, out axis, out rotateHalfTurn, out localMousePos3D)
  222. : SnapWallPosition(WallManager.startPoint, gridHit.point,
  223. out axis, out cellsCount, out rotateHalfTurn, out localMousePos3D);
  224. }
  225. else return;
  226. if (WallInput(mousePos3D, axis, cellsCount)) return;
  227. switch (WallManager.state)
  228. {
  229. case WallManager.ToolState.FIRST_WALL_PREVIEW:
  230. if (_modularDeleteMode) PreviewDeleteSingleWall(sceneView.camera, axis, mousePos3D);
  231. else PreviewFirstWall(sceneView.camera, mousePos3D, axis, rotateHalfTurn);
  232. break;
  233. case WallManager.ToolState.EDITING:
  234. if (_modularDeleteMode)
  235. {
  236. if (cellsCount == 1) PreviewDeleteSingleWall(sceneView.camera, axis, mousePos3D);
  237. else PreviewDeleteWall(sceneView.camera, axis, mousePos3D);
  238. }
  239. else PreviewWall(sceneView.camera, axis, rotateHalfTurn);
  240. break;
  241. }
  242. WallInfoText(sceneView, localMousePos3D, cellsCount);
  243. }
  244. private static void WallInfoText(UnityEditor.SceneView sceneView, Vector3 localMousePos3D, int cellsCount)
  245. {
  246. if (!PWBCore.staticData.showInfoText) return;
  247. var localX = Mathf.RoundToInt(localMousePos3D.x / SnapManager.settings.step.x);
  248. if (localX >= 0) ++localX;
  249. var localZ = Mathf.RoundToInt(localMousePos3D.z / SnapManager.settings.step.z);
  250. if (localZ >= 0) ++localZ;
  251. var labelTexts = new string[] { $"Position: (X: {localX}, Z: {localZ})", $"Size: {cellsCount}"};
  252. InfoText.Draw(sceneView, labelTexts);
  253. }
  254. private static bool WallInput(Vector3 mousePos3D, AxesUtils.Axis axis, int cellsCount)
  255. {
  256. if ((Event.current.type == EventType.KeyUp || Event.current.type == EventType.KeyDown))
  257. {
  258. if (Event.current.control && !Event.current.alt && !Event.current.shift) _modularDeleteMode = true;
  259. else if (_modularDeleteMode && (!Event.current.control || Event.current.alt || Event.current.shift))
  260. {
  261. _modularDeleteMode = false;
  262. WallManager.state = WallManager.ToolState.FIRST_WALL_PREVIEW;
  263. return true;
  264. }
  265. }
  266. if (Event.current.button == 0)
  267. {
  268. if (Event.current.type == EventType.MouseDown)
  269. {
  270. WallManager.state = WallManager.ToolState.EDITING;
  271. WallManager.endPoint = WallManager.startPoint = mousePos3D;
  272. BrushstrokeManager.UpdateWallBrushstroke(axis, cellsCount: 1, setNextIdx: false, _modularDeleteMode);
  273. return true;
  274. }
  275. if (WallManager.state == WallManager.ToolState.EDITING)
  276. {
  277. if (Event.current.type == EventType.MouseDrag)
  278. {
  279. WallManager.endPoint = mousePos3D;
  280. if (_wallEnd != WallManager.endPoint)
  281. BrushstrokeManager.UpdateWallBrushstroke(axis, cellsCount, setNextIdx: true, _modularDeleteMode);
  282. }
  283. else if (Event.current.type == EventType.MouseUp || Event.current.type == EventType.MouseMove)
  284. {
  285. var paintStrokeCount = _paintStroke.Count;
  286. WallManager.endPoint = mousePos3D;
  287. if (_modularDeleteMode)
  288. DeleteWall();
  289. else Paint(WallManager.settings);
  290. WallManager.state = WallManager.ToolState.FIRST_WALL_PREVIEW;
  291. if (paintStrokeCount == 1)
  292. BrushstrokeManager.UpdateWallBrushstroke(axis, cellsCount: 1, setNextIdx: true, deleteMode: false);
  293. return true;
  294. }
  295. }
  296. _wallEnd = WallManager.endPoint;
  297. }
  298. if (Event.current.isKey && Event.current.keyCode == KeyCode.Escape)
  299. {
  300. WallManager.state = WallManager.ToolState.FIRST_WALL_PREVIEW;
  301. BrushstrokeManager.UpdateWallBrushstroke(axis, cellsCount: 1, setNextIdx: true, deleteMode: false);
  302. return true;
  303. }
  304. if (PWBSettings.shortcuts.wallHalfTurn.Check())
  305. {
  306. WallManager.halfTurn = !WallManager.halfTurn;
  307. WallManager.settings.UpdateCellSize();
  308. SetSnapStepToWallCellSize();
  309. WallManager.state = WallManager.ToolState.FIRST_WALL_PREVIEW;
  310. BrushstrokeManager.UpdateWallBrushstroke(WallManager.wallLenghtAxis, cellsCount: 1,
  311. setNextIdx: false, deleteMode: false);
  312. return true;
  313. }
  314. return false;
  315. }
  316. private static void PreviewFirstWall(Camera camera, Vector3 mousePos3D,
  317. AxesUtils.Axis axis, bool rotateHalfTurn)
  318. {
  319. if (BrushstrokeManager.brushstroke.Length == 0) return;
  320. var strokeItem = BrushstrokeManager.brushstroke[0].Clone();
  321. if (strokeItem.settings == null)
  322. {
  323. BrushstrokeManager.UpdateWallBrushstroke(axis, cellsCount: 1, setNextIdx: false, deleteMode: false);
  324. return;
  325. }
  326. var prefab = strokeItem.settings.prefab;
  327. if (prefab == null) return;
  328. _previewData.Clear();
  329. _paintStroke.Clear();
  330. var toolSettings = WallManager.settings;
  331. var itemRotation = Quaternion.Euler(strokeItem.additionalAngle);
  332. itemRotation *= Quaternion.Inverse(prefab.transform.rotation);
  333. if (rotateHalfTurn) itemRotation *= Quaternion.AngleAxis(180, toolSettings.upwardAxis);
  334. var previewRotation = itemRotation;
  335. if (axis != WallManager.wallLenghtAxis) previewRotation *= Quaternion.AngleAxis(90, toolSettings.upwardAxis);
  336. var cellCenter = mousePos3D;
  337. var halfCellSize = toolSettings.moduleSize / 2;
  338. var nearbyObjects = new System.Collections.Generic.List<GameObject>();
  339. boundsOctree.GetColliding(cellCenter, halfCellSize, SnapManager.settings.rotation,
  340. itemRotation, nearbyObjects);
  341. if (nearbyObjects.Count > 0)
  342. {
  343. bool checkNextItem = false;
  344. foreach (var obj in nearbyObjects)
  345. {
  346. if (obj == null) continue;
  347. if (!obj.activeInHierarchy) continue;
  348. var objCenter = BoundsUtils.GetBoundsRecursive(obj.transform).center;
  349. var centerDistance = (objCenter - cellCenter).magnitude;
  350. if (centerDistance > WallManager.wallThickness * 0.9999) continue;
  351. if (PaletteManager.selectedPalette.ContainsSceneObject(obj))
  352. {
  353. checkNextItem = true;
  354. break;
  355. }
  356. }
  357. if (checkNextItem) return;
  358. }
  359. var scaleMult = strokeItem.scaleMultiplier;
  360. var centerToPivot = GetCenterToPivot(prefab, scaleMult, itemRotation);
  361. var itemPosition = cellCenter + centerToPivot;
  362. var previewCenterToPivot = GetCenterToPivot(prefab, scaleMult, previewRotation);
  363. var previewItemPosition = cellCenter + previewCenterToPivot;
  364. var translateMatrix = Matrix4x4.Translate(Quaternion.Inverse(itemRotation) * -prefab.transform.position);
  365. var rootToWorld = Matrix4x4.TRS(itemPosition, itemRotation, scaleMult) * translateMatrix;
  366. var previewRootToWorld = Matrix4x4.TRS(previewItemPosition, previewRotation, scaleMult) * translateMatrix;
  367. var layer = toolSettings.overwritePrefabLayer ? toolSettings.layer : prefab.layer;
  368. PreviewBrushItem(prefab, previewRootToWorld, layer, camera,
  369. redMaterial: false, reverseTriangles: false, flipX: false, flipY: false);
  370. _previewData.Add(new PreviewData(prefab, previewRootToWorld, layer, flipX: false, flipY: false));
  371. var itemScale = Vector3.Scale(prefab.transform.localScale, scaleMult);
  372. Transform parentTransform = toolSettings.parent;
  373. var paintItem = new PaintStrokeItem(prefab, itemPosition, itemRotation,
  374. itemScale, layer, parentTransform, surface: null, flipX: false, flipY: false);
  375. _paintStroke.Add(paintItem);
  376. }
  377. private static void PreviewWall(Camera camera, AxesUtils.Axis axis, bool rotateHalfTurn)
  378. {
  379. BrushstrokeItem[] brushstroke = null;
  380. if (PreviewIfBrushtrokestaysTheSame(out brushstroke, camera, forceUpdate: _paintStroke.Count == 0)) return;
  381. if (BrushstrokeManager.brushstroke.Length == 0) return;
  382. _previewData.Clear();
  383. _paintStroke.Clear();
  384. var toolSettings = WallManager.settings;
  385. var halfCellSize = toolSettings.moduleSize / 2;
  386. for (int i = 0; i < brushstroke.Length; ++i)
  387. {
  388. var strokeItem = brushstroke[i];
  389. if (strokeItem.settings == null) return;
  390. var prefab = strokeItem.settings.prefab;
  391. if (prefab == null) return;
  392. var scaleMult = strokeItem.scaleMultiplier;
  393. var itemRotation = Quaternion.Euler(strokeItem.additionalAngle);
  394. if (rotateHalfTurn) itemRotation *= Quaternion.AngleAxis(180, toolSettings.upwardAxis);
  395. if (WallManager.halfTurn)
  396. itemRotation *= Quaternion.AngleAxis(180, toolSettings.upwardAxis);
  397. var cellCenter = strokeItem.tangentPosition;
  398. var centerToPivot = GetCenterToPivot(prefab, scaleMult, itemRotation);
  399. var itemPosition = cellCenter + centerToPivot;
  400. var nearbyObjects = new System.Collections.Generic.List<GameObject>();
  401. boundsOctree.GetColliding(cellCenter, halfCellSize, SnapManager.settings.rotation,
  402. itemRotation, nearbyObjects);
  403. if (nearbyObjects.Count > 0)
  404. {
  405. bool checkNextItem = false;
  406. foreach (var obj in nearbyObjects)
  407. {
  408. if (obj == null) continue;
  409. if (!obj.activeInHierarchy) continue;
  410. var objCenter = BoundsUtils.GetBoundsRecursive(obj.transform).center;
  411. var centerDistance = (objCenter - cellCenter).magnitude;
  412. if (centerDistance > WallManager.wallThickness * 0.9999) continue;
  413. if (PaletteManager.selectedPalette.ContainsSceneObject(obj))
  414. {
  415. checkNextItem = true;
  416. break;
  417. }
  418. }
  419. if (checkNextItem) continue;
  420. }
  421. var translateMatrix = Matrix4x4.Translate(Quaternion.Inverse(itemRotation) * -prefab.transform.position);
  422. var rootToWorld = Matrix4x4.TRS(itemPosition, itemRotation, scaleMult) * translateMatrix;
  423. var layer = toolSettings.overwritePrefabLayer ? toolSettings.layer : prefab.layer;
  424. PreviewBrushItem(prefab, rootToWorld, layer, camera,
  425. redMaterial: false, reverseTriangles: false, flipX: false, flipY: false);
  426. _previewData.Add(new PreviewData(prefab, rootToWorld, layer, flipX: false, flipY: false));
  427. var itemScale = Vector3.Scale(prefab.transform.localScale, scaleMult);
  428. Transform parentTransform = toolSettings.parent;
  429. var paintItem = new PaintStrokeItem(prefab, itemPosition, itemRotation,
  430. itemScale, layer, parentTransform, surface: null, flipX: false, flipY: false);
  431. _paintStroke.Add(paintItem);
  432. }
  433. }
  434. private static void PreviewDeleteSingleWall(Camera camera, AxesUtils.Axis axis, Vector3 position)
  435. {
  436. if (BrushstrokeManager.brushstroke.Length == 0) return;
  437. var strokeItem = BrushstrokeManager.brushstroke[0].Clone();
  438. if (strokeItem.settings == null)
  439. {
  440. BrushstrokeManager.UpdateWallBrushstroke(axis, cellsCount: 1, setNextIdx: false, deleteMode: true);
  441. return;
  442. }
  443. var itemRotation = Quaternion.Euler(strokeItem.additionalAngle);
  444. if (axis == AxesUtils.Axis.Z) itemRotation *= Quaternion.Euler(0f, 90f, 0f);
  445. var TRS = Matrix4x4.TRS(position, itemRotation, WallManager.settings.moduleSize);
  446. Graphics.DrawMesh(cubeMesh, TRS, transparentRedMaterial2, 0, camera);
  447. _wallDeleteStroke.Clear();
  448. _wallDeleteStroke.Add(new Pose(position, itemRotation));
  449. }
  450. private static System.Collections.Generic.HashSet<Pose> _wallDeleteStroke
  451. = new System.Collections.Generic.HashSet<Pose>();
  452. private static void PreviewDeleteWall(Camera camera, AxesUtils.Axis axis, Vector3 position)
  453. {
  454. if (BrushstrokeManager.brushstroke.Length == 0) return;
  455. var brushstroke = BrushstrokeManager.brushstroke;
  456. var toolSettings = WallManager.settings;
  457. _wallDeleteStroke.Clear();
  458. for (int i = 0; i < brushstroke.Length; ++i)
  459. {
  460. var strokeItem = brushstroke[i];
  461. var itemPosition = strokeItem.tangentPosition;
  462. var itemRotation = Quaternion.Euler(strokeItem.additionalAngle);
  463. var rootToWorld = Matrix4x4.TRS(itemPosition, itemRotation, WallManager.settings.moduleSize);
  464. Graphics.DrawMesh(cubeMesh, rootToWorld, transparentRedMaterial2, layer: 0, camera);
  465. _wallDeleteStroke.Add(new Pose(itemPosition, itemRotation));
  466. }
  467. }
  468. private static void DeleteWall()
  469. {
  470. if (_wallDeleteStroke.Count == 0) return;
  471. var toolSettings = WallManager.settings;
  472. var toBeDeleted = new System.Collections.Generic.HashSet<GameObject>();
  473. var halfCellSize = toolSettings.moduleSize / 2;
  474. foreach (var cellPose in _wallDeleteStroke)
  475. {
  476. var nearbyObjects = new System.Collections.Generic.List<GameObject>();
  477. boundsOctree.GetColliding(cellPose.position, halfCellSize,
  478. SnapManager.settings.rotation, cellPose.rotation, nearbyObjects);
  479. if (nearbyObjects.Count == 0) continue;
  480. foreach (var obj in nearbyObjects)
  481. {
  482. if (obj == null) continue;
  483. if (!obj.activeInHierarchy) continue;
  484. var objCenter = BoundsUtils.GetBoundsRecursive(obj.transform).center;
  485. var centerDistance = (objCenter - cellPose.position).magnitude;
  486. if (centerDistance > WallManager.wallThickness * 0.999) continue;
  487. if (PaletteManager.selectedPalette.ContainsSceneObject(obj)) toBeDeleted.Add(obj);
  488. }
  489. }
  490. void EraseObject(GameObject obj)
  491. {
  492. if (obj == null) return;
  493. var root = UnityEditor.PrefabUtility.GetNearestPrefabInstanceRoot(obj);
  494. if (root != null) obj = root;
  495. PWBCore.DestroyTempCollider(obj.GetInstanceID());
  496. UnityEditor.Undo.DestroyObjectImmediate(obj);
  497. }
  498. foreach (var obj in toBeDeleted) EraseObject(obj);
  499. }
  500. }
  501. }