Octave3DScene.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System;
  5. using System.Collections.Generic;
  6. namespace O3DWB
  7. {
  8. [Serializable]
  9. public class Octave3DScene : IMessageListener
  10. {
  11. #region Private Variables
  12. [SerializeField]
  13. private GameObjectSphereTree _gameObjectSphereTree = new GameObjectSphereTree(2);
  14. [SerializeField]
  15. private Octave3DMeshDatabase _octave3DMeshDatabase = new Octave3DMeshDatabase();
  16. private HashSet<Light> _sceneLights = new HashSet<Light>();
  17. #endregion
  18. #region Public Static Properties
  19. public static Vector3 VolumeSizeForNonMeshObjects { get { return Vector3.one; } }
  20. #endregion
  21. #region Public Properties
  22. public Octave3DMeshDatabase Octave3DMeshDatabase { get { return _octave3DMeshDatabase; } }
  23. #endregion
  24. #region Constructors
  25. public Octave3DScene()
  26. {
  27. MessageListenerRegistration.PerformRegistrationForOctave3DScene(this);
  28. // Note: Needed when erasing objects and then Undo. If this step is not performed,
  29. // then when the erase operation is undone, the restored objects will not
  30. // be registered with the tree.
  31. Undo.undoRedoPerformed -= RegisterUnregisteredObjects;
  32. Undo.undoRedoPerformed += RegisterUnregisteredObjects;
  33. }
  34. #endregion
  35. #region Public Static Functions
  36. public static Octave3DScene Get()
  37. {
  38. return Octave3DWorldBuilder.ActiveInstance.Octave3DScene;
  39. }
  40. #endregion
  41. #region Public Methods
  42. public void RegisterSceneLight(Light light)
  43. {
  44. _sceneLights.Add(light);
  45. }
  46. public List<Light> GetSceneLights()
  47. {
  48. var lights = new List<Light>(_sceneLights);
  49. lights.RemoveAll(item => item == null);
  50. return lights;
  51. }
  52. public Sphere GetEncapuslatingSphere()
  53. {
  54. return _gameObjectSphereTree.RootSphere;
  55. }
  56. public void RenderGizmosDebug()
  57. {
  58. _gameObjectSphereTree.RenderGizmosDebug();
  59. }
  60. public void Refresh(bool showProgress)
  61. {
  62. _gameObjectSphereTree.Rebuild(showProgress);
  63. }
  64. public void Update()
  65. {
  66. _gameObjectSphereTree.Update();
  67. }
  68. public void OnSceneGUI()
  69. {
  70. _gameObjectSphereTree.OnSceneGUI();
  71. }
  72. public List<GameObjectRayHit> RaycastAllBox(Ray ray)
  73. {
  74. return _gameObjectSphereTree.RaycastAllBox(ray);
  75. }
  76. public List<GameObjectRayHit> RaycastAllSprite(Ray ray)
  77. {
  78. return _gameObjectSphereTree.RaycastAllSprite(ray);
  79. }
  80. public List<GameObjectRayHit> RaycastAllMesh(Ray ray)
  81. {
  82. return _gameObjectSphereTree.RaycastAllMesh(ray);
  83. }
  84. public GameObjectRayHit RaycastAllMeshClosest(Ray ray)
  85. {
  86. var allHits = RaycastAllMesh(ray);
  87. if (allHits.Count == 0) return null;
  88. allHits.Sort(delegate(GameObjectRayHit h0, GameObjectRayHit h1)
  89. {
  90. return h0.HitEnter.CompareTo(h1.HitEnter);
  91. });
  92. return allHits[0];
  93. }
  94. public GameObjectRayHit RaycastAllTerainsClosest(Ray ray)
  95. {
  96. var terrainHits = new List<GameObjectRayHit>();
  97. RaycastHit[] rayHits = Physics.RaycastAll(ray);
  98. if (rayHits.Length != 0)
  99. {
  100. foreach (RaycastHit rayHit in rayHits)
  101. {
  102. if (rayHit.collider.GetType() == typeof(TerrainCollider))
  103. {
  104. var terrainRayHit = new TerrainRayHit(ray, rayHit);
  105. var gameObjectRayHit = new GameObjectRayHit(ray, rayHit.collider.gameObject, null, null, terrainRayHit, null);
  106. terrainHits.Add(gameObjectRayHit);
  107. }
  108. }
  109. }
  110. if (terrainHits.Count == 0) return null;
  111. terrainHits.Sort(delegate(GameObjectRayHit h0, GameObjectRayHit h1)
  112. {
  113. return h0.HitEnter.CompareTo(h1.HitEnter);
  114. });
  115. return terrainHits[0];
  116. }
  117. public List<GameObject> OverlapSphere(Sphere sphere)
  118. {
  119. return _gameObjectSphereTree.OverlapSphere(sphere);
  120. }
  121. public List<GameObject> OverlapBox(OrientedBox box)
  122. {
  123. return _gameObjectSphereTree.OverlapBox(box);
  124. }
  125. public List<GameObject> OverlapBox(Box box)
  126. {
  127. return _gameObjectSphereTree.OverlapBox(box);
  128. }
  129. public bool BoxIntersectsAnyObjectBoxes(OrientedBox box, List<GameObject> ignoreObjects, bool allowFaceTouch)
  130. {
  131. if (ignoreObjects == null) ignoreObjects = new List<GameObject>();
  132. return _gameObjectSphereTree.BoxIntersectsAnyObjectBoxes(box, new HashSet<GameObject>(ignoreObjects), allowFaceTouch);
  133. }
  134. public bool ObjectMeshIntersectsAnyMesh(GameObject queryMeshObject, TransformMatrix worldMatrix, List<GameObject> ignoreObjects)
  135. {
  136. if (ignoreObjects == null) ignoreObjects = new List<GameObject>();
  137. Octave3DMesh octave3DMesh = queryMeshObject.GetOctave3DMesh();
  138. if (octave3DMesh == null) return false;
  139. return _gameObjectSphereTree.ObjectMeshIntersectsAnyMesh(octave3DMesh, worldMatrix, new HashSet<GameObject>(ignoreObjects));
  140. }
  141. public bool ObjectMeshInHierarchyIntersectsAnyMesh(GameObject queryRoot, TransformMatrix rootWorldMatrix, List<GameObject> ignoreObjects)
  142. {
  143. List<GameObject> allChildrenAndSelf = queryRoot.GetAllChildrenIncludingSelf();
  144. foreach(var child in allChildrenAndSelf)
  145. {
  146. if(child == queryRoot)
  147. {
  148. if (ObjectMeshIntersectsAnyMesh(child, rootWorldMatrix, ignoreObjects)) return true;
  149. }
  150. else
  151. {
  152. Matrix4x4 relativeTransform = child.transform.GetRelativeTransformMatrix(rootWorldMatrix).ToMatrix4x4x;
  153. Matrix4x4 childWorldTransform = rootWorldMatrix.ToMatrix4x4x * relativeTransform;
  154. if (ObjectMeshIntersectsAnyMesh(child, new TransformMatrix(childWorldTransform), ignoreObjects)) return true;
  155. }
  156. }
  157. return false;
  158. }
  159. public List<GameObject> InstantiateObjectHirarchiesFromPlacementDataCollection(List<ObjectPlacementData> objectPlacementDataCollection)
  160. {
  161. if (objectPlacementDataCollection.Count == 0) return new List<GameObject>();
  162. var instantiatedHierarchyRoots = ObjectInstantiation.InstantiateObjectHirarchiesFromPlacementDataCollection(objectPlacementDataCollection);
  163. _gameObjectSphereTree.RegisterGameObjectHierarchies(instantiatedHierarchyRoots);
  164. return instantiatedHierarchyRoots;
  165. }
  166. public GameObject InstantiateObjectHierarchyFromPlacementData(ObjectPlacementData objectPlacementData)
  167. {
  168. GameObject instantiatedObject = ObjectInstantiation.InstantiateObjectHierarchyFromPlacementData(objectPlacementData);
  169. _gameObjectSphereTree.RegisterGameObjectHierarchy(instantiatedObject);
  170. return instantiatedObject;
  171. }
  172. public GameObject InstantiateObjectHierarchyFromPrefab(Prefab prefab, Transform transformData)
  173. {
  174. GameObject instantiatedObject = ObjectInstantiation.InstantiateObjectHierarchyFromPrefab(prefab, transformData.position, transformData.rotation, transformData.lossyScale);
  175. _gameObjectSphereTree.RegisterGameObjectHierarchy(instantiatedObject);
  176. return instantiatedObject;
  177. }
  178. public GameObject InstantiateObjectHierarchyFromPrefab(Prefab prefab, Vector3 worldPosition, Quaternion worldRotation, Vector3 worldScale)
  179. {
  180. GameObject instantiatedObject = ObjectInstantiation.InstantiateObjectHierarchyFromPrefab(prefab, worldPosition, worldRotation, worldScale);
  181. _gameObjectSphereTree.RegisterGameObjectHierarchy(instantiatedObject);
  182. return instantiatedObject;
  183. }
  184. public void RegisterObjectHierarchy(GameObject hierarchyRoot)
  185. {
  186. _gameObjectSphereTree.RegisterGameObjectHierarchy(hierarchyRoot);
  187. }
  188. public void RegisterObjectHierarchies(List<GameObject> roots)
  189. {
  190. foreach(var root in roots)
  191. {
  192. RegisterObjectHierarchy(root);
  193. }
  194. }
  195. public void RegisterObjectCollection(List<GameObject> gameObjects)
  196. {
  197. _gameObjectSphereTree.RegisterGameObjectCollection(gameObjects);
  198. }
  199. public void RegisterUnregisteredObjects()
  200. {
  201. _gameObjectSphereTree.RegisterUnregisteredObjects();
  202. }
  203. #endregion
  204. #region Message Handlers
  205. public void RespondToMessage(Message message)
  206. {
  207. switch(message.Type)
  208. {
  209. case MessageType.ToolWasReset:
  210. RespondToMessage(message as ToolWasResetMessage);
  211. break;
  212. case MessageType.ToolWasSelected:
  213. RespondToMessage(message as ToolWasSelectedMessage);
  214. break;
  215. }
  216. }
  217. private void RespondToMessage(ToolWasResetMessage message)
  218. {
  219. var allWorkingObjects = Octave3DWorldBuilder.ActiveInstance.GetAllWorkingObjects();
  220. RegisterObjectCollection(allWorkingObjects);
  221. }
  222. private void RespondToMessage(ToolWasSelectedMessage message)
  223. {
  224. // Note: It is possible that the user may have changed the transform of the
  225. // objects while the tool was deselected, so we need to ensure that the
  226. // tree is up to date.
  227. _gameObjectSphereTree.HandleTransformChangesForAllRegisteredObjects();
  228. // It may be possible that the user has added objects to the scene while the tool object
  229. // was deselected, so we will instruct the camera to update its visibility.
  230. SceneViewCamera.Instance.SetObjectVisibilityDirty();
  231. }
  232. #endregion
  233. }
  234. }
  235. #endif