diff --git a/Gems/ROS2/Code/CMakeLists.txt b/Gems/ROS2/Code/CMakeLists.txt index 9b5931d703..815bb6374f 100644 --- a/Gems/ROS2/Code/CMakeLists.txt +++ b/Gems/ROS2/Code/CMakeLists.txt @@ -41,6 +41,7 @@ ly_add_target( Gem::Atom_RPI.Public Gem::Atom_Feature_Common.Static Gem::Atom_Component_DebugCamera.Static + Gem::AtomLyIntegration_CommonFeatures.Editor.Static Gem::StartingPointInput Gem::PhysX.Static Gem::LmbrCentral.API diff --git a/Gems/ROS2/Code/Source/FactorySimulation/ConveyorBeltComponentKinematic.cpp b/Gems/ROS2/Code/Source/FactorySimulation/ConveyorBeltComponentKinematic.cpp index 53ed4cc2e0..38ce1640ab 100644 --- a/Gems/ROS2/Code/Source/FactorySimulation/ConveyorBeltComponentKinematic.cpp +++ b/Gems/ROS2/Code/Source/FactorySimulation/ConveyorBeltComponentKinematic.cpp @@ -6,32 +6,59 @@ * */ #include "ConveyorBeltComponentKinematic.h" +#include +#include #include #include #include #include #include +#include +#include #include #include #include #include namespace ROS2 { + static AZ::Data::AssetId GetDefaultPhysicsMaterialAssetId() + { + // Used for Edit Context. + // When the physics material asset property doesn't have an asset assigned it + // will show "(default)" to indicate that the default material will be used. + if (auto* materialManager = AZ::Interface::Get()) + { + if (AZStd::shared_ptr defaultMaterial = materialManager->GetDefaultMaterial()) + { + return defaultMaterial->GetMaterialAsset().GetId(); + } + } + return {}; + } + void ConveyorBeltComponentKinematic::Reflect(AZ::ReflectContext* context) { if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() ->Version(1) + ->Field("BeltEntityId", &ConveyorBeltComponentKinematic::m_ConveyorEntityId) ->Field("Speed", &ConveyorBeltComponentKinematic::m_speed) ->Field("BeltWidth", &ConveyorBeltComponentKinematic::m_beltWidth) - ->Field("SegmentLength", &ConveyorBeltComponentKinematic::m_segmentLength); + ->Field("SegmentLength", &ConveyorBeltComponentKinematic::m_segmentLength) + ->Field("TextureScale", &ConveyorBeltComponentKinematic::m_textureScale) + ->Field("MaterialAsset", &ConveyorBeltComponentKinematic::m_materialAsset); if (AZ::EditContext* ec = serialize->GetEditContext()) { ec->Class("Conveyor Belt Component Kinematic", "Conveyor Belt Component") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::Category, "ROS2") ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game")) + ->DataElement( + AZ::Edit::UIHandlers::EntityId, + &ConveyorBeltComponentKinematic::m_ConveyorEntityId, + "Conveyor Belt Entity", + "Entity of the conveyor belt") ->DataElement( AZ::Edit::UIHandlers::Default, &ConveyorBeltComponentKinematic::m_speed, "Speed", "Speed of the conveyor belt") ->DataElement(AZ::Edit::UIHandlers::Default, &ConveyorBeltComponentKinematic::m_beltWidth, "Width", "Belt width") @@ -40,7 +67,21 @@ namespace ROS2 &ConveyorBeltComponentKinematic::m_segmentLength, "Segment Length", "Length of simulated segments. Short segments causes larger number individual bodies to simulate and challenges " - "physics engine."); + "physics engine.") + ->DataElement( + AZ::Edit::UIHandlers::Default, + &ConveyorBeltComponentKinematic::m_textureScale, + "Texture scale", + "Scale of the texture on conveyor belt.") + ->DataElement( + AZ::Edit::UIHandlers::Default, + &ConveyorBeltComponentKinematic::m_materialAsset, + "Material", + "Material asset of the conveyor belt") + ->Attribute(AZ::Edit::Attributes::DefaultAsset, &GetDefaultPhysicsMaterialAssetId) + ->Attribute(AZ_CRC_CE("EditButton"), "") + ->Attribute(AZ_CRC_CE("EditDescription"), "Open in Asset Editor") + ->Attribute(AZ_CRC_CE("DisableEditButtonWhenNoAssetSelected"), true); } } } @@ -52,7 +93,7 @@ namespace ROS2 void ConveyorBeltComponentKinematic::Activate() { - m_initilized = false; + m_initialized = false; AZ::TickBus::Handler::BusConnect(); } @@ -66,7 +107,7 @@ namespace ROS2 AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle handle) { AzPhysics::SceneInterface* sceneInterface = AZ::Interface::Get(); - AZ_Assert(sceneInterface, "No scene intreface"); + AZ_Assert(sceneInterface, "No scene interface"); auto* body = azdynamic_cast(sceneInterface->GetSimulatedBodyFromHandle(sceneHandle, handle)); AZ_Assert(body, "No valid body found"); if (body) @@ -83,6 +124,8 @@ namespace ROS2 AzPhysics::SceneHandle sceneHandle, float normalizedLocation) { + auto colliderConfiguration = AZStd::make_shared(); + colliderConfiguration->m_materialSlots.SetMaterialAsset(0, m_materialAsset); auto shapeConfiguration = AZStd::make_shared(AZ::Vector3(m_segmentLength, m_beltWidth, m_segmentWidth)); const auto transform = GetTransformFromSpline(m_splineConsPtr, normalizedLocation); @@ -90,8 +133,7 @@ namespace ROS2 conveyorSegmentRigidBodyConfig.m_kinematic = true; conveyorSegmentRigidBodyConfig.m_position = transform.GetTranslation(); conveyorSegmentRigidBodyConfig.m_orientation = transform.GetRotation(); - conveyorSegmentRigidBodyConfig.m_colliderAndShapeData = - AzPhysics::ShapeColliderPair(AZStd::make_shared(), shapeConfiguration); + conveyorSegmentRigidBodyConfig.m_colliderAndShapeData = AzPhysics::ShapeColliderPair(colliderConfiguration, shapeConfiguration); conveyorSegmentRigidBodyConfig.m_computeCenterOfMass = true; conveyorSegmentRigidBodyConfig.m_computeInertiaTensor = true; conveyorSegmentRigidBodyConfig.m_startSimulationEnabled = true; @@ -104,7 +146,7 @@ namespace ROS2 return AZStd::make_pair(normalizedLocation, handle); } - void ConveyorBeltComponentKinematic::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) + void ConveyorBeltComponentKinematic::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) { AzPhysics::SystemInterface* physicsSystem = AZ::Interface::Get(); AZ_Assert(physicsSystem, "No physics system"); @@ -113,9 +155,9 @@ namespace ROS2 AzPhysics::SceneHandle defaultSceneHandle = sceneInterface->GetSceneHandle(AzPhysics::DefaultPhysicsSceneName); AZ_Assert(defaultSceneHandle != AzPhysics::InvalidSceneHandle, "Invalid default physics scene handle"); - // Initiliazation. Create segments and add to scene, attach post-simulation event, cache pointers,transform etc. + // Initialization. Create segments and add to scene, attach post-simulation event, cache pointers,transform etc. // Strong assumption is that conveyor belt is not transformed after initialization. - if (!m_initilized) + if (!m_initialized) { m_splineTransform = AZ::Transform::CreateIdentity(); AZ::TransformBus::EventResult(m_splineTransform, m_entity->GetId(), &AZ::TransformBus::Events::GetWorldTM); @@ -148,7 +190,7 @@ namespace ROS2 } AZ_Printf("ConveyorBeltComponentKinematic", "Initial Number of segments: %d", m_ConveyorSegments.size()); - m_initilized = true; + m_initialized = true; } } @@ -183,6 +225,23 @@ namespace ROS2 return c.second == AzPhysics::InvalidSimulatedBodyHandle; }), m_ConveyorSegments.end()); + + // move texture + if (m_ConveyorEntityId.IsValid()) + { + AZ::Render::MaterialAssignmentId materialId; + AZ::Render::MaterialComponentRequestBus::EventResult( + materialId, m_ConveyorEntityId, &AZ::Render::MaterialComponentRequestBus::Events::FindMaterialAssignmentId, -1, "Belt"); + + m_textureOffset += deltaTime * m_speed * m_textureScale; + + AZ::Render::MaterialComponentRequestBus::Event( + m_ConveyorEntityId, + &AZ::Render::MaterialComponentRequestBus::Events::SetPropertyValueT, + materialId, + "uv.offsetU", + m_textureOffset); + } } AZStd::pair ConveyorBeltComponentKinematic::GetStartAndEndPointOfBelt(AZ::ConstSplinePtr splinePtr) { diff --git a/Gems/ROS2/Code/Source/FactorySimulation/ConveyorBeltComponentKinematic.h b/Gems/ROS2/Code/Source/FactorySimulation/ConveyorBeltComponentKinematic.h index 46c8397bd4..c54a4143be 100644 --- a/Gems/ROS2/Code/Source/FactorySimulation/ConveyorBeltComponentKinematic.h +++ b/Gems/ROS2/Code/Source/FactorySimulation/ConveyorBeltComponentKinematic.h @@ -21,6 +21,7 @@ #include #include #include +#include #include namespace ROS2 @@ -91,20 +92,29 @@ namespace ROS2 float m_beltWidth = 1.0f; //! Length of individual segments of the conveyor belt float m_segmentLength = 1.0f; + //! Material of individual segments of the conveyor belt + AZ::Data::Asset m_materialAsset; //! Cache of created segments AZStd::deque> m_ConveyorSegments; //! Heigh of belt static constexpr float m_segmentWidth = 0.1f; + //! Offset of the texture + float m_textureOffset = 0.0f; + //! Scaling factor of the texture + float m_textureScale = 1.0f; //! Pointer to the spline AZ::ConstSplinePtr m_splineConsPtr{ nullptr }; //! Real spline length - float m_splineLength{ -1.f }; + float m_splineLength = -1.0f; //! Transform from spline's local frame to world frame AZ::Transform m_splineTransform; //! Start and end point of the belt AZ::Vector3 m_startPoint; AZ::Vector3 m_endPoint; - bool m_initilized{ false }; + //! Conveyor belt entity (used for texture movement) + AZ::EntityId m_ConveyorEntityId; + + bool m_initialized{ false }; }; } // namespace ROS2