123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <SceneReloadSoakTestComponent.h>
- #include <SampleComponentManager.h>
- #include <SampleComponentConfig.h>
- #include <Atom/RPI.Reflect/Model/ModelAsset.h>
- #include <Atom/RPI.Reflect/Material/MaterialAsset.h>
- #include <Atom/Component/DebugCamera/NoClipControllerBus.h>
- #include <AzCore/Component/Entity.h>
- #include <RHI/BasicRHIComponent.h>
- #include <SceneReloadSoakTestComponent_Traits_Platform.h>
- namespace AtomSampleViewer
- {
- using namespace AZ;
- using namespace RPI;
- void SceneReloadSoakTestComponent::Reflect(ReflectContext* context)
- {
- if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
- {
- serializeContext->Class<SceneReloadSoakTestComponent, EntityLatticeTestComponent>()
- ->Version(0)
- ;
- }
- }
- void SceneReloadSoakTestComponent::Activate()
- {
- m_timeSettings.clear();
- m_timeSettings.push_back(TimeSetting{2.0f, 1});
- m_timeSettings.push_back(TimeSetting{0.2f, 50});
- m_timeSettings.push_back(TimeSetting{0.5f, 10});
- m_timeSettings.push_back(TimeSetting{1.0f, 5});
- m_countdown = 0;
- m_totalTime = 0;
- m_currentSettingIndex = 0;
- m_currentCount = 0;
- m_totalResetCount = 0;
- SetLatticeDimensions(ATOMSAMPLEVIEWER_TRAIT_SCENE_RELOAD_SOAK_TEST_COMPONENT_LATTICE_SIZE, ATOMSAMPLEVIEWER_TRAIT_SCENE_RELOAD_SOAK_TEST_COMPONENT_LATTICE_SIZE, ATOMSAMPLEVIEWER_TRAIT_SCENE_RELOAD_SOAK_TEST_COMPONENT_LATTICE_SIZE);
- Base::Activate();
- TickBus::Handler::BusConnect();
- ExampleComponentRequestBus::Handler::BusConnect(GetEntityId());
- }
- void SceneReloadSoakTestComponent::Deactivate()
- {
- ExampleComponentRequestBus::Handler::BusDisconnect();
- TickBus::Handler::BusDisconnect();
- Base::Deactivate();
- }
-
- void SceneReloadSoakTestComponent::ResetCamera()
- {
- Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &Debug::NoClipControllerRequestBus::Events::SetHeading, DegToRad(-25));
- Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &Debug::NoClipControllerRequestBus::Events::SetPitch, DegToRad(25));
- }
- void SceneReloadSoakTestComponent::PrepareCreateLatticeInstances(uint32_t instanceCount)
- {
- m_materialIsUnique.reserve(instanceCount);
- m_meshHandles.reserve(instanceCount);
- const char* materialPath = DefaultPbrMaterialPath;
- const char* modelPath = "objects/shaderball_simple.fbx.azmodel";
- Data::AssetCatalogRequestBus::BroadcastResult(
- m_materialAssetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
- materialPath, azrtti_typeid<MaterialAsset>(), false);
- Data::AssetCatalogRequestBus::BroadcastResult(
- m_modelAssetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
- modelPath, azrtti_typeid<ModelAsset>(), false);
- AZ_Assert(m_materialAssetId.IsValid(), "Failed to get material asset id: %s", materialPath);
- AZ_Assert(m_modelAssetId.IsValid(), "Failed to get model asset id: %s", modelPath);
- }
- void SceneReloadSoakTestComponent::CreateLatticeInstance(const Transform& transform)
- {
- Data::Asset<MaterialAsset> materialAsset;
- materialAsset.Create(m_materialAssetId);
- // We have a mixture of both unique and shared instance to give more variety and therefore more opportunity for things to break.
- bool materialIsUnique = (m_materialIsUnique.size() % 2) == 0;
- auto materialInstance = materialIsUnique ? Material::Create(materialAsset) : Material::FindOrCreate(materialAsset);
- m_materialIsUnique.push_back(materialIsUnique);
- Data::Asset<ModelAsset> modelAsset;
- modelAsset.Create(m_modelAssetId);
- auto meshHandle = GetMeshFeatureProcessor()->AcquireMesh(Render::MeshHandleDescriptor(modelAsset, materialInstance));
- GetMeshFeatureProcessor()->SetTransform(meshHandle, transform);
- m_meshHandles.emplace_back(AZStd::move(meshHandle));
- }
- void SceneReloadSoakTestComponent::DestroyLatticeInstances()
- {
- m_materialIsUnique.clear();
- for (auto& meshHandle : m_meshHandles)
- {
- GetMeshFeatureProcessor()->ReleaseMesh(meshHandle);
- }
- m_meshHandles.clear();
- }
- void SceneReloadSoakTestComponent::OnTick(float deltaTime, [[maybe_unused]] ScriptTimePoint scriptTime)
- {
- // There are some crashes that specifically occurred when unloading a scene while compiling material changes
- {
- // Create a new SimpleLcgRandom every time TickMaterialUpdate is called to keep a consistent seed and consistent color selection.
- SimpleLcgRandom random;
-
- bool updatedSharedMaterialInstance = false;
- size_t entityIndex = 0;
- for (auto& meshHandle : m_meshHandles)
- {
- static const float speed = 4.0f;
- const float t = static_cast<float>(sin(m_totalTime * speed) * 0.5f + 0.5f);
- static const Color colorOptions[] =
- {
- Color(1.0f, 0.0f, 0.0f, 1.0f),
- Color(0.0f, 1.0f, 0.0f, 1.0f),
- Color(0.0f, 0.0f, 1.0f, 1.0f),
- Color(1.0f, 1.0f, 0.0f, 1.0f),
- Color(0.0f, 1.0f, 1.0f, 1.0f),
- Color(1.0f, 0.0f, 1.0f, 1.0f),
- };
- const int colorIndexA = random.GetRandom() % AZ_ARRAY_SIZE(colorOptions);
- int colorIndexB = colorIndexA;
- while (colorIndexA == colorIndexB)
- {
- colorIndexB = random.GetRandom() % AZ_ARRAY_SIZE(colorOptions);
- }
- const Color color = colorOptions[colorIndexA] * t + colorOptions[colorIndexB] * (1.0f - t);
- if (m_materialIsUnique[entityIndex] || !updatedSharedMaterialInstance)
- {
- for (auto& customMaterialPair : GetMeshFeatureProcessor()->GetCustomMaterials(meshHandle))
- {
- if (Data::Instance<Material> material = customMaterialPair.second.m_material)
- {
- MaterialPropertyIndex colorPropertyIndex = material->FindPropertyIndex(Name("baseColor.color"));
- if (colorPropertyIndex.IsValid())
- {
- material->SetPropertyValue(colorPropertyIndex, color);
- material->Compile();
- if (!m_materialIsUnique[entityIndex])
- {
- updatedSharedMaterialInstance = true;
- }
- }
- else
- {
- AZ_Error("", false, "Could not find the color property index");
- }
- }
- }
- }
- entityIndex++;
- }
- }
-
- m_countdown -= deltaTime;
- m_totalTime += deltaTime;
- // Rebuild the scene every time the countdown expires.
- // We might also need to move to the next TimeSetting with a new countdown time.
- if (m_countdown < 0)
- {
- TimeSetting currentSetting = m_timeSettings[m_currentSettingIndex % m_timeSettings.size()];
- m_countdown = currentSetting.resetDelay;
- // The TimeSetting struct tells us how many times we should use it, before moving to the next TimeSetting struct
- m_currentCount++;
- if (m_currentCount >= currentSetting.count)
- {
- m_currentCount = 0;
- m_currentSettingIndex++;
- }
- m_totalResetCount++;
- AZ_TracePrintf("", "SceneReloadSoakTest RESET # %d @ time %f. Next reset in %f s\n", m_totalResetCount, m_totalTime, m_countdown);
- RebuildLattice();
- }
- }
- } // namespace AtomSampleViewer
|