/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "LmbrCentral_precompiled.h" #include "CapsuleShapeComponent.h" #include #include #include #include #include #include namespace LmbrCentral { void CapsuleShapeComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC("ShapeService", 0xe86aa5fe)); provided.push_back(AZ_CRC("CapsuleShapeService", 0x9bc1122c)); provided.push_back(AZ_CRC("AreaLightShapeService", 0x68ea78dc)); } void CapsuleShapeComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("ShapeService", 0xe86aa5fe)); incompatible.push_back(AZ_CRC("CapsuleShapeService", 0x9bc1122c)); incompatible.push_back(AZ_CRC("AreaLightShapeService", 0x68ea78dc)); } void CapsuleShapeComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); } void CapsuleShapeDebugDisplayComponent::Reflect(AZ::ReflectContext* context) { if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() ->Version(1) ->Field("Configuration", &CapsuleShapeDebugDisplayComponent::m_capsuleShapeConfig) ; } } void CapsuleShapeDebugDisplayComponent::Activate() { EntityDebugDisplayComponent::Activate(); ShapeComponentNotificationsBus::Handler::BusConnect(GetEntityId()); GenerateVertices(); } void CapsuleShapeDebugDisplayComponent::Deactivate() { ShapeComponentNotificationsBus::Handler::BusDisconnect(); EntityDebugDisplayComponent::Deactivate(); } void CapsuleShapeDebugDisplayComponent::Draw(AzFramework::DebugDisplayRequests& debugDisplay) { DrawShape(debugDisplay, m_capsuleShapeConfig.GetDrawParams(), m_capsuleShapeMesh); } bool CapsuleShapeDebugDisplayComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig) { if (const auto config = azrtti_cast(baseConfig)) { m_capsuleShapeConfig = *config; return true; } return false; } bool CapsuleShapeDebugDisplayComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const { if (auto outConfig = azrtti_cast(outBaseConfig)) { *outConfig = m_capsuleShapeConfig; return true; } return false; } void CapsuleShapeDebugDisplayComponent::GenerateVertices() { CapsuleGeometrySystemRequestBus::Broadcast( &CapsuleGeometrySystemRequestBus::Events::GenerateCapsuleMesh, m_capsuleShapeConfig.m_radius, m_capsuleShapeConfig.m_height, g_capsuleDebugShapeSides, g_capsuleDebugShapeCapSegments, m_capsuleShapeMesh.m_vertexBuffer, m_capsuleShapeMesh.m_indexBuffer, m_capsuleShapeMesh.m_lineBuffer ); } void CapsuleShapeDebugDisplayComponent::OnShapeChanged(ShapeChangeReasons changeReason) { if (changeReason == ShapeChangeReasons::ShapeChanged) { CapsuleShapeComponentRequestsBus::EventResult(m_capsuleShapeConfig, GetEntityId(), &CapsuleShapeComponentRequests::GetCapsuleConfiguration); GenerateVertices(); } } namespace ClassConverters { static bool DeprecateCapsuleColliderConfiguration(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement); static bool DeprecateCapsuleColliderComponent(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement); } void CapsuleShapeConfig::Reflect(AZ::ReflectContext* context) { if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { // Deprecate: CapsuleColliderConfiguration -> CapsuleShapeConfig serializeContext->ClassDeprecate( "CapsuleColliderConfiguration", "{902BCDA9-C9E5-429C-991B-74C241ED2889}", &ClassConverters::DeprecateCapsuleColliderConfiguration) ; serializeContext->Class() ->Version(2) ->Field("Height", &CapsuleShapeConfig::m_height) ->Field("Radius", &CapsuleShapeConfig::m_radius) ; if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { editContext->Class("Configuration", "Capsule shape configuration parameters") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(AZ::Edit::UIHandlers::Default, &CapsuleShapeConfig::m_height, "Height", "End to end height of capsule, this includes the cylinder and both caps") ->Attribute(AZ::Edit::Attributes::Min, 0.f) ->Attribute(AZ::Edit::Attributes::Suffix, " m") ->Attribute(AZ::Edit::Attributes::Step, 0.1f) ->DataElement(AZ::Edit::UIHandlers::Default, &CapsuleShapeConfig::m_radius, "Radius", "Radius of capsule") ->Attribute(AZ::Edit::Attributes::Min, 0.f) ->Attribute(AZ::Edit::Attributes::Suffix, " m") ->Attribute(AZ::Edit::Attributes::Step, 0.05f) ; } } if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->Class() ->Property("Height", BehaviorValueProperty(&CapsuleShapeConfig::m_height)) ->Property("Radius", BehaviorValueProperty(&CapsuleShapeConfig::m_radius)) ; } } void CapsuleShapeComponent::Reflect(AZ::ReflectContext* context) { CapsuleShape::Reflect(context); if (auto serializeContext = azrtti_cast(context)) { // Deprecate: CapsuleColliderComponent -> CapsuleShapeComponent serializeContext->ClassDeprecate( "CapsuleColliderComponent", "{D1F746A9-FC24-48E4-88DE-5B3122CB6DE7}", &ClassConverters::DeprecateCapsuleColliderComponent ); serializeContext->Class() ->Version(2, &ClassConverters::UpgradeCapsuleShapeComponent) ->Field("CapsuleShape", &CapsuleShapeComponent::m_capsuleShape) ; } if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->Constant("CapsuleShapeComponentTypeId", BehaviorConstant(CapsuleShapeComponentTypeId)); behaviorContext->EBus("CapsuleShapeComponentRequestsBus") ->Event("GetCapsuleConfiguration", &CapsuleShapeComponentRequestsBus::Events::GetCapsuleConfiguration) ->Event("SetHeight", &CapsuleShapeComponentRequestsBus::Events::SetHeight) ->Event("SetRadius", &CapsuleShapeComponentRequestsBus::Events::SetRadius) ; } } void CapsuleShapeComponent::Activate() { m_capsuleShape.Activate(GetEntityId()); } void CapsuleShapeComponent::Deactivate() { m_capsuleShape.Deactivate(); } bool CapsuleShapeComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig) { if (const auto config = azrtti_cast(baseConfig)) { m_capsuleShape.SetCapsuleConfiguration(*config); return true; } return false; } bool CapsuleShapeComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const { if (auto outConfig = azrtti_cast(outBaseConfig)) { *outConfig = m_capsuleShape.GetCapsuleConfiguration(); return true; } return false; } namespace ClassConverters { static bool DeprecateCapsuleColliderConfiguration(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) { /* Old: New: */ // Cache the Height and Radius float oldHeight = 0.f; float oldRadius = 0.f; int oldIndex = classElement.FindElement(AZ_CRC("Height", 0xf54de50f)); if (oldIndex != -1) { classElement.GetSubElement(oldIndex).GetData(oldHeight); } oldIndex = classElement.FindElement(AZ_CRC("Radius", 0x3b7c6e5a)); if (oldIndex != -1) { classElement.GetSubElement(oldIndex).GetData(oldRadius); } // Convert to CapsuleShapeConfig const bool result = classElement.Convert(context); if (result) { int newIndex = classElement.AddElement(context, "Height"); if (newIndex != -1) { classElement.GetSubElement(newIndex).SetData(context, oldHeight); } else { return false; } newIndex = classElement.AddElement(context, "Radius"); if (newIndex != -1) { classElement.GetSubElement(newIndex).SetData(context, oldRadius); return true; } } return false; } static bool DeprecateCapsuleColliderComponent(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) { /* Old: New: */ // Cache the Configuration CapsuleShapeConfig configuration; int configIndex = classElement.FindElement(AZ_CRC("Configuration", 0xa5e2a5d7)); if (configIndex != -1) { classElement.GetSubElement(configIndex).GetData(configuration); } // Convert to CapsuleShapeComponent const bool result = classElement.Convert(context); if (result) { configIndex = classElement.AddElement(context, "Configuration"); if (configIndex != -1) { classElement.GetSubElement(configIndex).SetData(context, configuration); } return true; } return false; } } // namespace ClassConverters } // namespace LmbrCentral