NetworkRigidBodyComponent.cpp 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * 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.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0 OR MIT
  5. *
  6. */
  7. #include <Source/Components/NetworkRigidBodyComponent.h>
  8. #include <AzFramework/Components/TransformComponent.h>
  9. #include <AzFramework/Physics/RigidBodyBus.h>
  10. #include <AzFramework/Physics/SimulatedBodies/RigidBody.h>
  11. namespace MultiplayerSample
  12. {
  13. AZ_CVAR_EXTERNED(float, bg_RewindPositionTolerance);
  14. AZ_CVAR_EXTERNED(float, bg_RewindOrientationTolerance);
  15. void NetworkRigidBodyComponent::NetworkRigidBodyComponent::Reflect(AZ::ReflectContext* context)
  16. {
  17. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  18. if (serializeContext)
  19. {
  20. serializeContext->Class<NetworkRigidBodyComponent, NetworkRigidBodyComponentBase>()->Version(1);
  21. }
  22. NetworkRigidBodyComponentBase::Reflect(context);
  23. }
  24. NetworkRigidBodyComponent::NetworkRigidBodyComponent()
  25. : m_syncRewindHandler([this](){ OnSyncRewind(); })
  26. , m_transformChangedHandler([this]([[maybe_unused]] const AZ::Transform& localTm, const AZ::Transform& worldTm){ OnTransformUpdate(worldTm); })
  27. {
  28. }
  29. void NetworkRigidBodyComponent::OnInit()
  30. {
  31. }
  32. void NetworkRigidBodyComponent::OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
  33. {
  34. GetNetBindComponent()->AddEntitySyncRewindEventHandler(m_syncRewindHandler);
  35. GetEntity()->FindComponent<AzFramework::TransformComponent>()->BindTransformChangedEventHandler(m_transformChangedHandler);
  36. m_physicsRigidBodyComponent =
  37. Physics::RigidBodyRequestBus::FindFirstHandler(GetEntity()->GetId());
  38. AZ_Assert(m_physicsRigidBodyComponent, "PhysX Rigid Body Component is required on entity %s", GetEntity()->GetName().c_str());
  39. if (!HasController())
  40. {
  41. m_physicsRigidBodyComponent->SetKinematic(true);
  42. }
  43. }
  44. void NetworkRigidBodyComponent::OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating)
  45. {
  46. }
  47. void NetworkRigidBodyComponent::OnTransformUpdate(const AZ::Transform& worldTm)
  48. {
  49. m_transform = worldTm;
  50. if (!HasController())
  51. {
  52. m_physicsRigidBodyComponent->SetKinematicTarget(worldTm);
  53. }
  54. }
  55. void NetworkRigidBodyComponent::OnSyncRewind()
  56. {
  57. uint32_t frameId = static_cast<uint32_t>(Multiplayer::GetNetworkTime()->GetHostFrameId());
  58. AzPhysics::RigidBody* rigidBody = m_physicsRigidBodyComponent->GetRigidBody();
  59. rigidBody->SetFrameId(frameId);
  60. const AZ::Transform& rewoundTransform = m_transform.Get();
  61. const AZ::Transform& physicsTransform = rigidBody->GetTransform();
  62. // Don't call SetLocalPose unless the transforms are actually different
  63. const AZ::Vector3 positionDelta = physicsTransform.GetTranslation() - rewoundTransform.GetTranslation();
  64. const AZ::Quaternion orientationDelta = physicsTransform.GetRotation() - rewoundTransform.GetRotation();
  65. if ((positionDelta.GetLengthSq() >= bg_RewindPositionTolerance) ||
  66. (orientationDelta.GetLengthSq() >= bg_RewindOrientationTolerance))
  67. {
  68. rigidBody->SetTransform(rewoundTransform);
  69. }
  70. }
  71. } // namespace MultiplayerSample