ObjectPlacement.cs 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. namespace O3DWB
  8. {
  9. [Serializable]
  10. public class ObjectPlacement : ScriptableObject, IMessageListener
  11. {
  12. #region Private Variables
  13. private CoordinateSystemAxis _currentGuideAlignmentAxis = CoordinateSystemAxis.PositiveRight;
  14. private bool _isPlacementLocked = false;
  15. [SerializeField]
  16. private InteractableMirror _mirror;
  17. [SerializeField]
  18. private ProjectedBoxFacePivotPoints _projectedGuidePivotPoints = new ProjectedBoxFacePivotPoints();
  19. [SerializeField]
  20. private ObjectPivotPointsRenderSettings _guidePivotPointsRenderSettings;
  21. private ProjectedBoxFacePivotPointsRenderer _guidePivotPointsRenderer = new ProjectedBoxFacePivotPointsRenderer();
  22. private ObjectVertexSnapSession _objectVertexSnapSession = new ObjectVertexSnapSession();
  23. private ObjectVertexSnapSessionRenderer _objectVertexSnapSessionRenderer = new ObjectVertexSnapSessionRenderer();
  24. [SerializeField]
  25. private ObjectVertexSnapSessionRenderSettings _objectVertexSnapSessionRenderSettings;
  26. [SerializeField]
  27. private ObjectPlacementSettings _settings;
  28. [SerializeField]
  29. private PersistentObjectPlacementGuideData _persistentObjectPlacementGuideData = new PersistentObjectPlacementGuideData();
  30. [SerializeField]
  31. private PointAndClickObjectPlacement _pointAndClickObjectPlacement = new PointAndClickObjectPlacement();
  32. [SerializeField]
  33. private PathObjectPlacement _pathObjectPlacement = new PathObjectPlacement();
  34. [SerializeField]
  35. private BlockObjectPlacement _blockObjectPlacement = new BlockObjectPlacement();
  36. [SerializeField]
  37. private DecorPaintObjectPlacement _decorPaintObjectPlacement;
  38. #endregion
  39. #region Private Properties
  40. private InteractableMirror Mirror
  41. {
  42. get
  43. {
  44. if (_mirror == null) _mirror = Octave3DWorldBuilder.ActiveInstance.CreateScriptableObject<InteractableMirror>();
  45. return _mirror;
  46. }
  47. }
  48. #endregion
  49. #region Public Properties
  50. public ObjectPlacementSettings Settings
  51. {
  52. get
  53. {
  54. if (_settings == null) _settings = Octave3DWorldBuilder.ActiveInstance.CreateScriptableObject<ObjectPlacementSettings>();
  55. return _settings;
  56. }
  57. }
  58. public ObjectPivotPointsRenderSettings GuidePivotPointsRenderSettings
  59. {
  60. get
  61. {
  62. if (_guidePivotPointsRenderSettings == null) _guidePivotPointsRenderSettings = Octave3DWorldBuilder.ActiveInstance.CreateScriptableObject<ObjectPivotPointsRenderSettings>();
  63. return _guidePivotPointsRenderSettings;
  64. }
  65. }
  66. public ObjectVertexSnapSessionRenderSettings ObjectVertexSnapSessionRenderSettings
  67. {
  68. get
  69. {
  70. if (_objectVertexSnapSessionRenderSettings == null) _objectVertexSnapSessionRenderSettings = Octave3DWorldBuilder.ActiveInstance.CreateScriptableObject<ObjectVertexSnapSessionRenderSettings>();
  71. return _objectVertexSnapSessionRenderSettings;
  72. }
  73. }
  74. public ProjectedBoxFacePivotPoints ProjectedGuidePivotPoints { get { return _projectedGuidePivotPoints; } }
  75. public Vector3 CenterProjectedGuidePivotPoint { get { return _projectedGuidePivotPoints.CenterPoint; } }
  76. public Vector3 ActiveGuidePivotPoint { get { return _projectedGuidePivotPoints.ActivePoint; } }
  77. public ObjectPlacementMode ObjectPlacementMode { get { return Settings.ObjectPlacementMode; } }
  78. public bool UsingBrushDecorPaintMode { get { return ObjectPlacementMode == ObjectPlacementMode.DecorPaint && Settings.DecorPaintObjectPlacementSettings.DecorPaintMode == DecorPaintMode.Brush; } }
  79. public PersistentObjectPlacementGuideData PersistentObjectPlacementGuideData { get { return _persistentObjectPlacementGuideData; } }
  80. public PointAndClickObjectPlacement PointAndClickObjectPlacement { get { return _pointAndClickObjectPlacement; } }
  81. public PathObjectPlacement PathObjectPlacement { get { return _pathObjectPlacement; } }
  82. public BlockObjectPlacement BlockObjectPlacement { get { return _blockObjectPlacement; } }
  83. public DecorPaintObjectPlacement DecorPaintObjectPlacement
  84. {
  85. get
  86. {
  87. if (_decorPaintObjectPlacement == null) _decorPaintObjectPlacement = Octave3DWorldBuilder.ActiveInstance.CreateScriptableObject<DecorPaintObjectPlacement>();
  88. return _decorPaintObjectPlacement;
  89. }
  90. }
  91. public bool UserWantsToPlaceTileConnections
  92. {
  93. get
  94. {
  95. return Settings.ObjectPlacementMode == ObjectPlacementMode.Path &&
  96. PathObjectPlacement.PathSettings.TileConnectionSettings.UseTileConnections;
  97. }
  98. }
  99. public bool IsObjectVertexSnapSessionActive { get { return _objectVertexSnapSession.IsActive; } }
  100. public bool IsPlacementLocked { get { return _isPlacementLocked; } }
  101. public InteractableMirrorSettings MirrorSettings { get { return Mirror.Settings; } }
  102. public InteractableMirrorRenderSettings MirrorRenderSettings { get { return Mirror.RenderSettings; } }
  103. public InteractableMirrorView MirrorView { get { return Mirror.View; } }
  104. #endregion
  105. #region Constructors
  106. public ObjectPlacement()
  107. {
  108. PrefabCategory.PrefabActivationValidationCallback = PrefabActivationValidationCallback;
  109. }
  110. #endregion
  111. #region Public Static Functions
  112. public static ObjectPlacement Get()
  113. {
  114. return Octave3DWorldBuilder.ActiveInstance.ObjectPlacement;
  115. }
  116. #endregion
  117. #region Public Methods
  118. public void DestroyPlacementGuide()
  119. {
  120. if(ObjectPlacementGuide.ExistsInScene)
  121. {
  122. PrepareForPlacementGuideDestruction();
  123. ObjectPlacementGuide.DestroyIfExists();
  124. }
  125. }
  126. public void RenderGizmos()
  127. {
  128. if (_objectVertexSnapSession.IsActive) _objectVertexSnapSessionRenderer.RenderGizmos(_objectVertexSnapSession, ObjectVertexSnapSessionRenderSettings);
  129. if (Settings.ObjectPlacementMode == ObjectPlacementMode.DecorPaint) RenderGizmosForDecorPaintMode();
  130. else RenderGizmosForNonDecorPaintMode();
  131. if(Mirror.IsActive)
  132. {
  133. Mirror.RenderGizmos();
  134. if (ObjectPlacementMode == ObjectPlacementMode.PointAndClick &&
  135. ObjectPlacementGuide.ExistsInSceneAndIsActive) Mirror.RenderMirroredHierarchyOrientedBox(ObjectPlacementGuide.SceneObject);
  136. else
  137. if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint &&
  138. DecorPaintObjectPlacement.DecorPaintMode == DecorPaintMode.Single &&
  139. ObjectPlacementGuide.ExistsInSceneAndIsActive) Mirror.RenderMirroredHierarchyOrientedBox(ObjectPlacementGuide.SceneObject);
  140. else
  141. if (ObjectPlacementMode == ObjectPlacementMode.Path &&
  142. PathObjectPlacement.IsPathUnderManualConstruction) Mirror.RenderMirroredEntityOrientedBoxes(PathObjectPlacement.AllOrientedBoxesInPath);
  143. else
  144. if (ObjectPlacementMode == ObjectPlacementMode.Block &&
  145. BlockObjectPlacement.IsBlockUnderManualConstruction) Mirror.RenderMirroredEntityOrientedBoxes(BlockObjectPlacement.AllOrientedBoxesInBlock);
  146. }
  147. }
  148. public void RenderHandles()
  149. {
  150. if (ObjectPlacementGuide.ExistsInScene)
  151. {
  152. Handles.BeginGUI();
  153. var labelStyle = new GUIStyle();
  154. labelStyle.normal.textColor = Color.white;
  155. Rect labelRect = new Rect(2.0f, 0.0f, 1000, 15.0f);
  156. GUI.Label(labelRect, "Active prefab: " + ObjectPlacementGuide.Instance.SourcePrefab.Name, labelStyle);
  157. if(ObjectPlacementMode != ObjectPlacementMode.DecorPaint)
  158. {
  159. labelRect.yMin += 15.0f;
  160. GUI.Label(labelRect, "Enable object surface grid [W]: " + ObjectSnapping.Get().Settings.EnableObjectSurfaceGrid, labelStyle);
  161. labelRect.yMin += 15.0f;
  162. GUI.Label(labelRect, "Object to object snap [U]: " + ObjectSnapping.Get().Settings.EnableObjectToObjectSnap, labelStyle);
  163. labelRect.yMin += 15.0f;
  164. GUI.Label(labelRect, "Toggle original pivot [0]: " + ObjectSnapping.Get().Settings.UseOriginalPivot, labelStyle);
  165. }
  166. Handles.EndGUI();
  167. }
  168. if (ObjectPlacementMode == ObjectPlacementMode.Block) BlockObjectPlacement.RenderHandles();
  169. }
  170. public void HandleRepaintEvent(Event e)
  171. {
  172. if(Mirror.IsInteractionSessionActive)
  173. {
  174. Mirror.HandleRepaintEvent(e);
  175. return;
  176. }
  177. else
  178. {
  179. ObjectPlacementGuide.Active = CanGuideBeActive();
  180. CancelPlacementGuideSessionsIfNecessary();
  181. if (!AllShortcutCombos.Instance.ActivateObjectVertexSnapSession_Placement.IsActive()) _objectVertexSnapSession.End();
  182. }
  183. }
  184. public void HandleMouseMoveEvent(Event e)
  185. {
  186. if (_isPlacementLocked) return;
  187. if (Mirror.IsInteractionSessionActive)
  188. {
  189. e.DisableInSceneView();
  190. Mirror.HandleMouseMoveEvent(e);
  191. return;
  192. }
  193. ObjectPlacementGuidePrefabUpdate.EnsureGuideUsesCorrectPrefab();
  194. if(_objectVertexSnapSession.IsActive)
  195. {
  196. e.DisableInSceneView();
  197. _objectVertexSnapSession.UpdateForMouseMovement();
  198. return;
  199. }
  200. bool isAnyGuideSessionActive = false;
  201. if(ObjectPlacementGuide.ExistsInSceneAndIsActive)
  202. {
  203. e.DisableInSceneView();
  204. UpdatePlacementGuideSessions(e);
  205. isAnyGuideSessionActive = ObjectPlacementGuide.Instance.IsAnyMouseSessionActive;
  206. }
  207. if (!isAnyGuideSessionActive && !_objectVertexSnapSession.IsActive)
  208. {
  209. if (ObjectPlacementMode == ObjectPlacementMode.PointAndClick) PointAndClickObjectPlacement.HandleMouseMoveEvent(e);
  210. else if (ObjectPlacementMode == ObjectPlacementMode.Block) BlockObjectPlacement.HandleMouseMoveEvent(e);
  211. else if (ObjectPlacementMode == ObjectPlacementMode.Path) PathObjectPlacement.HandleMouseMoveEvent(e);
  212. else if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint) DecorPaintObjectPlacement.HandleMouseMoveEvent(e);
  213. }
  214. SceneView.RepaintAll();
  215. }
  216. public void HandleMouseDragEvent(Event e)
  217. {
  218. if (_isPlacementLocked || Mirror.IsInteractionSessionActive) return;
  219. if (_objectVertexSnapSession.IsActive)
  220. {
  221. e.DisableInSceneView();
  222. _objectVertexSnapSession.UpdateForMouseMovement();
  223. return;
  224. }
  225. if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint) DecorPaintObjectPlacement.HandleMouseDragEvent(e);
  226. }
  227. public void HandleMouseButtonDownEvent(Event e)
  228. {
  229. if (e.InvolvesLeftMouseButton()) e.DisableInSceneView();
  230. if (Mirror.IsInteractionSessionActive && e.InvolvesLeftMouseButton())
  231. {
  232. e.DisableInSceneView();
  233. Mirror.EndInteractionSession();
  234. return;
  235. }
  236. if(_objectVertexSnapSession.IsActive)
  237. {
  238. e.DisableInSceneView();
  239. return;
  240. }
  241. if (AllShortcutCombos.Instance.SnapXZGridToCursorPickPointOnLeftClick_Placement.IsActive() && e.InvolvesLeftMouseButton())
  242. {
  243. if(!IsConstructingBlock() && !IsConstructingPath())
  244. {
  245. e.DisableInSceneView();
  246. ObjectSnapping.Get().SnapXZGridToCursorPickPoint(e.clickCount == 2);
  247. return;
  248. }
  249. }
  250. if (_isPlacementLocked)
  251. {
  252. // Note: If this is a left click event, we will eat the event so that the tool
  253. // object doesn't get deselected in the scene view.
  254. if (e.InvolvesLeftMouseButton()) e.DisableInSceneView();
  255. return;
  256. }
  257. if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint) DecorPaintObjectPlacement.HandleMouseButtonDownEvent(e);
  258. if (ObjectPlacementMode == ObjectPlacementMode.PointAndClick) PointAndClickObjectPlacement.HandleMouseButtonDownEvent(e);
  259. else if (ObjectPlacementMode == ObjectPlacementMode.Path) PathObjectPlacement.HandleMouseButtonDownEvent(e);
  260. else if (ObjectPlacementMode == ObjectPlacementMode.Block) BlockObjectPlacement.HandleMouseButtonDownEvent(e);
  261. }
  262. public void HandleMouseButtonUpEvent(Event e)
  263. {
  264. if (_isPlacementLocked) return;
  265. if (ObjectPlacementGuide.ExistsInSceneAndIsActive &&
  266. !ObjectPlacementGuide.Instance.IsAnyMouseSessionActive)
  267. {
  268. if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint) DecorPaintObjectPlacement.HandleMouseButtonUpEvent(e);
  269. }
  270. }
  271. public void HandleKeyboardButtonDownEvent(Event e)
  272. {
  273. e.DisableInSceneView();
  274. if (AllShortcutCombos.Instance.LockObjectPlacement.IsActive())
  275. {
  276. _isPlacementLocked = !_isPlacementLocked;
  277. Inspector.Get().EditorWindow.Repaint();
  278. return;
  279. }
  280. if (_isPlacementLocked) return;
  281. if (Mirror.IsInteractionSessionActive)
  282. {
  283. Mirror.HandleKeyboardButtonDownEvent(e);
  284. return;
  285. }
  286. if (AllShortcutCombos.Instance.PickPrefabFromScene.IsActive() && CanPickPrefabFromScene())
  287. {
  288. e.DisableInSceneView();
  289. MouseCursor.Instance.PushObjectPickMaskFlags(MouseCursorObjectPickFlags.ObjectBox | MouseCursorObjectPickFlags.ObjectTerrain);
  290. MouseCursor.Instance.PushObjectMaskEnabledState(false);
  291. MouseCursorRayHit cursorRayHit = MouseCursor.Instance.GetRayHit();
  292. MouseCursor.Instance.PopObjectPickMaskFlags();
  293. MouseCursor.Instance.PopObjectMaskEnabledState();
  294. if (cursorRayHit.WasAnObjectHit)
  295. {
  296. GameObject sourcePrefab = cursorRayHit.ClosestObjectRayHit.HitObject.GetSourcePrefabRoot();
  297. if (sourcePrefab != null)
  298. {
  299. PrefabCategory categoryWhichContainsPrefab = PrefabCategoryDatabase.Get().GetPrefabCategoryWhichContainsPrefab(sourcePrefab);
  300. if (categoryWhichContainsPrefab != null)
  301. {
  302. Prefab prefabToActivate = categoryWhichContainsPrefab.GetPrefabByUnityPrefab(sourcePrefab);
  303. if (prefabToActivate != null)
  304. {
  305. UndoEx.RecordForToolAction(PrefabCategoryDatabase.Get());
  306. PrefabCategoryDatabase.Get().SetActivePrefabCategory(categoryWhichContainsPrefab);
  307. UndoEx.RecordForToolAction(categoryWhichContainsPrefab);
  308. categoryWhichContainsPrefab.SetActivePrefab(prefabToActivate);
  309. if (AllShortcutCombos.Instance.PickPrefabWithTransform.IsActive())
  310. {
  311. if (ObjectPlacementGuide.ExistsInScene)
  312. {
  313. ObjectPlacementGuide.Instance.SetWorldScale(cursorRayHit.ClosestObjectRayHit.HitObject.transform.lossyScale);
  314. }
  315. }
  316. }
  317. }
  318. else
  319. {
  320. PrefabCategory activeCategory = PrefabCategoryDatabase.Get().ActivePrefabCategory;
  321. if (activeCategory != null)
  322. {
  323. UndoEx.RecordForToolAction(activeCategory);
  324. Prefab prefab = PrefabFactory.Create(sourcePrefab);
  325. activeCategory.AddPrefab(prefab);
  326. //activeCategory.SetActivePrefab(prefab);
  327. }
  328. }
  329. }
  330. }
  331. return;
  332. }
  333. if(AllShortcutCombos.Instance.ToggleDecorSurfaceAlign.IsActive())
  334. {
  335. // ...
  336. Settings.DecorPaintObjectPlacementSettings.SingleDecorPaintModeSettings.PlacementGuideSurfaceAlignmentSettings.IsEnabled =
  337. !Settings.DecorPaintObjectPlacementSettings.SingleDecorPaintModeSettings.PlacementGuideSurfaceAlignmentSettings.IsEnabled;
  338. Octave3DWorldBuilder.ActiveInstance.Inspector.Repaint();
  339. }
  340. else
  341. if(AllShortcutCombos.Instance.StepXZGridUp.IsActive())
  342. {
  343. XZGrid grid = ObjectSnapping.Get().XZSnapGrid;
  344. UndoEx.RecordForToolAction(grid);
  345. grid.Translate(new Vector3(0.0f, ObjectSnapping.Get().Settings.XZGridYOffsetStep, 0.0f));
  346. Octave3DWorldBuilder.ActiveInstance.Inspector.Repaint();
  347. }
  348. else
  349. if(AllShortcutCombos.Instance.StepXZGridDown.IsActive())
  350. {
  351. XZGrid grid = ObjectSnapping.Get().XZSnapGrid;
  352. UndoEx.RecordForToolAction(grid);
  353. grid.Translate(new Vector3(0.0f, -ObjectSnapping.Get().Settings.XZGridYOffsetStep, 0.0f));
  354. Octave3DWorldBuilder.ActiveInstance.Inspector.Repaint();
  355. }
  356. else
  357. if (AllShortcutCombos.Instance.ActivateObjectVertexSnapSession_Placement.IsActive() && CanActivateObjectVertexSnapSession())
  358. {
  359. e.DisableInSceneView();
  360. DestroyPlacementGuide();
  361. _objectVertexSnapSession.Begin();
  362. return;
  363. }
  364. else
  365. if(AllShortcutCombos.Instance.ActivateDecorPaintPlacement.IsActive())
  366. {
  367. if(Settings.ObjectPlacementMode != ObjectPlacementMode.DecorPaint)
  368. {
  369. UndoEx.RecordForToolAction(Settings);
  370. Settings.ObjectPlacementMode = ObjectPlacementMode.DecorPaint;
  371. Inspector.Get().Repaint();
  372. return;
  373. }
  374. }
  375. else
  376. if (AllShortcutCombos.Instance.ActivatePointAndClickPlacement.IsActive())
  377. {
  378. if (Settings.ObjectPlacementMode != ObjectPlacementMode.PointAndClick)
  379. {
  380. UndoEx.RecordForToolAction(Settings);
  381. Settings.ObjectPlacementMode = ObjectPlacementMode.PointAndClick;
  382. Inspector.Get().Repaint();
  383. return;
  384. }
  385. }
  386. else
  387. if (AllShortcutCombos.Instance.ActivatePathPlacement.IsActive())
  388. {
  389. if (Settings.ObjectPlacementMode != ObjectPlacementMode.Path)
  390. {
  391. UndoEx.RecordForToolAction(Settings);
  392. Settings.ObjectPlacementMode = ObjectPlacementMode.Path;
  393. Inspector.Get().Repaint();
  394. return;
  395. }
  396. }
  397. else
  398. if (AllShortcutCombos.Instance.ActivateBlockPlacement.IsActive())
  399. {
  400. if (Settings.ObjectPlacementMode != ObjectPlacementMode.Block)
  401. {
  402. UndoEx.RecordForToolAction(Settings);
  403. Settings.ObjectPlacementMode = ObjectPlacementMode.Block;
  404. Inspector.Get().Repaint();
  405. return;
  406. }
  407. }
  408. else
  409. if (AllShortcutCombos.Instance.ToggleUseOriginalPivotForSnapping.IsActive())
  410. {
  411. if (Settings.ObjectPlacementMode != ObjectPlacementMode.DecorPaint)
  412. {
  413. ObjectSnapping.Get().Settings.UseOriginalPivot = !ObjectSnapping.Get().Settings.UseOriginalPivot;
  414. Inspector.Get().Repaint();
  415. return;
  416. }
  417. }
  418. if (ObjectPlacementGuide.ExistsInSceneAndIsActive)
  419. {
  420. if (RotatePlacementGuideWithKeyboardIfNecessary()) e.DisableInSceneView();
  421. else
  422. if (AllShortcutCombos.Instance.CycleThroughProjectedBoxFaceGuidePivotPoints.IsActive() && !ObjectSnapping.Get().Settings.UseOriginalPivot)
  423. {
  424. e.DisableInSceneView();
  425. _projectedGuidePivotPoints.ActivateNextPivotPoint();
  426. }
  427. else
  428. if (AllShortcutCombos.Instance.SetPlacementGuideScaleToOriginal.IsActive())
  429. {
  430. e.DisableInSceneView();
  431. ObjectPlacementGuide.Instance.SetHierarchyWorldScaleByPivotPoint(ObjectPlacementGuide.Instance.SourcePrefab.InitialWorldScale, CalculateGuideScalePivotPoint());
  432. UpdateGuideProjectedPivotPoints();
  433. }
  434. else
  435. if(AllShortcutCombos.Instance.ToggleEnableObjectSurfaceGrid.IsActive())
  436. {
  437. e.DisableInSceneView();
  438. UndoEx.RecordForToolAction(ObjectSnapSettings.Get());
  439. ObjectSnapSettings.Get().EnableObjectSurfaceGrid = !ObjectSnapSettings.Get().EnableObjectSurfaceGrid;
  440. Octave3DWorldBuilder.ActiveInstance.Inspector.EditorWindow.Repaint();
  441. }
  442. else
  443. if (AllShortcutCombos.Instance.SetPlacementGuideRotationToIdentity.IsActive())
  444. {
  445. e.DisableInSceneView();
  446. ObjectPlacementGuide.Instance.SetHierarchyWorldRotationAndPreserveHierarchyCenter(Quaternion.identity);
  447. UpdateGuideProjectedPivotPoints();
  448. }
  449. else
  450. if (AllShortcutCombos.Instance.AlignPlacementGuideToNextAxis.IsActive())
  451. {
  452. e.DisableInSceneView();
  453. AxisAlignment.AlignObjectAxis(ObjectPlacementGuide.SceneObject, _currentGuideAlignmentAxis, ObjectPlacementSurfaceInfo.GetSurfaceNormal());
  454. UpdateGuideProjectedPivotPoints();
  455. AdjustPlacementGuidePositionOnCurrentPlacementSurface();
  456. _currentGuideAlignmentAxis = CoordinateSystemAxes.GetNext(_currentGuideAlignmentAxis);
  457. }
  458. else
  459. if(AllShortcutCombos.Instance.AdjustXZGridCellSizeToGuideSize.IsActive() && ObjectPlacementGuide.ExistsInSceneAndIsActive)
  460. {
  461. e.DisableInSceneView();
  462. Plane xzGridPlane = ObjectSnapping.Get().XZSnapGrid.Plane;
  463. OrientedBox guideWorldOrientedBox = ObjectPlacementGuide.SceneObject.GetHierarchyWorldOrientedBox();
  464. BoxFace faceWhichFacesGrid = guideWorldOrientedBox.GetBoxFaceWhichFacesNormal(xzGridPlane.normal);
  465. List<Vector3> boxFacePoints = guideWorldOrientedBox.GetBoxFaceCornerPoints(faceWhichFacesGrid);
  466. List<Vector3> projectedBoxFacePoints = xzGridPlane.ProjectAllPoints(boxFacePoints);
  467. Box projectedPointsBox = Vector3Extensions.GetPointCloudBox(projectedBoxFacePoints);
  468. UndoEx.RecordForToolAction(ObjectSnapping.Get().XZSnapGrid.CellSizeSettings);
  469. TransformMatrix gridTransformMatrix = ObjectSnapping.Get().XZSnapGrid.TransformMatrix;
  470. ObjectSnapping.Get().XZSnapGrid.CellSizeSettings.CellSizeX = projectedPointsBox.Size.GetAbsDot(gridTransformMatrix.GetNormalizedRightAxis());
  471. ObjectSnapping.Get().XZSnapGrid.CellSizeSettings.CellSizeZ = projectedPointsBox.Size.GetAbsDot(gridTransformMatrix.GetNormalizedLookAxis());
  472. SceneView.RepaintAll();
  473. }
  474. else
  475. if(AllShortcutCombos.Instance.TogglePlacementObject2ObjectSnap.IsActive())
  476. {
  477. e.DisableInSceneView();
  478. UndoEx.RecordForToolAction(ObjectSnapSettings.Get());
  479. ObjectSnapping.Get().Settings.EnableObjectToObjectSnap = !ObjectSnapping.Get().Settings.EnableObjectToObjectSnap;
  480. Octave3DWorldBuilder.ActiveInstance.Inspector.EditorWindow.Repaint();
  481. }
  482. }
  483. if (_settings.ObjectPlacementMode == ObjectPlacementMode.Path) PathObjectPlacement.HandleKeyboardButtonDownEvent(e);
  484. else if (_settings.ObjectPlacementMode == ObjectPlacementMode.Block) BlockObjectPlacement.HandleKeyboardButtonDownEvent(e);
  485. }
  486. public void HandleKeyboardButtonUpEvent(Event e)
  487. {
  488. }
  489. public void HandleMouseScrollWheelEvent(Event e)
  490. {
  491. if (_isPlacementLocked) return;
  492. if (AllShortcutCombos.Instance.CycleThroughPrefabsInActiveCategoryUsingMouseScrollWheel.IsActive() && ObjectPlacementGuide.ExistsInScene)
  493. {
  494. e.DisableInSceneView();
  495. if (Mathf.Abs(e.delta.y) <= 3.0f)
  496. {
  497. OrientedBox guideWorldOrientedBox = ObjectPlacementGuide.SceneObject.GetHierarchyWorldOrientedBox();
  498. Quaternion currentWorldRotation = ObjectPlacementGuide.Instance.WorldRotation;
  499. UndoEx.RecordForToolAction(PrefabCategoryDatabase.Get().ActivePrefabCategory);
  500. if (e.delta.y > 0.0f) PrefabCategoryActions.ActivateNextPrefabInPrefabCategory(PrefabCategoryDatabase.Get().ActivePrefabCategory);
  501. else if (e.delta.y < 0.0f) PrefabCategoryActions.ActivatePreviousPrefabInPrefabCategory(PrefabCategoryDatabase.Get().ActivePrefabCategory);
  502. ObjectPlacementGuide.Instance.SetWorldPosition(ObjectPositionCalculator.CalculateObjectHierarchyPosition(ObjectPlacementGuide.SceneObject, guideWorldOrientedBox.Center, ObjectPlacementGuide.Instance.WorldScale, ObjectPlacementGuide.Instance.WorldRotation));
  503. UpdateGuideProjectedPivotPoints();
  504. AdjustPlacementGuidePositionOnCurrentPlacementSurface();
  505. if (Settings.InheritRotationOnPrefabScroll) ObjectPlacementGuide.Instance.SetWorldRotation(currentWorldRotation);
  506. Octave3DWorldBuilder.ActiveInstance.PrefabManagementWindow.Repaint();
  507. }
  508. }
  509. else
  510. if (AllShortcutCombos.Instance.CycleThroughPrefabCategoriesUsingMouseScrollWheel.IsActive())
  511. {
  512. e.DisableInSceneView();
  513. if (Mathf.Abs(e.delta.y) <= 3.0f && PrefabCategoryDatabase.Get().NumberOfCategories > 1)
  514. {
  515. if (ObjectPlacementGuide.ExistsInScene)
  516. {
  517. OrientedBox guideWorldOrientedBox = ObjectPlacementGuide.SceneObject.GetHierarchyWorldOrientedBox();
  518. UndoEx.RecordForToolAction(PrefabCategoryDatabase.Get());
  519. if (e.delta.y > 0.0f) PrefabCategoryDatabase.Get().ActivateNextPrefabCategory();
  520. else if (e.delta.y < 0.0f) PrefabCategoryDatabase.Get().ActivatePreviousPrefabCategory();
  521. if (PrefabCategoryDatabase.Get().ActivePrefabCategory.ActivePrefab != null)
  522. {
  523. DestroyPlacementGuide();
  524. ObjectPlacementGuide.CreateFromActivePrefabIfNotExists();
  525. ObjectPlacementGuide.Instance.SetWorldPosition(ObjectPositionCalculator.CalculateObjectHierarchyPosition(ObjectPlacementGuide.SceneObject, guideWorldOrientedBox.Center, ObjectPlacementGuide.Instance.WorldScale, ObjectPlacementGuide.Instance.WorldRotation));
  526. UpdateGuideProjectedPivotPoints();
  527. AdjustPlacementGuidePositionOnCurrentPlacementSurface();
  528. }
  529. Octave3DWorldBuilder.ActiveInstance.PrefabManagementWindow.Repaint();
  530. }
  531. else
  532. {
  533. UndoEx.RecordForToolAction(PrefabCategoryDatabase.Get());
  534. if (e.delta.y > 0.0f) PrefabCategoryDatabase.Get().ActivateNextPrefabCategory();
  535. else if (e.delta.y < 0.0f) PrefabCategoryDatabase.Get().ActivatePreviousPrefabCategory();
  536. Octave3DWorldBuilder.ActiveInstance.PrefabManagementWindow.Repaint();
  537. }
  538. }
  539. }
  540. else
  541. if (DoesCurrentPlacementModeRequireSnapping() &&
  542. AllShortcutCombos.Instance.EnableScrollWheelDesiredCellSizeAdjustmentForObjectColliderSnapSurfaceGrid.IsActive())
  543. {
  544. e.DisableInSceneView();
  545. if (Mathf.Abs(e.delta.y) <= 3.0f)
  546. {
  547. float adjustmentSpeed = ObjectSnapSettings.Get().ObjectColliderSnapSurfaceGridSettings.DesiredCellSize * 0.1f;
  548. float sizeAdjustAmount = -e.delta.y * adjustmentSpeed;
  549. UndoEx.RecordForToolAction(ObjectSnapSettings.Get().ObjectColliderSnapSurfaceGridSettings);
  550. ObjectSnapSettings.Get().ObjectColliderSnapSurfaceGridSettings.DesiredCellSize += sizeAdjustAmount;
  551. ObjectSnapping.Get().RefreshSnapSurface();
  552. }
  553. }
  554. else
  555. if (Settings.ObjectPlacementMode == ObjectPlacementMode.DecorPaint) DecorPaintObjectPlacement.HandleMouseScrollWheelEvent(e);
  556. }
  557. #endregion
  558. #region Message Handlers
  559. public void RespondToMessage(Message message)
  560. {
  561. switch(message.Type)
  562. {
  563. case MessageType.PrefabWasRemovedFromCategory:
  564. RespondToMessage(message as PrefabWasRemovedFromCategoryMessage);
  565. break;
  566. case MessageType.PrefabCategoryWasRemovedFromDatabase:
  567. RespondToMessage(message as PrefabCategoryWasRemovedFromDatabaseMessage);
  568. break;
  569. case MessageType.ObjectPlacementModeWasChanged:
  570. RespondToMessage(message as ObjectPlacementModeWasChangedMessage);
  571. break;
  572. case MessageType.UndoRedoWasPerformed:
  573. RespondToMessage(message as UndoRedoWasPerformedMessage);
  574. break;
  575. case MessageType.InspectorGUIWasChanged:
  576. RespondToMessage(message as InspectorGUIWasChangedMessage);
  577. break;
  578. case MessageType.ObjectHierarchyRootsWerePlacedInScene:
  579. RespondToMessage(message as ObjectHierarchyRootsWerePlacedInSceneMessage);
  580. break;
  581. case MessageType.ObjectPlacementGuideWasInstantiated:
  582. RespondToMessage(message as ObjectPlacementGuideWasInstantiatedMessage);
  583. break;
  584. case MessageType.ToolWasReset:
  585. RespondToMessage(message as ToolWasResetMessage);
  586. break;
  587. }
  588. }
  589. private void RespondToMessage(PrefabWasRemovedFromCategoryMessage message)
  590. {
  591. PathObjectPlacement.PathSettings.TileConnectionSettings.RecordAllTileConnectionTypeSettingsForUndo();
  592. PathObjectPlacement.PathSettings.TileConnectionSettings.RemovePrefabAssociation(message.PrefabWhichWasRemoved);
  593. ObjectPlacementPathTileConnectionConfigurationDatabase.Get().RecordAllConfigurationsForUndo();
  594. ObjectPlacementPathTileConnectionConfigurationDatabase.Get().RemovePrefabAssociationForAllConfigurations(message.PrefabWhichWasRemoved);
  595. // NOTE: This is now handled inside the brush class
  596. //DecorPaintObjectPlacementBrushDatabase.Get().RecordAllBrushesForUndo();
  597. // DecorPaintObjectPlacementBrushDatabase.Get().RemovePrefabAssociationForAllBrushElements(message.PrefabWhichWasRemoved);
  598. }
  599. private void RespondToMessage(PrefabCategoryWasRemovedFromDatabaseMessage message)
  600. {
  601. List<Prefab> allPrefabsInCategory = message.PrefabCategoryWhichWasRemoved.GetAllPrefabs();
  602. PathObjectPlacement.PathSettings.TileConnectionSettings.RecordAllTileConnectionTypeSettingsForUndo();
  603. PathObjectPlacement.PathSettings.TileConnectionSettings.RemovePrefabAssociations(allPrefabsInCategory);
  604. ObjectPlacementPathTileConnectionConfigurationDatabase.Get().RecordAllConfigurationsForUndo();
  605. ObjectPlacementPathTileConnectionConfigurationDatabase.Get().RemovePrefabAssociationForAllConfigurations(allPrefabsInCategory);
  606. // NOTE: This is now handled inside the brush class
  607. //DecorPaintObjectPlacementBrushDatabase.Get().RecordAllBrushesForUndo();
  608. // DecorPaintObjectPlacementBrushDatabase.Get().RemovePrefabAssociationForAllBrushElements(allPrefabsInCategory);
  609. }
  610. private void RespondToMessage(ObjectPlacementModeWasChangedMessage message)
  611. {
  612. BlockObjectPlacement.CancelManualBlockConstruction();
  613. PathObjectPlacement.CancelManualPathConstruction();
  614. }
  615. private void RespondToMessage(UndoRedoWasPerformedMessage message)
  616. {
  617. if (ShouldPlacementGuideBeDestroyed()) DestroyPlacementGuide();
  618. if (Settings.ObjectPlacementMode != ObjectPlacementMode.Block) BlockObjectPlacement.CancelManualBlockConstruction();
  619. if (Settings.ObjectPlacementMode != ObjectPlacementMode.Path) PathObjectPlacement.CancelManualPathConstruction();
  620. if(Settings.ObjectPlacementMode != ObjectPlacementMode.DecorPaint) ObjectSnapping.Get().RefreshSnapSurface();
  621. UpdateGuideProjectedPivotPoints();
  622. if (BlockObjectPlacement.IsBlockUnderManualConstruction || PathObjectPlacement.IsPathUnderManualConstruction) ObjectPlacementGuide.Active = false;
  623. }
  624. private void RespondToMessage(InspectorGUIWasChangedMessage message)
  625. {
  626. if (ShouldPlacementGuideBeDestroyed()) DestroyPlacementGuide();
  627. }
  628. private void RespondToMessage(ObjectHierarchyRootsWerePlacedInSceneMessage message)
  629. {
  630. List<GameObject> placedObjects = message.PlacedRoots;
  631. if(placedObjects != null && placedObjects.Count != 0)
  632. {
  633. if (message.ObjectPlacementType == ObjectHierarchyRootsWerePlacedInSceneMessage.PlacementType.ObjectPlacement)
  634. {
  635. // Assign objects to custom layer if necessary
  636. if (!Settings.SpawnInPrefabLayer)
  637. {
  638. foreach(var parent in placedObjects)
  639. {
  640. parent.SetHierarchyLayer(Settings.CustomSpawnLayer, true);
  641. }
  642. }
  643. // Mirror placed objects
  644. List<GameObject> mirroredObjects = Mirror.MirrorGameObjectHierarchies(placedObjects);
  645. placedObjects.AddRange(mirroredObjects);
  646. }
  647. // Check if the objects need to be attached to the active group. If not,
  648. // check if they must be attached as children of the currently hovered object.
  649. if (CanAttachPlacedRootsToObjectGroup(message.ObjectPlacementType))
  650. {
  651. if(message.ObjectPlacementType == ObjectHierarchyRootsWerePlacedInSceneMessage.PlacementType.Selection &&
  652. ObjectSelection.Get().Settings.ObjectGroupSettings.DestinationGroup != null)
  653. {
  654. GameObject selectionObjectGroup = ObjectSelection.Get().Settings.ObjectGroupSettings.DestinationGroup.GroupObject;
  655. if (selectionObjectGroup != null) selectionObjectGroup.AttachChildren(placedObjects, true);
  656. }
  657. else
  658. {
  659. if (Settings.UseActivePrefabCategoryGroup)
  660. {
  661. GameObject categoryGroupParent = PrefabCategoryDatabase.Get().ActivePrefabCategory.ObjectGroup.GroupObject;
  662. categoryGroupParent.AttachChildren(placedObjects, true);
  663. }
  664. else
  665. {
  666. GameObject activeGroupParent = GetActiveObjectGroup().GroupObject;
  667. activeGroupParent.AttachChildren(placedObjects, true);
  668. }
  669. }
  670. }
  671. else
  672. if (CanAttachPlacedRootsAsChildrenOfHoveredObject(message.ObjectPlacementType))
  673. {
  674. GameObject surfaceObject = ObjectPlacementSurfaceInfo.GetSurfaceObject();
  675. surfaceObject.AttachChildren(placedObjects, true);
  676. }
  677. }
  678. }
  679. private void RespondToMessage(ObjectPlacementGuideWasInstantiatedMessage message)
  680. {
  681. // Note: Only handle this in case the focus is on the Scene View window. On a couple of
  682. // occasions exceptions were thrown regarding the 'GUIPointToWorldRay' function.
  683. if (SceneViewExtensions.IsSceneViewWindowFocused())
  684. {
  685. UpdateGuideProjectedPivotPoints();
  686. AdjustPlacementGuidePositionOnCurrentPlacementSurface();
  687. }
  688. }
  689. private void RespondToMessage(ToolWasResetMessage message)
  690. {
  691. DestroyPlacementGuide();
  692. }
  693. #endregion
  694. #region Private Methods
  695. private void OnEnable()
  696. {
  697. MessageListenerRegistration.PerformRegistrationForObjectPlacementModule(this);
  698. }
  699. private ObjectGroup GetActiveObjectGroup()
  700. {
  701. return Octave3DWorldBuilder.ActiveInstance.PlacementObjectGroupDatabase.ActiveGroup;
  702. }
  703. private bool CanPickPrefabFromScene()
  704. {
  705. return !PathObjectPlacement.IsPathUnderManualConstruction && !BlockObjectPlacement.IsBlockUnderManualConstruction;
  706. }
  707. private bool CanAttachPlacedRootsAsChildrenOfHoveredObject(ObjectHierarchyRootsWerePlacedInSceneMessage.PlacementType objectPlacementType)
  708. {
  709. if (objectPlacementType == ObjectHierarchyRootsWerePlacedInSceneMessage.PlacementType.Selection) return false;
  710. GameObject surfaceObject = ObjectPlacementSurfaceInfo.GetSurfaceObject();
  711. return Settings.MakePlacedObjectsChildrenOfHoveredObject && surfaceObject != null && Octave3DWorldBuilder.ActiveInstance.IsWorkingObject(surfaceObject);
  712. }
  713. private bool CanAttachPlacedRootsToObjectGroup(ObjectHierarchyRootsWerePlacedInSceneMessage.PlacementType objectPlacementType)
  714. {
  715. if(objectPlacementType == ObjectHierarchyRootsWerePlacedInSceneMessage.PlacementType.ObjectPlacement)
  716. {
  717. if(Settings.UseActivePrefabCategoryGroup)
  718. {
  719. PrefabCategory activePrefabCategory = PrefabCategoryDatabase.Get().ActivePrefabCategory;
  720. ObjectGroup categoryGroup = activePrefabCategory.ObjectGroup;
  721. if (categoryGroup == null || categoryGroup.GroupObject == null) return false;
  722. }
  723. else
  724. {
  725. ObjectGroup activeObjectGroup = GetActiveObjectGroup();
  726. if (activeObjectGroup == null || activeObjectGroup.GroupObject == null) return false;
  727. }
  728. }
  729. else
  730. {
  731. ObjectGroup activeObjectGroup = GetActiveObjectGroup();
  732. if (activeObjectGroup == null || activeObjectGroup.GroupObject == null) return false;
  733. }
  734. if (objectPlacementType == ObjectHierarchyRootsWerePlacedInSceneMessage.PlacementType.Selection)
  735. return ObjectSelection.Get().Settings.ObjectGroupSettings.AttachToObjectGroup;
  736. return Settings.AttachPlacedObjectsToObjectGroup;
  737. }
  738. private bool DoesCurrentPlacementModeRequireSnapping()
  739. {
  740. return ObjectPlacementMode != O3DWB.ObjectPlacementMode.DecorPaint;
  741. }
  742. private bool ShouldPlacementGuideBeDestroyed()
  743. {
  744. return Inspector.Get().ActiveInspectorGUIIdentifier != InspectorGUIIdentifier.ObjectPlacement &&
  745. Inspector.Get().ActiveInspectorGUIIdentifier != InspectorGUIIdentifier.ObjectSnapping;
  746. }
  747. private bool PrefabActivationValidationCallback(Prefab prefabToActivate)
  748. {
  749. if (UserWantsToPlaceTileConnections)
  750. {
  751. ObjectPlacementPathTileConnectionSettings tileConnectionSettings = PathObjectPlacement.PathSettings.TileConnectionSettings;
  752. ObjectPlacementPathTileConnectionTypeSettings beginTileConnectionSettings = tileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Begin);
  753. if (beginTileConnectionSettings.Prefab != prefabToActivate) return false;
  754. }
  755. /*if (Octave3DWorldBuilder.Instance.Inspector.ActiveInspectorGUIIdentifier != InspectorGUIIdentifier.ObjectPlacement &&
  756. Octave3DWorldBuilder.Instance.Inspector.ActiveInspectorGUIIdentifier != InspectorGUIIdentifier.ObjectSnapping) return false;*/
  757. return true;
  758. }
  759. private void PrepareForPlacementGuideDestruction()
  760. {
  761. BlockObjectPlacement.CancelManualBlockConstruction();
  762. PathObjectPlacement.CancelManualPathConstruction();
  763. }
  764. private void UpdatePlacementGuideSessions(Event e)
  765. {
  766. if(ObjectPlacementGuide.ExistsInSceneAndIsActive)
  767. {
  768. ObjectPlacementGuide guide = ObjectPlacementGuide.Instance;
  769. if (CanBeginGuideMouseScaleSession()) guide.BeginMouseScaleSession(CalculateGuideScalePivotPoint());
  770. if (CanBeginGuideMouseRotationSession()) BeginGuideMouseRotationSession();
  771. if (CanBeginOffsetGuideFromPlacementSession()) guide.BeginMouseMoveAlongDirectionSession(ObjectPlacementSurfaceInfo.GetSurfaceNormal());
  772. CancelPlacementGuideSessionsIfNecessary();
  773. guide.UpdateActiveMouseSessionsForMouseMovement(e);
  774. UpdateGuideProjectedPivotPoints(true);
  775. }
  776. }
  777. private void CancelPlacementGuideSessionsIfNecessary()
  778. {
  779. if (ObjectPlacementGuide.ExistsInScene)
  780. {
  781. ObjectPlacementGuide guide = ObjectPlacementGuide.Instance;
  782. if (MustEndGuideMouseScaleSession()) guide.EndMouseScaleSession();
  783. if (MustEndGuideMouseRotationSession()) guide.EndMouseRotationSession();
  784. if (MustEndOffsetGuideFromPlacementSession()) guide.EndMouseMoveAlongDirectionSession();
  785. }
  786. }
  787. private bool CanBeginGuideMouseRotationSession()
  788. {
  789. if (!ObjectPlacementGuide.ExistsInSceneAndIsActive) return false;
  790. if (PathObjectPlacement.IsPathUnderManualConstruction) return false;
  791. if (BlockObjectPlacement.IsBlockUnderManualConstruction) return false;
  792. if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint && DecorPaintObjectPlacement.DecorPaintMode == DecorPaintMode.Brush) return false;
  793. if (DecorPaintObjectPlacement.IsStroking) return false;
  794. if (ObjectPlacementGuide.Instance.IsAnyMouseSessionActive) return false;
  795. return true;
  796. }
  797. private void BeginGuideMouseRotationSession()
  798. {
  799. ObjectPlacementGuide guide = ObjectPlacementGuide.Instance;
  800. if (AllShortcutCombos.Instance.MouseRotatePlacementGuideAroundPlacementSurfaceNormal.IsActive())
  801. guide.BeginMouseRotationSession(ObjectPlacementSurfaceInfo.GetSurfaceNormal());
  802. else
  803. if (AllShortcutCombos.Instance.MouseRotatePlacementGuideAroundX.IsActive())
  804. guide.BeginMouseRotationSession(TransformAxis.X);
  805. else
  806. if (AllShortcutCombos.Instance.MouseRotatePlacementGuideAroundY.IsActive())
  807. guide.BeginMouseRotationSession(TransformAxis.Y);
  808. else
  809. if (AllShortcutCombos.Instance.MouseRotatePlacementGuideAroundZ.IsActive())
  810. guide.BeginMouseRotationSession(TransformAxis.Z);
  811. }
  812. private bool MustEndGuideMouseRotationSession()
  813. {
  814. if (_pathObjectPlacement.IsPathUnderManualConstruction || _blockObjectPlacement.IsBlockUnderManualConstruction) return true;
  815. ObjectPlacementGuide guide = ObjectPlacementGuide.Instance;
  816. if (guide.IsMouseRotationSessionForCustomAxis)
  817. {
  818. if(!AllShortcutCombos.Instance.MouseRotatePlacementGuideAroundPlacementSurfaceNormal.IsActive()) return true;
  819. }
  820. else
  821. {
  822. if (guide.MouseRotationSessionAxis == TransformAxis.X && !AllShortcutCombos.Instance.MouseRotatePlacementGuideAroundX.IsActive()) return true;
  823. if (guide.MouseRotationSessionAxis == TransformAxis.Y && !AllShortcutCombos.Instance.MouseRotatePlacementGuideAroundY.IsActive()) return true;
  824. if (guide.MouseRotationSessionAxis == TransformAxis.Z && !AllShortcutCombos.Instance.MouseRotatePlacementGuideAroundZ.IsActive()) return true;
  825. }
  826. return false;
  827. }
  828. private bool CanBeginGuideMouseScaleSession()
  829. {
  830. if (UserWantsToPlaceTileConnections) return false;
  831. if (!ObjectPlacementGuide.ExistsInSceneAndIsActive) return false;
  832. if (PathObjectPlacement.IsPathUnderManualConstruction) return false;
  833. if (BlockObjectPlacement.IsBlockUnderManualConstruction) return false;
  834. if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint && DecorPaintObjectPlacement.DecorPaintMode == DecorPaintMode.Brush) return false;
  835. if (DecorPaintObjectPlacement.IsStroking) return false;
  836. if (ObjectPlacementGuide.Instance.IsAnyMouseSessionActive) return false;
  837. return AllShortcutCombos.Instance.MousePlacementGuideUniformScale.IsActive();
  838. }
  839. private bool MustEndGuideMouseScaleSession()
  840. {
  841. return _pathObjectPlacement.IsPathUnderManualConstruction ||
  842. _blockObjectPlacement.IsBlockUnderManualConstruction ||
  843. !AllShortcutCombos.Instance.MousePlacementGuideUniformScale.IsActive();
  844. }
  845. private bool RotatePlacementGuideWithKeyboardIfNecessary()
  846. {
  847. if (!CanPlacementGuideBeRotatedWithKeyboard()) return false;
  848. ObjectPlacementGuide objectPlacementGuide = ObjectPlacementGuide.Instance;
  849. AllShortcutCombos allShortcutCombos = AllShortcutCombos.Instance;
  850. bool wasRotated = false;
  851. if (allShortcutCombos.KeyboardRotatePlacementGuideAroundX.IsActive())
  852. {
  853. objectPlacementGuide.RotateUsingKeyboardSettings(TransformAxis.X);
  854. wasRotated = true;
  855. }
  856. if (allShortcutCombos.KeyboardRotatePlacementGuideAroundY.IsActive())
  857. {
  858. objectPlacementGuide.RotateUsingKeyboardSettings(TransformAxis.Y);
  859. wasRotated = true;
  860. }
  861. if (allShortcutCombos.KeyboardRotatePlacementGuideAroundZ.IsActive())
  862. {
  863. objectPlacementGuide.RotateUsingKeyboardSettings(TransformAxis.Z);
  864. wasRotated = true;
  865. }
  866. if (allShortcutCombos.KeyboardRotatePlacementGuideAroundPlacementSurfaceNormal.IsActive())
  867. {
  868. objectPlacementGuide.RotateUsingKeyboardSettings(ObjectPlacementSurfaceInfo.GetSurfaceNormal());
  869. wasRotated = true;
  870. }
  871. if (wasRotated) UpdateGuideProjectedPivotPoints();
  872. return wasRotated;
  873. }
  874. private bool CanActivateObjectVertexSnapSession()
  875. {
  876. return !PathObjectPlacement.IsPathUnderManualConstruction && !BlockObjectPlacement.IsBlockUnderManualConstruction &&
  877. !Mirror.IsInteractionSessionActive && !(DecorPaintObjectPlacement.IsStroking);
  878. }
  879. private bool CanPlacementGuideBeRotatedWithKeyboard()
  880. {
  881. if (!ObjectPlacementGuide.ExistsInSceneAndIsActive) return false;
  882. if (PathObjectPlacement.IsPathUnderManualConstruction) return false;
  883. if (BlockObjectPlacement.IsBlockUnderManualConstruction) return false;
  884. if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint && DecorPaintObjectPlacement.DecorPaintMode == DecorPaintMode.Brush) return false;
  885. if (DecorPaintObjectPlacement.IsStroking) return false;
  886. return !ObjectPlacementGuide.Instance.IsAnyMouseSessionActive;
  887. }
  888. private bool CanBeginOffsetGuideFromPlacementSession()
  889. {
  890. if (!ObjectPlacementGuide.ExistsInSceneAndIsActive) return false;
  891. if (PathObjectPlacement.IsPathUnderManualConstruction) return false;
  892. if (BlockObjectPlacement.IsBlockUnderManualConstruction) return false;
  893. if (ObjectPlacementMode == ObjectPlacementMode.DecorPaint && DecorPaintObjectPlacement.DecorPaintMode == DecorPaintMode.Brush) return false;
  894. if (DecorPaintObjectPlacement.IsStroking) return false;
  895. if (ObjectPlacementGuide.Instance.IsAnyMouseSessionActive) return false;
  896. return AllShortcutCombos.Instance.OffsetGuideFromPlacementSurface.IsActive();
  897. }
  898. private bool MustEndOffsetGuideFromPlacementSession()
  899. {
  900. return _pathObjectPlacement.IsPathUnderManualConstruction ||
  901. _blockObjectPlacement.IsBlockUnderManualConstruction ||
  902. !AllShortcutCombos.Instance.OffsetGuideFromPlacementSurface.IsActive();
  903. }
  904. private bool CanGuideBeActive()
  905. {
  906. if (AllShortcutCombos.Instance.SnapXZGridToCursorPickPointOnLeftClick_Placement.IsActive()) return false;
  907. if (IsConstructingPath()) return false;
  908. if (IsConstructingBlock()) return false;
  909. return true;
  910. }
  911. private bool IsConstructingPath()
  912. {
  913. return ObjectPlacementMode == ObjectPlacementMode.Path && PathObjectPlacement.IsPathUnderManualConstruction;
  914. }
  915. private bool IsConstructingBlock()
  916. {
  917. return ObjectPlacementMode == ObjectPlacementMode.Block && BlockObjectPlacement.IsBlockUnderManualConstruction;
  918. }
  919. private void UpdateGuideProjectedPivotPoints(bool keepPlacementSurface = false)
  920. {
  921. if(ObjectPlacementGuide.ExistsInScene)
  922. {
  923. if (ObjectPlacementMode != ObjectPlacementMode.DecorPaint) ObjectSnapping.Get().UpdateProjectedBoxFacePivotPoints(ObjectPlacementGuide.SceneObject, _projectedGuidePivotPoints, keepPlacementSurface);
  924. else DecorPaintObjectPlacement.UpdateGuidePivotPoints();
  925. }
  926. }
  927. private Vector3 CalculateGuideScalePivotPoint()
  928. {
  929. Plane pivotSurfacePlane = new Plane(ObjectPlacementSurfaceInfo.GetSurfaceNormal(), _projectedGuidePivotPoints.ActivePoint);
  930. return pivotSurfacePlane.ProjectPoint(ObjectPlacementGuide.SceneObject.GetHierarchyWorldOrientedBox().Center);
  931. }
  932. private void RenderGizmosForDecorPaintMode()
  933. {
  934. ObjectSnapping.Get().XZSnapGrid.RenderGizmos();
  935. if(Settings.DecorPaintObjectPlacementSettings.DecorPaintMode == DecorPaintMode.Single) _guidePivotPointsRenderer.RenderGizmos(_projectedGuidePivotPoints, GuidePivotPointsRenderSettings);
  936. DecorPaintObjectPlacement.RenderGizmos();
  937. }
  938. private void RenderGizmosForNonDecorPaintMode()
  939. {
  940. if(!_objectVertexSnapSession.IsActive && !AllShortcutCombos.Instance.SnapXZGridToCursorPickPointOnLeftClick_Placement.IsActive())
  941. {
  942. ObjectSnapping.Get().RenderGizmos();
  943. if (!ObjectSnapping.Get().Settings.UseOriginalPivot) _guidePivotPointsRenderer.RenderGizmos(_projectedGuidePivotPoints, GuidePivotPointsRenderSettings);
  944. else
  945. if(ObjectPlacementGuide.ExistsInSceneAndIsActive)
  946. {
  947. // Note: Just us the projected pivot points settings for rendering the object pivot
  948. Camera camera = SceneViewCamera.Camera;
  949. Vector2 screenPoint = Vector3Extensions.WorldToScreenPoint(ObjectPlacementGuide.Instance.transform.position);
  950. Circle2D circle = new Circle2D(screenPoint, GuidePivotPointsRenderSettings.PivotPointSizeInPixels * 0.5f);
  951. GizmosEx.Render2DFilledCircle(circle, GuidePivotPointsRenderSettings.ProjectedBoxFacePivotPointsRenderSettings.ActivePivotPointRenderSettings.FillColor);
  952. GizmosEx.Render2DCircleBorderLines(circle, GuidePivotPointsRenderSettings.ProjectedBoxFacePivotPointsRenderSettings.ActivePivotPointRenderSettings.BorderLineColor);
  953. }
  954. if (Settings.ObjectPlacementMode == ObjectPlacementMode.Path) _pathObjectPlacement.RenderGizmos();
  955. else if (Settings.ObjectPlacementMode == ObjectPlacementMode.Block) _blockObjectPlacement.RenderGizmos();
  956. }
  957. else
  958. {
  959. ObjectSnapping.Get().XZSnapGrid.RenderGizmos();
  960. }
  961. }
  962. private void AdjustPlacementGuidePositionOnCurrentPlacementSurface()
  963. {
  964. if (DoesCurrentPlacementModeRequireSnapping()) ObjectPlacementGuide.Instance.Snap();
  965. else ObjectPlacementGuide.Instance.SetWorldPosition(DecorPaintObjectPlacement.CalculatePlacementGuidePosition());
  966. UpdateGuideProjectedPivotPoints();
  967. }
  968. #endregion
  969. }
  970. }
  971. #endif