CylinderShapeComponent.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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. #include "CylinderShapeComponent.h"
  9. #include <AzCore/RTTI/BehaviorContext.h>
  10. #include <AzCore/Serialization/EditContext.h>
  11. #include <AzFramework/Entity/EntityDebugDisplayBus.h>
  12. #include <Shape/ShapeComponentConverters.h>
  13. #include <Shape/ShapeDisplay.h>
  14. namespace LmbrCentral
  15. {
  16. void CylinderShapeComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  17. {
  18. provided.push_back(AZ_CRC_CE("ShapeService"));
  19. provided.push_back(AZ_CRC_CE("CylinderShapeService"));
  20. }
  21. void CylinderShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  22. {
  23. incompatible.push_back(AZ_CRC_CE("ShapeService"));
  24. incompatible.push_back(AZ_CRC_CE("CylinderShapeService"));
  25. incompatible.push_back(AZ_CRC_CE("NonUniformScaleService"));
  26. }
  27. void CylinderShapeComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  28. {
  29. required.push_back(AZ_CRC_CE("TransformService"));
  30. }
  31. void CylinderShapeDebugDisplayComponent::Reflect(AZ::ReflectContext* context)
  32. {
  33. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  34. {
  35. serializeContext->Class<CylinderShapeDebugDisplayComponent, EntityDebugDisplayComponent>()
  36. ->Version(1)
  37. ->Field("Configuration", &CylinderShapeDebugDisplayComponent::m_cylinderShapeConfig)
  38. ;
  39. }
  40. }
  41. void CylinderShapeDebugDisplayComponent::Activate()
  42. {
  43. EntityDebugDisplayComponent::Activate();
  44. ShapeComponentNotificationsBus::Handler::BusConnect(GetEntityId());
  45. }
  46. void CylinderShapeDebugDisplayComponent::Deactivate()
  47. {
  48. ShapeComponentNotificationsBus::Handler::BusDisconnect();
  49. EntityDebugDisplayComponent::Deactivate();
  50. }
  51. void CylinderShapeDebugDisplayComponent::Draw(AzFramework::DebugDisplayRequests& debugDisplay)
  52. {
  53. DrawCylinderShape(m_cylinderShapeConfig.GetDrawParams(), m_cylinderShapeConfig, debugDisplay);
  54. }
  55. bool CylinderShapeDebugDisplayComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
  56. {
  57. if (const auto config = azrtti_cast<const CylinderShapeConfig*>(baseConfig))
  58. {
  59. m_cylinderShapeConfig = *config;
  60. return true;
  61. }
  62. return false;
  63. }
  64. bool CylinderShapeDebugDisplayComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
  65. {
  66. if (auto outConfig = azrtti_cast<CylinderShapeConfig*>(outBaseConfig))
  67. {
  68. *outConfig = m_cylinderShapeConfig;
  69. return true;
  70. }
  71. return false;
  72. }
  73. void CylinderShapeDebugDisplayComponent::OnShapeChanged(ShapeChangeReasons changeReason)
  74. {
  75. if (changeReason == ShapeChangeReasons::ShapeChanged)
  76. {
  77. CylinderShapeComponentRequestsBus::EventResult(m_cylinderShapeConfig, GetEntityId(), &CylinderShapeComponentRequests::GetCylinderConfiguration);
  78. }
  79. }
  80. namespace ClassConverters
  81. {
  82. static bool DeprecateCylinderColliderConfiguration(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
  83. static bool DeprecateCylinderColliderComponent(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
  84. }
  85. void CylinderShapeConfig::Reflect(AZ::ReflectContext* context)
  86. {
  87. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  88. {
  89. // Deprecate: CylinderColliderConfiguration -> CylinderShapeConfig
  90. serializeContext->ClassDeprecate(
  91. "CylinderColliderConfiguration",
  92. AZ::Uuid("{E1DCB833-EFC4-43AC-97B0-4E07AA0DFAD9}"),
  93. &ClassConverters::DeprecateCylinderColliderConfiguration)
  94. ;
  95. serializeContext->Class<CylinderShapeConfig, ShapeComponentConfig>()
  96. ->Version(2)
  97. ->Field("Height", &CylinderShapeConfig::m_height)
  98. ->Field("Radius", &CylinderShapeConfig::m_radius)
  99. ;
  100. if (AZ::EditContext* editContext = serializeContext->GetEditContext())
  101. {
  102. editContext->Class<CylinderShapeConfig>("Configuration", "Cylinder shape configuration parameters")
  103. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  104. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  105. ->DataElement(AZ::Edit::UIHandlers::Default, &CylinderShapeConfig::m_height, "Height", "Height of cylinder")
  106. ->Attribute(AZ::Edit::Attributes::Min, 0.f)
  107. ->Attribute(AZ::Edit::Attributes::Max, 1000000.f)
  108. ->Attribute(AZ::Edit::Attributes::Suffix, " m")
  109. ->Attribute(AZ::Edit::Attributes::Step, 0.1f)
  110. ->DataElement(AZ::Edit::UIHandlers::Default, &CylinderShapeConfig::m_radius, "Radius", "Radius of cylinder")
  111. ->Attribute(AZ::Edit::Attributes::Min, 0.f)
  112. ->Attribute(AZ::Edit::Attributes::Max, 1000000.f)
  113. ->Attribute(AZ::Edit::Attributes::Suffix, " m")
  114. ->Attribute(AZ::Edit::Attributes::Step, 0.05f)
  115. ;
  116. }
  117. }
  118. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  119. {
  120. behaviorContext->Class<CylinderShapeConfig>()
  121. ->Property("Height", BehaviorValueProperty(&CylinderShapeConfig::m_height))
  122. ->Property("Radius", BehaviorValueProperty(&CylinderShapeConfig::m_radius))
  123. ;
  124. }
  125. }
  126. void CylinderShapeComponent::Reflect(AZ::ReflectContext* context)
  127. {
  128. CylinderShape::Reflect(context);
  129. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  130. {
  131. serializeContext->ClassDeprecate(
  132. "CylinderColliderComponent",
  133. AZ::Uuid("{A43F684B-07B6-4CD7-8D59-643709DF9486}"),
  134. &ClassConverters::DeprecateCylinderColliderComponent)
  135. ;
  136. serializeContext->Class<CylinderShapeComponent, AZ::Component>()
  137. ->Version(2, &ClassConverters::UpgradeCylinderShapeComponent)
  138. ->Field("CylinderShape", &CylinderShapeComponent::m_cylinderShape)
  139. ;
  140. }
  141. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  142. {
  143. behaviorContext->Constant("CylinderShapeComponentTypeId", BehaviorConstant(CylinderShapeComponentTypeId));
  144. behaviorContext->EBus<CylinderShapeComponentRequestsBus>("CylinderShapeComponentRequestsBus")
  145. ->Event("GetCylinderConfiguration", &CylinderShapeComponentRequestsBus::Events::GetCylinderConfiguration)
  146. ->Event("SetHeight", &CylinderShapeComponentRequestsBus::Events::SetHeight)
  147. ->Event("SetRadius", &CylinderShapeComponentRequestsBus::Events::SetRadius)
  148. ;
  149. }
  150. }
  151. void CylinderShapeComponent::Activate()
  152. {
  153. m_cylinderShape.Activate(GetEntityId());
  154. }
  155. void CylinderShapeComponent::Deactivate()
  156. {
  157. m_cylinderShape.Deactivate();
  158. }
  159. bool CylinderShapeComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
  160. {
  161. if (const auto config = azrtti_cast<const CylinderShapeConfig*>(baseConfig))
  162. {
  163. m_cylinderShape.SetCylinderConfiguration(*config);
  164. return true;
  165. }
  166. return false;
  167. }
  168. bool CylinderShapeComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
  169. {
  170. if (auto outConfig = azrtti_cast<CylinderShapeConfig*>(outBaseConfig))
  171. {
  172. *outConfig = m_cylinderShape.GetCylinderConfiguration();
  173. return true;
  174. }
  175. return false;
  176. }
  177. namespace ClassConverters
  178. {
  179. static bool DeprecateCylinderColliderConfiguration(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
  180. {
  181. /*
  182. Old:
  183. <Class name="CylinderColliderConfiguration" field="Configuration" version="1" type="{E1DCB833-EFC4-43AC-97B0-4E07AA0DFAD9}">
  184. <Class name="float" field="Height" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  185. <Class name="float" field="Radius" value="0.2500000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  186. </Class>
  187. New:
  188. <Class name="CylinderShapeConfig" field="Configuration" version="1" type="{53254779-82F1-441E-9116-81E1FACFECF4}">
  189. <Class name="float" field="Height" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  190. <Class name="float" field="Radius" value="0.2500000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  191. </Class>
  192. */
  193. // Cache the Height and Radius
  194. float oldHeight = 0.f;
  195. float oldRadius = 0.f;
  196. int oldIndex = classElement.FindElement(AZ_CRC_CE("Height"));
  197. if (oldIndex != -1)
  198. {
  199. classElement.GetSubElement(oldIndex).GetData<float>(oldHeight);
  200. }
  201. oldIndex = classElement.FindElement(AZ_CRC_CE("Radius"));
  202. if (oldIndex != -1)
  203. {
  204. classElement.GetSubElement(oldIndex).GetData<float>(oldRadius);
  205. }
  206. // Convert to CylinderShapeConfig
  207. const bool result = classElement.Convert<CylinderShapeConfig>(context);
  208. if (result)
  209. {
  210. int newIndex = classElement.AddElement<float>(context, "Height");
  211. if (newIndex != -1)
  212. {
  213. classElement.GetSubElement(newIndex).SetData<float>(context, oldHeight);
  214. }
  215. newIndex = classElement.AddElement<float>(context, "Radius");
  216. if (newIndex != -1)
  217. {
  218. classElement.GetSubElement(newIndex).SetData<float>(context, oldRadius);
  219. }
  220. return true;
  221. }
  222. return false;
  223. }
  224. static bool DeprecateCylinderColliderComponent(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
  225. {
  226. /*
  227. Old:
  228. <Class name="CylinderColliderComponent" version="1" type="{A43F684B-07B6-4CD7-8D59-643709DF9486}">
  229. <Class name="CylinderColliderConfiguration" field="Configuration" version="1" type="{E1DCB833-EFC4-43AC-97B0-4E07AA0DFAD9}">
  230. <Class name="float" field="Height" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  231. <Class name="float" field="Radius" value="0.2500000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  232. </Class>
  233. </Class>
  234. New:
  235. <Class name="CylinderShapeComponent" version="1" type="{B0C6AA97-E754-4E33-8D32-33E267DB622F}">
  236. <Class name="CylinderShapeConfig" field="Configuration" version="1" type="{53254779-82F1-441E-9116-81E1FACFECF4}">
  237. <Class name="float" field="Height" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  238. <Class name="float" field="Radius" value="0.2500000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
  239. </Class>
  240. </Class>
  241. */
  242. // Cache the Configuration
  243. CylinderShapeConfig configuration;
  244. int configIndex = classElement.FindElement(AZ_CRC_CE("Configuration"));
  245. if (configIndex != -1)
  246. {
  247. classElement.GetSubElement(configIndex).GetData<CylinderShapeConfig>(configuration);
  248. }
  249. // Convert to CylinderShapeComponent
  250. const bool result = classElement.Convert<CylinderShapeComponent>(context);
  251. if (result)
  252. {
  253. configIndex = classElement.AddElement<CylinderShapeConfig>(context, "Configuration");
  254. if (configIndex != -1)
  255. {
  256. classElement.GetSubElement(configIndex).SetData<CylinderShapeConfig>(context, configuration);
  257. }
  258. return true;
  259. }
  260. return false;
  261. }
  262. } // namespace ClassConverters
  263. } // namespace LmbrCentral