EditorHairComponent.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #if defined (ATOMTRESSFX_EDITOR)
  9. #include <AzCore/RTTI/BehaviorContext.h>
  10. #include <Components/EditorHairComponent.h>
  11. #include <Rendering/HairRenderObject.h>
  12. namespace AZ
  13. {
  14. namespace Render
  15. {
  16. namespace Hair
  17. {
  18. void EditorHairComponent::Reflect(AZ::ReflectContext* context)
  19. {
  20. BaseClass::Reflect(context);
  21. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  22. {
  23. serializeContext->Class<EditorHairComponent, BaseClass>()
  24. ->Version(1);
  25. if (AZ::EditContext* editContext = serializeContext->GetEditContext())
  26. {
  27. editContext->Class<EditorHairComponent>(
  28. "Atom Hair", "Controls Hair Properties")
  29. ->ClassElement(Edit::ClassElements::EditorData, "")
  30. ->Attribute(Edit::Attributes::Category, "Graphics/Mesh")
  31. ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
  32. ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Component_Placeholder.svg")
  33. ->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
  34. ->Attribute(Edit::Attributes::AutoExpand, true)
  35. ;
  36. editContext->Class<HairComponentController>(
  37. "HairComponentController", "")
  38. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  39. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  40. ->DataElement(AZ::Edit::UIHandlers::Default, &HairComponentController::m_configuration, "Configuration", "")
  41. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
  42. ;
  43. editContext->Class<HairComponentConfig>(
  44. "HairComponentConfig", "")
  45. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  46. ->DataElement(
  47. AZ::Edit::UIHandlers::Default, &HairComponentConfig::m_hairAsset, "Hair Asset",
  48. "TressFX asset to be assigned to this entity.")
  49. ->DataElement(
  50. AZ::Edit::UIHandlers::Default, &HairComponentConfig::m_simulationSettings, "TressFX Sim Settings",
  51. "TressFX simulation settings to be applied on this entity.")
  52. ->DataElement(
  53. AZ::Edit::UIHandlers::Default, &HairComponentConfig::m_renderingSettings, "TressFX Render Settings",
  54. "TressFX rendering settings to be applied on this entity.")
  55. ->DataElement(AZ::Edit::UIHandlers::Default, &HairComponentConfig::m_hairGlobalSettings)
  56. ->Attribute(AZ::Edit::Attributes::ChangeNotify, &HairComponentConfig::OnHairGlobalSettingsChanged)
  57. ;
  58. }
  59. }
  60. if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
  61. {
  62. behaviorContext->Class<EditorHairComponent>()->RequestBus("HairRequestsBus");
  63. behaviorContext->ConstantProperty("EditorHairComponentTypeId", BehaviorConstant(Uuid(Hair::EditorHairComponentTypeId)))
  64. ->Attribute(AZ::Script::Attributes::Module, "render")
  65. ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation);
  66. }
  67. }
  68. EditorHairComponent::EditorHairComponent(const HairComponentConfig& config)
  69. : BaseClass(config)
  70. {
  71. m_prevHairAssetId = config.m_hairAsset.GetId();
  72. }
  73. void EditorHairComponent::Activate()
  74. {
  75. BaseClass::Activate();
  76. AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId());
  77. }
  78. void EditorHairComponent::Deactivate()
  79. {
  80. BaseClass::Deactivate();
  81. AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
  82. }
  83. u32 EditorHairComponent::OnConfigurationChanged()
  84. {
  85. // Since any of the hair config and hair asset change will trigger this call, we use the prev loaded hair assetId
  86. // to check which config actually got changed.
  87. // This is because an asset change is a heavy operation and we don't want to trigger that when it's not needed.
  88. if (m_prevHairAssetId == m_controller.GetConfiguration().m_hairAsset.GetId())
  89. {
  90. m_controller.OnHairConfigChanged();
  91. }
  92. else
  93. {
  94. m_controller.OnHairAssetChanged();
  95. m_prevHairAssetId = m_controller.GetConfiguration().m_hairAsset.GetId();
  96. }
  97. return Edit::PropertyRefreshLevels::AttributesAndValues;
  98. }
  99. void EditorHairComponent::DisplayEntityViewport(
  100. [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
  101. {
  102. // Only render debug information when selected.
  103. if (!IsSelected())
  104. {
  105. return;
  106. }
  107. // Only render debug information after render object got created.
  108. if (!m_controller.m_renderObject)
  109. {
  110. return;
  111. }
  112. float x = 40.0;
  113. float y = 20.0f;
  114. float size = 1.00f;
  115. bool center = false;
  116. AZStd::string debugString = AZStd::string::format(
  117. "Hair component stats:\n"
  118. " Total number of hairs: %d\n"
  119. " Total number of guide hairs: %d\n"
  120. " Amount of follow hair per guide hair: %d\n",
  121. m_controller.m_renderObject->GetNumTotalHairStrands(),
  122. m_controller.m_renderObject->GetNumGuideHairs(),
  123. m_controller.m_renderObject->GetNumFollowHairsPerGuideHair());
  124. debugDisplay.Draw2dTextLabel(x, y, size, debugString.c_str(), center);
  125. }
  126. } // namespace Hair
  127. } // namespace Render
  128. } // namespace AZ
  129. #endif // ATOMTRESSFX_EDITOR