123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /*
- * 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 <AzTest/AzTest.h>
- #include <AzCore/UnitTest/TestTypes.h>
- #include "VegetationTest.h"
- #include "VegetationMocks.h"
- //////////////////////////////////////////////////////////////////////////
- #include <AzCore/Component/Entity.h>
- #include <AzCore/Serialization/SerializeContext.h>
- #include <AzCore/Serialization/EditContext.h>
- #include <Source/Components/AreaBlenderComponent.h>
- #include <Source/Components/AreaBlenderComponent.h>
- #include <Source/Components/BlockerComponent.h>
- #include <Source/Components/DescriptorListCombinerComponent.h>
- #include <Source/Components/DescriptorListComponent.h>
- #include <Source/Components/DescriptorWeightSelectorComponent.h>
- #include <Source/Components/DistanceBetweenFilterComponent.h>
- #include <Source/Components/DistributionFilterComponent.h>
- #include <Source/Components/LevelSettingsComponent.h>
- #include <Source/Components/MeshBlockerComponent.h>
- #include <Source/Components/PositionModifierComponent.h>
- #include <Source/Components/RotationModifierComponent.h>
- #include <Source/Components/ScaleModifierComponent.h>
- #include <Source/Components/ShapeIntersectionFilterComponent.h>
- #include <Source/Components/SlopeAlignmentModifierComponent.h>
- #include <Source/Components/SpawnerComponent.h>
- #include <Source/Components/SurfaceAltitudeFilterComponent.h>
- #include <Source/Components/SurfaceMaskDepthFilterComponent.h>
- #include <Source/Components/SurfaceMaskFilterComponent.h>
- #include <Source/Components/SurfaceSlopeFilterComponent.h>
- #include <Source/Debugger/AreaDebugComponent.h>
- namespace UnitTest
- {
- struct VegetationComponentTestsBasics
- : public VegetationComponentTests
- {
- void RegisterComponentDescriptors() override
- {
- m_app.RegisterComponentDescriptor(MockShapeServiceComponent::CreateDescriptor());
- m_app.RegisterComponentDescriptor(MockVegetationAreaServiceComponent::CreateDescriptor());
- m_app.RegisterComponentDescriptor(MockMeshServiceComponent::CreateDescriptor());
- }
- template <typename Component, typename MockComponent1>
- void CreateWith()
- {
- m_app.RegisterComponentDescriptor(Component::CreateDescriptor());
- AZ::Entity entity;
- entity.CreateComponent<Component>();
- entity.CreateComponent<MockComponent1>();
- entity.Init();
- ASSERT_TRUE(entity.GetState() == AZ::Entity::State::Init);
- entity.Activate();
- ASSERT_TRUE(entity.GetState() == AZ::Entity::State::Active);
- entity.Deactivate();
- ASSERT_TRUE(entity.GetState() == AZ::Entity::State::Init);
- }
- template <typename ComponentA, typename ComponentB>
- bool IsComponentCompatible()
- {
- AZ::ComponentDescriptor::DependencyArrayType providedServicesA;
- ComponentA::GetProvidedServices(providedServicesA);
- AZ::ComponentDescriptor::DependencyArrayType incompatibleServicesB;
- ComponentB::GetIncompatibleServices(incompatibleServicesB);
- for (auto providedServiceA : providedServicesA)
- {
- for (auto incompatibleServiceB : incompatibleServicesB)
- {
- if (providedServiceA == incompatibleServiceB)
- {
- return false;
- }
- }
- }
- return true;
- }
- template <typename ComponentA, typename ComponentB>
- bool AreComponentsCompatible()
- {
- return IsComponentCompatible<ComponentA, ComponentB>() && IsComponentCompatible<ComponentB, ComponentA>();
- }
- bool BeginElementMinMaxTests(
- AZ::SerializeContext* sc,
- void* instance,
- const AZ::SerializeContext::ClassData* classData,
- const AZ::SerializeContext::ClassElement* classElement)
- {
- (void)instance;
- if (classElement)
- {
- // if we are a pointer, then we may be pointing to a derived type.
- if (classElement->m_flags & AZ::SerializeContext::ClassElement::FLG_POINTER)
- {
- // if dataAddress is a pointer in this case, cast it's value to a void* (or const void*) and dereference to get to the actual class.
- instance = *(void**)(instance);
- if (instance && classElement->m_azRtti)
- {
- AZ::Uuid actualClassId = classElement->m_azRtti->GetActualUuid(instance);
- if (actualClassId != classElement->m_typeId)
- {
- // we are pointing to derived type, adjust class data, uuid and pointer.
- classData = sc->FindClassData(actualClassId);
- if (classData)
- {
- instance = classElement->m_azRtti->Cast(instance, classData->m_azRtti->GetTypeId());
- }
- }
- }
- }
- }
- //check editor data numeric elements for min/max attributes
- if (classElement &&
- classElement->m_editData)
- {
- if (classElement->m_editData->m_elementId == AZ::Edit::UIHandlers::Default ||
- classElement->m_editData->m_elementId == AZ::Edit::UIHandlers::Slider ||
- classElement->m_editData->m_elementId == AZ::Edit::UIHandlers::SpinBox)
- {
- if (classElement->m_typeId == azrtti_typeid<AZ::u64>() ||
- classElement->m_typeId == azrtti_typeid<AZ::u32>() ||
- classElement->m_typeId == azrtti_typeid<AZ::u16>() ||
- classElement->m_typeId == azrtti_typeid<AZ::u8>() ||
- classElement->m_typeId == azrtti_typeid<AZ::s64>() ||
- classElement->m_typeId == azrtti_typeid<AZ::s32>() ||
- classElement->m_typeId == azrtti_typeid<AZ::s16>() ||
- classElement->m_typeId == azrtti_typeid<AZ::s8>() ||
- classElement->m_typeId == azrtti_typeid<float>() ||
- classElement->m_typeId == azrtti_typeid<double>())
- {
- EXPECT_TRUE(classElement->m_editData->FindAttribute(AZ::Edit::Attributes::Min) != nullptr);
- EXPECT_TRUE(classElement->m_editData->FindAttribute(AZ::Edit::Attributes::Max) != nullptr);
- }
- }
- }
- return true;
- }
- bool EndfElementMinMaxTests()
- {
- return true;
- }
- template<typename T>
- void ValidateHasMinMaxRanges()
- {
- //create a serialize context with edit context enabled
- AZ::SerializeContext serializeContext(true, true);
- //must reflect AZ::Entity to register AZ::ComponentConfig so new serialize context asserts don't fail test
- AZ::Entity::Reflect(&serializeContext);
- //reflect and inspect the object
- T::Reflect(&serializeContext);
- T object;
- serializeContext.EnumerateObject(&object,
- AZStd::bind(&VegetationComponentTestsBasics::BeginElementMinMaxTests, this, &serializeContext, AZStd::placeholders::_1, AZStd::placeholders::_2, AZStd::placeholders::_3),
- AZStd::bind(&VegetationComponentTestsBasics::EndfElementMinMaxTests, this),
- AZ::SerializeContext::ENUM_ACCESS_FOR_READ);
- }
- };
- TEST_F(VegetationComponentTestsBasics, VerifyCompatibility)
- {
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::DescriptorWeightSelectorComponent, Vegetation::DescriptorWeightSelectorComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::PositionModifierComponent, Vegetation::PositionModifierComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::RotationModifierComponent, Vegetation::RotationModifierComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::ScaleModifierComponent, Vegetation::ScaleModifierComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::DescriptorListComponent, Vegetation::DescriptorListComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::DescriptorListComponent, Vegetation::DescriptorListCombinerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::DescriptorListCombinerComponent, Vegetation::DescriptorListComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::DescriptorListCombinerComponent, Vegetation::DescriptorListCombinerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::AreaBlenderComponent, Vegetation::AreaBlenderComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::AreaBlenderComponent, Vegetation::BlockerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::AreaBlenderComponent, Vegetation::SpawnerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::AreaBlenderComponent, Vegetation::MeshBlockerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::BlockerComponent, Vegetation::AreaBlenderComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::BlockerComponent, Vegetation::BlockerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::BlockerComponent, Vegetation::SpawnerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::BlockerComponent, Vegetation::MeshBlockerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::SpawnerComponent, Vegetation::AreaBlenderComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::SpawnerComponent, Vegetation::BlockerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::SpawnerComponent, Vegetation::SpawnerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::SpawnerComponent, Vegetation::MeshBlockerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::MeshBlockerComponent, Vegetation::AreaBlenderComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::MeshBlockerComponent, Vegetation::BlockerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::MeshBlockerComponent, Vegetation::SpawnerComponent>()));
- EXPECT_FALSE((AreComponentsCompatible<Vegetation::MeshBlockerComponent, Vegetation::MeshBlockerComponent>()));
- }
- TEST_F(VegetationComponentTestsBasics, CreateEach)
- {
- CreateWith<Vegetation::AreaBlenderComponent, MockShapeServiceComponent>();
- CreateWith<Vegetation::BlockerComponent, MockShapeServiceComponent>();
- CreateWith<Vegetation::DescriptorListCombinerComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::DescriptorListComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::DescriptorWeightSelectorComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::DistanceBetweenFilterComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::DistributionFilterComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::LevelSettingsComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::MeshBlockerComponent, MockMeshServiceComponent>();
- CreateWith<Vegetation::PositionModifierComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::RotationModifierComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::ScaleModifierComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::ShapeIntersectionFilterComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::SlopeAlignmentModifierComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::SpawnerComponent, MockShapeServiceComponent>();
- CreateWith<Vegetation::SurfaceAltitudeFilterComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::SurfaceMaskDepthFilterComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::SurfaceMaskFilterComponent, MockVegetationAreaServiceComponent>();
- CreateWith<Vegetation::SurfaceSlopeFilterComponent, MockVegetationAreaServiceComponent>();
- }
- TEST_F(VegetationComponentTestsBasics, LevelSettingsComponent)
- {
- MockSystemConfigurationRequestBus mockSystemConfigurationRequestBus;
- struct TestLevelSettingsComponent
- : public Vegetation::LevelSettingsComponent
- {
- const Vegetation::LevelSettingsConfig& Config() const
- {
- return m_configuration;
- }
- };
- // Provide a default configuration to the system component
- constexpr int defaultProcessTime = 7;
- Vegetation::InstanceSystemConfig defaultSystemConfig;
- defaultSystemConfig.m_maxInstanceProcessTimeMicroseconds = defaultProcessTime;
- mockSystemConfigurationRequestBus.UpdateSystemConfig(&defaultSystemConfig);
- const auto* instConfig = azrtti_cast<const Vegetation::InstanceSystemConfig*>(mockSystemConfigurationRequestBus.m_lastUpdated);
- ASSERT_TRUE(instConfig != nullptr);
- EXPECT_EQ(defaultProcessTime, instConfig->m_maxInstanceProcessTimeMicroseconds);
- {
- // Create a level settings component with a different config that should override the system component
- Vegetation::LevelSettingsComponent* component = nullptr;
- Vegetation::LevelSettingsConfig config;
- config.m_instanceSystemConfig.m_maxInstanceProcessTimeMicroseconds = 13;
- auto entity = CreateEntity(config, &component);
- const auto* instConfig2 = azrtti_cast<const Vegetation::InstanceSystemConfig*>(mockSystemConfigurationRequestBus.m_lastUpdated);
- ASSERT_TRUE(instConfig2 != nullptr);
- EXPECT_EQ(13, instConfig2->m_maxInstanceProcessTimeMicroseconds);
- TestLevelSettingsComponent* tester = static_cast<TestLevelSettingsComponent*>(component);
- EXPECT_EQ(13, tester->Config().m_instanceSystemConfig.m_maxInstanceProcessTimeMicroseconds);
- }
- // Entity should be out of scope now (destroyed), so the default settings should be restored
- instConfig = azrtti_cast<const Vegetation::InstanceSystemConfig*>(mockSystemConfigurationRequestBus.m_lastUpdated);
- EXPECT_EQ(defaultProcessTime, instConfig->m_maxInstanceProcessTimeMicroseconds);
- }
- TEST_F(VegetationComponentTestsBasics, Components_HaveMinMaxRanges)
- {
- ValidateHasMinMaxRanges<Vegetation::AreaSystemConfig>();
- ValidateHasMinMaxRanges<Vegetation::InstanceSystemConfig>();
- ValidateHasMinMaxRanges<Vegetation::AreaDebugConfig>();
- }
- }
- //////////////////////////////////////////////////////////////////////////
- AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
|