MultiSceneExampleComponent.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. /*
  2. * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
  3. * its licensors.
  4. *
  5. * For complete copyright and license terms please see the LICENSE at the root of this
  6. * distribution (the "License"). All use of this software is governed by the License,
  7. * or, if provided, by the license below or the license accompanying this file. Do not
  8. * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
  9. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. *
  11. */
  12. #include <AtomSampleViewerOptions.h>
  13. #include <MultiSceneExampleComponent.h>
  14. #include <Atom/Component/DebugCamera/CameraComponent.h>
  15. #include <Atom/Component/DebugCamera/NoClipControllerComponent.h>
  16. #include <Atom/RPI.Public/RenderPipeline.h>
  17. #include <Atom/RPI.Public/Scene.h>
  18. #include <Atom/RHI/RHISystemInterface.h>
  19. #include <Atom/RPI.Public/RPISystemInterface.h>
  20. #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
  21. #include <Atom/RPI.Reflect/Model/ModelAsset.h>
  22. #include <AzCore/Math/MatrixUtils.h>
  23. #include <AzCore/Component/Entity.h>
  24. #include <AzFramework/Components/TransformComponent.h>
  25. #include <AzFramework/Scene/SceneSystemBus.h>
  26. #include <AzFramework/Entity/GameEntityContextComponent.h>
  27. #include <SampleComponentConfig.h>
  28. #include <SampleComponentManager.h>
  29. #include <EntityUtilityFunctions.h>
  30. #include <RHI/BasicRHIComponent.h>
  31. namespace AtomSampleViewer
  32. {
  33. //////////////////////////////////////////////////////////////////////////
  34. // SecondWindowedScene
  35. SecondWindowedScene::SecondWindowedScene(AZStd::string_view sceneName, MultiSceneExampleComponent* parent)
  36. {
  37. using namespace AZ;
  38. m_sceneName = sceneName;
  39. m_parent = parent;
  40. // Create a new EntityContext and AzFramework::Scene, and link them together via SetSceneForEntityContextId
  41. m_entityContext = AZStd::make_unique<AzFramework::EntityContext>();
  42. m_entityContext->InitContext();
  43. // Create the scene
  44. Outcome<AzFramework::Scene*, AZStd::string> createSceneOutcome = Failure<AZStd::string>("SceneSystemRequests bus not responding.");
  45. AzFramework::SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequests::CreateScene, m_sceneName);
  46. AZ_Assert(createSceneOutcome, "%s", createSceneOutcome.GetError().data());
  47. m_frameworkScene = createSceneOutcome.GetValue();
  48. bool success = false;
  49. AzFramework::SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequests::SetSceneForEntityContextId, m_entityContext->GetContextId(), m_frameworkScene);
  50. AZ_Assert(success, "Unable to set entity context on AzFramework::Scene: %s", m_sceneName.c_str());
  51. // Create a NativeWindow and WindowContext
  52. m_nativeWindow = AZStd::make_unique<AzFramework::NativeWindow>("Multi Scene: Second Window", AzFramework::WindowGeometry(0, 0, 1280, 720));
  53. m_nativeWindow->Activate();
  54. RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
  55. m_windowContext = AZStd::make_shared<RPI::WindowContext>();
  56. m_windowContext->Initialize(*device, m_nativeWindow->GetWindowHandle());
  57. // Create the RPI::Scene, add some feature processors
  58. RPI::SceneDescriptor sceneDesc;
  59. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::CapsuleLightFeatureProcessor");
  60. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::DecalTextureArrayFeatureProcessor");
  61. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::DirectionalLightFeatureProcessor");
  62. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::DiskLightFeatureProcessor");
  63. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::ImageBasedLightFeatureProcessor");
  64. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::MeshFeatureProcessor");
  65. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::PointLightFeatureProcessor");
  66. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::PostProcessFeatureProcessor");
  67. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::QuadLightFeatureProcessor");
  68. sceneDesc.m_featureProcessorNames.push_back("ReflectionProbeFeatureProcessor");
  69. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::SkyBoxFeatureProcessor");
  70. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::SpotLightFeatureProcessor");
  71. sceneDesc.m_featureProcessorNames.push_back("AZ::Render::TransformServiceFeatureProcessor");
  72. m_scene = RPI::Scene::CreateScene(sceneDesc);
  73. // Setup scene srg modification callback (to push per-frame values to the shaders)
  74. RPI::ShaderResourceGroupCallback srgCallback = [this](RPI::ShaderResourceGroup* srg)
  75. {
  76. if (srg == nullptr)
  77. {
  78. return;
  79. }
  80. RHI::ShaderInputNameIndex timeIndex = "m_time";
  81. RHI::ShaderInputNameIndex deltaTimeIndex = "m_deltaTime";
  82. srg->SetConstant(timeIndex, aznumeric_cast<float>(m_simulateTime));
  83. srg->SetConstant(deltaTimeIndex, m_deltaTime);
  84. bool needCompile = timeIndex.IsValid() || deltaTimeIndex.IsValid();
  85. if (needCompile)
  86. {
  87. srg->Compile();
  88. }
  89. };
  90. m_scene->SetShaderResourceGroupCallback(srgCallback);
  91. // Link our RPI::Scene to the AzFramework::Scene
  92. m_frameworkScene->SetSubsystem(m_scene.get());
  93. // Create a custom pipeline descriptor
  94. RPI::RenderPipelineDescriptor pipelineDesc;
  95. pipelineDesc.m_mainViewTagName = "MainCamera"; // Surface shaders render to the "MainCamera" tag
  96. pipelineDesc.m_name = "SecondPipeline"; // Sets the debug name for this pipeline
  97. pipelineDesc.m_rootPassTemplate = "MainPipeline"; // References a template in AtomSampleViewer\Passes\MainPipeline.pass
  98. pipelineDesc.m_renderSettings.m_multisampleState.m_samples = 4;
  99. m_pipeline = RPI::RenderPipeline::CreateRenderPipelineForWindow(pipelineDesc, *m_windowContext);
  100. m_scene->AddRenderPipeline(m_pipeline);
  101. m_scene->Activate();
  102. RPI::RPISystemInterface::Get()->RegisterScene(m_scene);
  103. // Create a camera entity, hook it up to the RenderPipeline
  104. m_cameraEntity = CreateEntity("WindowedSceneCamera", m_entityContext->GetContextId());
  105. Debug::CameraComponentConfig cameraConfig(m_windowContext);
  106. cameraConfig.m_fovY = Constants::HalfPi;
  107. m_cameraEntity->CreateComponent(azrtti_typeid<Debug::CameraComponent>())->SetConfiguration(cameraConfig);
  108. m_cameraEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
  109. m_cameraEntity->CreateComponent(azrtti_typeid<Debug::NoClipControllerComponent>());
  110. m_cameraEntity->Init();
  111. m_cameraEntity->Activate();
  112. m_pipeline->SetDefaultViewFromEntity(m_cameraEntity->GetId());
  113. // Create a Depth of Field entity
  114. m_depthOfFieldEntity = CreateEntity("DepthOfField", m_entityContext->GetContextId());
  115. m_depthOfFieldEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
  116. // Get the FeatureProcessors
  117. m_meshFeatureProcessor = m_scene->GetFeatureProcessor<Render::MeshFeatureProcessorInterface>();
  118. m_skyBoxFeatureProcessor = m_scene->GetFeatureProcessor<Render::SkyBoxFeatureProcessorInterface>();
  119. m_pointLightFeatureProcessor = m_scene->GetFeatureProcessor<Render::PointLightFeatureProcessorInterface>();
  120. m_spotLightFeatureProcessor = m_scene->GetFeatureProcessor<Render::SpotLightFeatureProcessorInterface>();
  121. m_directionalLightFeatureProcessor = m_scene->GetFeatureProcessor<Render::DirectionalLightFeatureProcessorInterface>();
  122. m_reflectionProbeFeatureProcessor = m_scene->GetFeatureProcessor<Render::ReflectionProbeFeatureProcessorInterface>();
  123. m_postProcessFeatureProcessor = m_scene->GetFeatureProcessor<Render::PostProcessFeatureProcessorInterface>();
  124. // Helper function to load meshes
  125. const auto LoadMesh = [this](const char* modelPath) -> Render::MeshFeatureProcessorInterface::MeshHandle
  126. {
  127. AZ_Assert(m_meshFeatureProcessor, "Cannot find mesh feature processor on scene");
  128. auto meshAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::ModelAsset>(modelPath, RPI::AssetUtils::TraceLevel::Assert);
  129. Render::MeshFeatureProcessorInterface::MeshHandle meshHandle = m_meshFeatureProcessor->AcquireMesh(meshAsset);
  130. return meshHandle;
  131. };
  132. // Create the ShaderBalls
  133. {
  134. for (uint32_t i = 0u; i < ShaderBallCount; i++)
  135. {
  136. m_shaderBallMeshHandles.push_back(LoadMesh("objects/shaderball_simple.azmodel"));
  137. auto updateShaderBallTransform = [this, i](Data::Instance<RPI::Model> model)
  138. {
  139. const Aabb& aabb = model->GetAabb();
  140. const Vector3 translation{ 0.0f, -aabb.GetMin().GetZ() * aznumeric_cast<float>(i), -aabb.GetMin().GetY() };
  141. const auto transform = Transform::CreateTranslation(translation);
  142. m_meshFeatureProcessor->SetTransform(m_shaderBallMeshHandles[i], transform);
  143. };
  144. // If the model is available already, set the tranform immediately, else utilize the EBus::Event feature
  145. Data::Instance<RPI::Model> shaderBallModel = m_meshFeatureProcessor->GetModel(m_shaderBallMeshHandles[i]);
  146. if (shaderBallModel)
  147. {
  148. updateShaderBallTransform(shaderBallModel);
  149. }
  150. else
  151. {
  152. m_shaderBallChangedHandles.push_back(ModelChangedHandler(updateShaderBallTransform));
  153. m_meshFeatureProcessor->ConnectModelChangeEventHandler(m_shaderBallMeshHandles[i], m_shaderBallChangedHandles.back());
  154. }
  155. }
  156. }
  157. // Create the floor
  158. {
  159. const Vector3 scale{ 24.f, 24.f, 1.0f };
  160. const Vector3 translation{ 0.f, 0.f, 0.0f };
  161. const auto transform = Transform::CreateTranslation(translation) * Transform::CreateScale(scale);
  162. m_floorMeshHandle = LoadMesh("testdata/objects/cube/cube.azmodel");
  163. m_meshFeatureProcessor->SetTransform(m_floorMeshHandle, transform);
  164. }
  165. // Create the Skybox
  166. {
  167. m_skyBoxFeatureProcessor->SetSkyboxMode(Render::SkyBoxMode::PhysicalSky);
  168. m_skyBoxFeatureProcessor->Enable(true);
  169. }
  170. // Create PointLight
  171. {
  172. m_pointLightHandle = m_pointLightFeatureProcessor->AcquireLight();
  173. const Vector3 pointLightPosition(4.0f, 0.0f, 5.0f);
  174. m_pointLightFeatureProcessor->SetPosition(m_pointLightHandle, pointLightPosition);
  175. Render::PhotometricValue rgbIntensity;
  176. rgbIntensity.SetEffectiveSolidAngle(Render::PhotometricValue::OmnidirectionalSteradians);
  177. m_pointLightFeatureProcessor->SetRgbIntensity(m_pointLightHandle, rgbIntensity.GetCombinedRgb<Render::PhotometricUnit::Candela>());
  178. m_pointLightFeatureProcessor->SetBulbRadius(m_pointLightHandle, 4.0f);
  179. }
  180. // Create SpotLight
  181. {
  182. m_spotLightHandle = m_spotLightFeatureProcessor->AcquireLight();
  183. const Vector3 spotLightPosition(3.0f, 0.0f, 4.0f);
  184. m_spotLightFeatureProcessor->SetPosition(m_spotLightHandle, spotLightPosition);
  185. Render::PhotometricValue rgbIntensity;
  186. m_spotLightFeatureProcessor->SetRgbIntensity(m_spotLightHandle, Render::PhotometricColor<Render::PhotometricUnit::Candela>(Color::CreateOne() * 2000.0f));
  187. const auto lightDir = Transform::CreateLookAt(
  188. spotLightPosition,
  189. Vector3::CreateZero());
  190. m_spotLightFeatureProcessor->SetDirection(m_spotLightHandle, lightDir.GetBasis(1));
  191. const float radius = sqrtf(2000.0f / 0.5f);
  192. m_spotLightFeatureProcessor->SetAttenuationRadius(m_spotLightHandle, radius);
  193. m_spotLightFeatureProcessor->SetShadowmapSize(m_spotLightHandle, Render::ShadowmapSize::Size512);
  194. m_spotLightFeatureProcessor->SetConeAngles(m_spotLightHandle, 45.f, 55.f);
  195. m_spotLightFeatureProcessor->SetShadowBoundaryWidthAngle(m_spotLightHandle, 0.25f);
  196. }
  197. // Create DirectionalLight
  198. {
  199. m_directionalLightHandle = m_directionalLightFeatureProcessor->AcquireLight();
  200. // Get the camera configuration
  201. {
  202. Camera::Configuration config;
  203. Camera::CameraRequestBus::EventResult(
  204. config,
  205. m_cameraEntity->GetId(),
  206. &Camera::CameraRequestBus::Events::GetCameraConfiguration);
  207. m_directionalLightFeatureProcessor->SetCameraConfiguration(
  208. m_directionalLightHandle,
  209. config);
  210. }
  211. // Camera Transform
  212. {
  213. Transform transform = Transform::CreateIdentity();
  214. TransformBus::EventResult(
  215. transform,
  216. m_cameraEntity->GetId(),
  217. &TransformBus::Events::GetWorldTM);
  218. m_directionalLightFeatureProcessor->SetCameraTransform(
  219. m_directionalLightHandle, transform);
  220. }
  221. Render::PhotometricColor<Render::PhotometricUnit::Lux> lightColor(Color::CreateOne() * 50.0f);
  222. m_directionalLightFeatureProcessor->SetRgbIntensity(m_directionalLightHandle, lightColor);
  223. const Vector3 helperPosition(-3.0f, 0.0f, 4.0f);
  224. const auto lightDir = Transform::CreateLookAt(
  225. helperPosition,
  226. Vector3::CreateZero());
  227. m_directionalLightFeatureProcessor->SetDirection(m_directionalLightHandle, lightDir.GetBasis(1));
  228. m_directionalLightFeatureProcessor->SetShadowmapSize(m_directionalLightHandle, Render::ShadowmapSize::Size512);
  229. m_directionalLightFeatureProcessor->SetCascadeCount(m_directionalLightHandle, 2);
  230. }
  231. // Create ReflectionProbe
  232. {
  233. const Vector3 probePosition{ -5.0f, 0.0f, 1.5f };
  234. const Transform probeTransform = Transform::CreateTranslation(probePosition);
  235. m_reflectionProbeHandle = m_reflectionProbeFeatureProcessor->AddProbe(probeTransform, true);
  236. m_reflectionProbeFeatureProcessor->ShowProbeVisualization(m_reflectionProbeHandle, true);
  237. }
  238. // Enable Depth of Field
  239. {
  240. // Setup the depth of field
  241. auto* postProcessSettings = m_postProcessFeatureProcessor->GetOrCreateSettingsInterface(m_depthOfFieldEntity->GetId());
  242. m_depthOfFieldSettings = postProcessSettings->GetOrCreateDepthOfFieldSettingsInterface();
  243. m_depthOfFieldSettings->SetQualityLevel(1u);
  244. m_depthOfFieldSettings->SetApertureF(0.5f);
  245. m_depthOfFieldSettings->SetEnableDebugColoring(false);
  246. m_depthOfFieldSettings->SetEnableAutoFocus(true);
  247. m_depthOfFieldSettings->SetAutoFocusScreenPosition(Vector2{ 0.5f, 0.5f });
  248. m_depthOfFieldSettings->SetAutoFocusSensitivity(1.0f);
  249. m_depthOfFieldSettings->SetAutoFocusSpeed(Render::DepthOfField::AutoFocusSpeedMax);
  250. m_depthOfFieldSettings->SetAutoFocusDelay(0.2f);
  251. m_depthOfFieldSettings->SetCameraEntityId(m_cameraEntity->GetId());
  252. m_depthOfFieldSettings->SetEnabled(true);
  253. m_depthOfFieldSettings->OnConfigChanged();
  254. m_depthOfFieldEntity->Init();
  255. m_depthOfFieldEntity->Activate();
  256. }
  257. // IBL
  258. m_defaultIbl.Init(m_scene.get());
  259. TickBus::Handler::BusConnect();
  260. AzFramework::WindowNotificationBus::Handler::BusConnect(m_nativeWindow->GetWindowHandle());
  261. }
  262. SecondWindowedScene::~SecondWindowedScene()
  263. {
  264. using namespace AZ;
  265. // Disconnect hte busses
  266. TickBus::Handler::BusDisconnect();
  267. AzFramework::WindowNotificationBus::Handler::BusDisconnect(m_nativeWindow->GetWindowHandle());
  268. m_defaultIbl.Reset();
  269. // Release all the light types
  270. m_pointLightFeatureProcessor->ReleaseLight(m_pointLightHandle);
  271. m_spotLightFeatureProcessor->ReleaseLight(m_spotLightHandle);
  272. m_directionalLightFeatureProcessor->ReleaseLight(m_directionalLightHandle);
  273. // Release the probe
  274. m_reflectionProbeFeatureProcessor->RemoveProbe(m_reflectionProbeHandle);
  275. m_reflectionProbeHandle = nullptr;
  276. // Release all meshes
  277. for (auto& shaderBallMeshHandle : m_shaderBallMeshHandles)
  278. {
  279. m_meshFeatureProcessor->ReleaseMesh(shaderBallMeshHandle);
  280. }
  281. m_meshFeatureProcessor->ReleaseMesh(m_floorMeshHandle);
  282. DestroyEntity(m_cameraEntity);
  283. DestroyEntity(m_depthOfFieldEntity);
  284. m_frameworkScene->UnsetSubsystem<RPI::Scene>();
  285. // Remove the scene
  286. m_scene->Deactivate();
  287. m_scene->RemoveRenderPipeline(m_pipeline->GetId());
  288. RPI::RPISystemInterface::Get()->UnregisterScene(m_scene);
  289. bool sceneRemovedSuccessfully = false;
  290. AzFramework::SceneSystemRequestBus::BroadcastResult(sceneRemovedSuccessfully, &AzFramework::SceneSystemRequests::RemoveScene, m_sceneName);
  291. m_scene = nullptr;
  292. m_windowContext->Shutdown();
  293. }
  294. void SecondWindowedScene::MoveCamera(bool enabled)
  295. {
  296. m_moveCamera = enabled;
  297. }
  298. // AZ::TickBus::Handler overrides ...
  299. void SecondWindowedScene::OnTick(float deltaTime, AZ::ScriptTimePoint timePoint)
  300. {
  301. using namespace AZ;
  302. m_deltaTime = deltaTime;
  303. m_simulateTime = timePoint.GetSeconds();
  304. // Move the camera a bit each frame
  305. // Note: view space in this scene is right-handed, Z-up, Y-forward
  306. const float dynamicOffsetScale = 4.0f;
  307. if (m_moveCamera)
  308. {
  309. m_dynamicCameraOffset = Vector3(dynamicOffsetScale * sinf(aznumeric_cast<float>(timePoint.GetSeconds())), 0.0f, 0.0f);
  310. }
  311. Vector3 cameraPosition = m_cameraOffset + m_dynamicCameraOffset;
  312. TransformBus::Event(m_cameraEntity->GetId(), &TransformBus::Events::SetLocalTranslation, cameraPosition);
  313. const auto cameraDirection = Transform::CreateLookAt(
  314. cameraPosition,
  315. Vector3::CreateZero());
  316. TransformBus::Event(m_cameraEntity->GetId(), &TransformBus::Events::SetLocalRotationQuaternion, cameraDirection.GetRotation());
  317. }
  318. void SecondWindowedScene::OnWindowClosed()
  319. {
  320. m_parent->OnChildWindowClosed();
  321. }
  322. AzFramework::NativeWindowHandle SecondWindowedScene::GetNativeWindowHandle()
  323. {
  324. if (m_nativeWindow)
  325. {
  326. return m_nativeWindow->GetWindowHandle();
  327. }
  328. else
  329. {
  330. return nullptr;
  331. }
  332. }
  333. //////////////////////////////////////////////////////////////////////////
  334. // MultiSceneExampleComponent
  335. void MultiSceneExampleComponent::Reflect(AZ::ReflectContext* context)
  336. {
  337. if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  338. {
  339. serializeContext->Class<MultiSceneExampleComponent, AZ::Component>()
  340. ->Version(0)
  341. ;
  342. }
  343. }
  344. MultiSceneExampleComponent::MultiSceneExampleComponent()
  345. {
  346. }
  347. void MultiSceneExampleComponent::Activate()
  348. {
  349. using namespace AZ;
  350. // Setup primary camera controls
  351. Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &Debug::CameraControllerRequestBus::Events::Enable,
  352. azrtti_typeid<Debug::NoClipControllerComponent>());
  353. RPI::ScenePtr scene = RPI::RPISystemInterface::Get()->GetDefaultScene();
  354. // Setup Main Mesh Entity
  355. {
  356. auto bunnyAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::ModelAsset>("objects/bunny.azmodel", RPI::AssetUtils::TraceLevel::Assert);
  357. m_meshHandle = GetMeshFeatureProcessor()->AcquireMesh(bunnyAsset);
  358. GetMeshFeatureProcessor()->SetTransform(m_meshHandle, Transform::CreateRotationZ(Constants::Pi));
  359. }
  360. // IBL
  361. {
  362. m_defaultIbl.Init(scene.get());
  363. }
  364. if (SupportsMultipleWindows())
  365. {
  366. OpenSecondSceneWindow();
  367. }
  368. TickBus::Handler::BusConnect();
  369. }
  370. void MultiSceneExampleComponent::Deactivate()
  371. {
  372. using namespace AZ;
  373. TickBus::Handler::BusDisconnect();
  374. Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &Debug::CameraControllerRequestBus::Events::Disable);
  375. m_defaultIbl.Reset();
  376. GetMeshFeatureProcessor()->ReleaseMesh(m_meshHandle);
  377. if (m_windowedScene)
  378. {
  379. m_windowedScene = nullptr;
  380. }
  381. }
  382. void MultiSceneExampleComponent::OnChildWindowClosed()
  383. {
  384. m_windowedScene = nullptr;
  385. }
  386. void MultiSceneExampleComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
  387. {
  388. if (ImGui::Begin("Multi Scene Panel"))
  389. {
  390. if (m_windowedScene)
  391. {
  392. static bool moveCamera = false;
  393. if (ImGui::Button("Close Second Scene Window"))
  394. {
  395. m_windowedScene = nullptr;
  396. moveCamera = false;
  397. }
  398. if (ImGui::Checkbox("Move camera##MultiSceneExample", &moveCamera))
  399. {
  400. if (m_windowedScene)
  401. {
  402. m_windowedScene->MoveCamera(moveCamera);
  403. }
  404. }
  405. }
  406. else
  407. {
  408. if (ImGui::Button("Open Second Scene Window"))
  409. {
  410. OpenSecondSceneWindow();
  411. }
  412. }
  413. }
  414. ImGui::End();
  415. }
  416. void MultiSceneExampleComponent::OpenSecondSceneWindow()
  417. {
  418. if (!m_windowedScene)
  419. {
  420. m_windowedScene = AZStd::make_unique<SecondWindowedScene>("SecondScene", this);
  421. }
  422. }
  423. } // namespace AtomSampleViewer