PageRenderTime 80ms CodeModel.GetById 55ms RepoModel.GetById 0ms app.codeStats 1ms

/Library/PackageCache/com.unity.render-pipelines.core@7.5.3/Editor/LookDev/Stage.cs

https://gitlab.com/hieplv.amgame/c0lor-blocks
C# | 368 lines | 238 code | 53 blank | 77 comment | 24 complexity | ef9795462fed29233f6898c0aea3ea78 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEditor.SceneManagement;
  4. using UnityEngine;
  5. using UnityEngine.SceneManagement;
  6. using UnityEngine.Rendering.LookDev;
  7. namespace UnityEditor.Rendering.LookDev
  8. {
  9. //TODO: add undo support
  10. /// <summary>
  11. /// Class handling object of the scene with isolation from other scene based on culling
  12. /// </summary>
  13. class Stage : IDisposable
  14. {
  15. const int k_PreviewCullingLayerIndex = 31; //Camera.PreviewCullingLayer; //TODO: expose or reflection
  16. private readonly Scene m_PreviewScene;
  17. // Everything except camera
  18. private readonly List<GameObject> m_GameObjects = new List<GameObject>();
  19. private readonly List<GameObject> m_PersistentGameObjects = new List<GameObject>();
  20. private readonly Camera m_Camera;
  21. private readonly Light m_SunLight;
  22. /// <summary>Get access to the stage's camera</summary>
  23. public Camera camera => m_Camera;
  24. /// <summary>Get access to the stage's light</summary>
  25. public Light sunLight => m_SunLight;
  26. /// <summary>Get access to the stage's scene</summary>
  27. public Scene scene => m_PreviewScene;
  28. private StageRuntimeInterface SRI;
  29. /// <summary>The runtime interface on stage</summary>
  30. public StageRuntimeInterface runtimeInterface
  31. => SRI ?? (SRI = new StageRuntimeInterface(
  32. CreateGameObjectIntoStage,
  33. () => camera,
  34. () => sunLight));
  35. /// <summary>
  36. /// Construct a new stage to let your object live.
  37. /// A stage is a scene with visibility isolation.
  38. /// </summary>
  39. /// <param name="sceneName">Name of the scene used.</param>
  40. public Stage(string sceneName)
  41. {
  42. if (string.IsNullOrEmpty(sceneName))
  43. throw new System.ArgumentNullException("sceneName");
  44. m_PreviewScene = EditorSceneManager.NewPreviewScene();
  45. m_PreviewScene.name = sceneName;
  46. var camGO = EditorUtility.CreateGameObjectWithHideFlags("Look Dev Camera", HideFlags.HideAndDontSave, typeof(Camera));
  47. MoveIntoStage(camGO, true); //position will be updated right before rendering
  48. camGO.layer = k_PreviewCullingLayerIndex;
  49. m_Camera = camGO.GetComponent<Camera>();
  50. m_Camera.cameraType = CameraType.Game; //cannot be preview in HDRP: too many things skiped
  51. m_Camera.enabled = false;
  52. m_Camera.clearFlags = CameraClearFlags.Depth;
  53. m_Camera.cullingMask = 1 << k_PreviewCullingLayerIndex;
  54. m_Camera.renderingPath = RenderingPath.DeferredShading;
  55. m_Camera.useOcclusionCulling = false;
  56. m_Camera.scene = m_PreviewScene;
  57. var lightGO = EditorUtility.CreateGameObjectWithHideFlags("Look Dev Sun", HideFlags.HideAndDontSave, typeof(Light));
  58. MoveIntoStage(lightGO, true); //position will be updated right before rendering
  59. m_SunLight = lightGO.GetComponent<Light>();
  60. m_SunLight.type = LightType.Directional;
  61. m_SunLight.shadows = LightShadows.Soft;
  62. m_SunLight.intensity = 0f;
  63. }
  64. /// <summary>
  65. /// Move a GameObject into the stage's scene at origin.
  66. /// </summary>
  67. /// <param name="gameObject">The gameObject to move.</param>
  68. /// <param name="persistent">
  69. /// [OPTIONAL] If true, the object is not recreated with the scene update.
  70. /// Default value: false.
  71. /// </param>
  72. /// <seealso cref="InstantiateIntoStage"/>
  73. public void MoveIntoStage(GameObject gameObject, bool persistent = false)
  74. => MoveIntoStage(gameObject, Vector3.zero, gameObject.transform.rotation, persistent);
  75. /// <summary>
  76. /// Move a GameObject into the stage's scene at specific position and
  77. /// rotation.
  78. /// </summary>
  79. /// <param name="gameObject">The gameObject to move.</param>
  80. /// <param name="position">The new world position</param>
  81. /// <param name="rotation">The new world rotation</param>
  82. /// <param name="persistent">
  83. /// [OPTIONAL] If true, the object is not recreated with the scene update.
  84. /// Default value: false.
  85. /// </param>
  86. /// <seealso cref="InstantiateIntoStage"/>
  87. public void MoveIntoStage(GameObject gameObject, Vector3 position, Quaternion rotation, bool persistent = false)
  88. {
  89. if (m_GameObjects.Contains(gameObject))
  90. return;
  91. SceneManager.MoveGameObjectToScene(gameObject, m_PreviewScene);
  92. gameObject.transform.position = position;
  93. gameObject.transform.rotation = rotation;
  94. if (persistent)
  95. m_PersistentGameObjects.Add(gameObject);
  96. else
  97. m_GameObjects.Add(gameObject);
  98. InitAddedObjectsRecursively(gameObject);
  99. }
  100. /// <summary>
  101. /// Instantiate a scene GameObject or a prefab into the stage's scene.
  102. /// It is instantiated at origin.
  103. /// </summary>
  104. /// <param name="prefabOrSceneObject">The element to instantiate</param>
  105. /// <param name="persistent">
  106. /// [OPTIONAL] If true, the object is not recreated with the scene update.
  107. /// Default value: false.
  108. /// </param>
  109. /// <returns>The instance</returns>
  110. /// <seealso cref="MoveIntoStage"/>
  111. public GameObject InstantiateIntoStage(GameObject prefabOrSceneObject, bool persistent = false)
  112. => InstantiateIntoStage(prefabOrSceneObject, Vector3.zero, prefabOrSceneObject.transform.rotation, persistent);
  113. /// <summary>
  114. /// Instantiate a scene GameObject or a prefab into the stage's scene
  115. /// at a specific position and rotation.
  116. /// </summary>
  117. /// <param name="prefabOrSceneObject">The element to instantiate</param>
  118. /// <param name="position">The new world position</param>
  119. /// <param name="rotation">The new world rotation</param>
  120. /// <param name="persistent">
  121. /// [OPTIONAL] If true, the object is not recreated with the scene update.
  122. /// Default value: false.
  123. /// </param>
  124. /// <returns>The instance</returns>
  125. /// <seealso cref="MoveIntoStage"/>
  126. public GameObject InstantiateIntoStage(GameObject prefabOrSceneObject, Vector3 position, Quaternion rotation, bool persistent = false)
  127. {
  128. var handle = GameObject.Instantiate(prefabOrSceneObject);
  129. MoveIntoStage(handle, position, rotation, persistent);
  130. return handle;
  131. }
  132. /// <summary>Create a GameObject into the stage.</summary>
  133. /// <param name="persistent">
  134. /// [OPTIONAL] If true, the object is not recreated with the scene update.
  135. /// Default value: false.
  136. /// </param>
  137. /// <returns>The created GameObject</returns>
  138. public GameObject CreateGameObjectIntoStage(bool persistent = false)
  139. {
  140. var handle = new GameObject();
  141. MoveIntoStage(handle, persistent);
  142. return handle;
  143. }
  144. /// <summary>Clear all scene object except camera.</summary>
  145. /// <param name="persistent">
  146. /// [OPTIONAL] If true, clears also persistent objects.
  147. /// Default value: false.
  148. /// </param>
  149. public void Clear(bool persistent = false)
  150. {
  151. foreach (var go in m_GameObjects)
  152. UnityEngine.Object.DestroyImmediate(go);
  153. m_GameObjects.Clear();
  154. if (persistent)
  155. {
  156. foreach (var go in m_PersistentGameObjects)
  157. UnityEngine.Object.DestroyImmediate(go);
  158. m_PersistentGameObjects.Clear();
  159. }
  160. }
  161. static void InitAddedObjectsRecursively(GameObject go)
  162. {
  163. go.hideFlags = HideFlags.HideAndDontSave;
  164. go.layer = k_PreviewCullingLayerIndex;
  165. var meshRenderer = go.GetComponent<MeshRenderer>();
  166. if (meshRenderer != null)
  167. meshRenderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off;
  168. var skinnedMeshRenderer = go.GetComponent<SkinnedMeshRenderer>();
  169. if (skinnedMeshRenderer != null)
  170. skinnedMeshRenderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off;
  171. var lineRenderer = go.GetComponent<LineRenderer>();
  172. if (lineRenderer != null)
  173. lineRenderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off;
  174. var volumes = go.GetComponents<UnityEngine.Rendering.Volume>();
  175. foreach (var volume in volumes)
  176. volume.UpdateLayer(); //force update of layer now as the Update can be called after we unregister volume from manager
  177. foreach (Transform child in go.transform)
  178. InitAddedObjectsRecursively(child.gameObject);
  179. }
  180. /// <summary>Changes stage scene's objects visibility.</summary>
  181. /// <param name="visible">
  182. /// True: make them visible.
  183. /// False: hide them.
  184. /// </param>
  185. void SetGameObjectVisible(bool visible)
  186. {
  187. foreach (GameObject go in m_GameObjects)
  188. {
  189. if (go == null || go.Equals(null))
  190. continue;
  191. foreach (UnityEngine.Renderer renderer in go.GetComponentsInChildren<UnityEngine.Renderer>())
  192. renderer.enabled = visible;
  193. foreach (Light light in go.GetComponentsInChildren<Light>())
  194. light.enabled = visible;
  195. }
  196. // in case we add camera frontal light and such
  197. foreach (UnityEngine.Renderer renderer in m_Camera.GetComponentsInChildren<UnityEngine.Renderer>())
  198. renderer.enabled = visible;
  199. foreach (Light light in m_Camera.GetComponentsInChildren<Light>())
  200. light.enabled = visible;
  201. }
  202. public void OnBeginRendering(IDataProvider dataProvider)
  203. {
  204. SetGameObjectVisible(true);
  205. dataProvider.OnBeginRendering(runtimeInterface);
  206. }
  207. public void OnEndRendering(IDataProvider dataProvider)
  208. {
  209. SetGameObjectVisible(false);
  210. dataProvider.OnEndRendering(runtimeInterface);
  211. }
  212. private bool disposedValue = false; // To detect redundant calls
  213. void CleanUp()
  214. {
  215. if (!disposedValue)
  216. {
  217. if (SRI != null)
  218. SRI.SRPData = null;
  219. SRI = null;
  220. EditorSceneManager.ClosePreviewScene(m_PreviewScene);
  221. disposedValue = true;
  222. }
  223. }
  224. ~Stage() => CleanUp();
  225. /// <summary>Clear and close the stage's scene.</summary>
  226. public void Dispose()
  227. {
  228. CleanUp();
  229. GC.SuppressFinalize(this);
  230. }
  231. }
  232. class StageCache : IDisposable
  233. {
  234. const string firstStageName = "LookDevFirstView";
  235. const string secondStageName = "LookDevSecondView";
  236. Stage[] m_Stages;
  237. Context m_Contexts;
  238. IDataProvider m_CurrentDataProvider;
  239. public Stage this[ViewIndex index]
  240. => m_Stages[(int)index];
  241. public bool initialized { get; private set; }
  242. public StageCache(IDataProvider dataProvider, Context contexts)
  243. {
  244. m_Contexts = contexts;
  245. m_Stages = new Stage[2]
  246. {
  247. InitStage(ViewIndex.First, dataProvider),
  248. InitStage(ViewIndex.Second, dataProvider)
  249. };
  250. initialized = true;
  251. }
  252. Stage InitStage(ViewIndex index, IDataProvider dataProvider)
  253. {
  254. Stage stage;
  255. switch (index)
  256. {
  257. case ViewIndex.First:
  258. stage = new Stage(firstStageName);
  259. stage.camera.backgroundColor = new Color32(5, 5, 5, 255);
  260. stage.camera.name += "_1";
  261. break;
  262. case ViewIndex.Second:
  263. stage = new Stage(secondStageName);
  264. stage.camera.backgroundColor = new Color32(5, 5, 5, 255);
  265. stage.camera.name += "_2";
  266. break;
  267. default:
  268. throw new ArgumentException("Unknown ViewIndex: " + index);
  269. }
  270. dataProvider.FirstInitScene(stage.runtimeInterface);
  271. m_CurrentDataProvider = dataProvider;
  272. return stage;
  273. }
  274. public void UpdateSceneObjects(ViewIndex index)
  275. {
  276. Stage stage = this[index];
  277. stage.Clear();
  278. var viewContent = m_Contexts.GetViewContent(index);
  279. if (viewContent == null)
  280. {
  281. viewContent.viewedInstanceInPreview = null;
  282. return;
  283. }
  284. if (viewContent.viewedObjectReference != null && !viewContent.viewedObjectReference.Equals(null))
  285. viewContent.viewedInstanceInPreview = stage.InstantiateIntoStage(viewContent.viewedObjectReference);
  286. }
  287. public void UpdateSceneLighting(ViewIndex index, IDataProvider provider)
  288. {
  289. Stage stage = this[index];
  290. Environment environment = m_Contexts.GetViewContent(index).environment;
  291. provider.UpdateSky(stage.camera,
  292. environment == null ? default : environment.sky,
  293. stage.runtimeInterface);
  294. }
  295. private bool disposedValue = false; // To detect redundant calls
  296. void CleanUp()
  297. {
  298. if (!disposedValue)
  299. {
  300. foreach (Stage stage in m_Stages)
  301. {
  302. m_CurrentDataProvider.Cleanup(stage.runtimeInterface);
  303. stage.Dispose();
  304. }
  305. disposedValue = true;
  306. }
  307. }
  308. ~StageCache() => CleanUp();
  309. public void Dispose()
  310. {
  311. CleanUp();
  312. GC.SuppressFinalize(this);
  313. }
  314. }
  315. }