CollisionChain2D.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "../Precompiled.h"
  4. #include "../Core/Context.h"
  5. #include "../IO/MemoryBuffer.h"
  6. #include "../IO/VectorBuffer.h"
  7. #include "../Physics2D/CollisionChain2D.h"
  8. #include "../Physics2D/PhysicsUtils2D.h"
  9. #include "../DebugNew.h"
  10. namespace Urho3D
  11. {
  12. extern const char* PHYSICS2D_CATEGORY;
  13. CollisionChain2D::CollisionChain2D(Context* context) :
  14. CollisionShape2D(context),
  15. loop_(false)
  16. {
  17. fixtureDef_.shape = &chainShape_;
  18. }
  19. CollisionChain2D::~CollisionChain2D() = default;
  20. void CollisionChain2D::RegisterObject(Context* context)
  21. {
  22. context->RegisterFactory<CollisionChain2D>(PHYSICS2D_CATEGORY);
  23. URHO3D_ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, true, AM_DEFAULT);
  24. URHO3D_ACCESSOR_ATTRIBUTE("Loop", GetLoop, SetLoop, false, AM_DEFAULT);
  25. URHO3D_COPY_BASE_ATTRIBUTES(CollisionShape2D);
  26. URHO3D_ACCESSOR_ATTRIBUTE("Vertices", GetVerticesAttr, SetVerticesAttr, Variant::emptyBuffer, AM_FILE);
  27. }
  28. void CollisionChain2D::SetLoop(bool loop)
  29. {
  30. if (loop == loop_)
  31. return;
  32. loop_ = loop;
  33. MarkNetworkUpdate();
  34. RecreateFixture();
  35. }
  36. void CollisionChain2D::SetVertexCount(i32 count)
  37. {
  38. assert(count >= 0);
  39. vertices_.Resize(count);
  40. }
  41. void CollisionChain2D::SetVertex(i32 index, const Vector2& vertex)
  42. {
  43. assert(index >= 0);
  44. if (index >= vertices_.Size())
  45. return;
  46. vertices_[index] = vertex;
  47. if (index == vertices_.Size() - 1)
  48. {
  49. MarkNetworkUpdate();
  50. RecreateFixture();
  51. }
  52. }
  53. void CollisionChain2D::SetVertices(const Vector<Vector2>& vertices)
  54. {
  55. vertices_ = vertices;
  56. MarkNetworkUpdate();
  57. RecreateFixture();
  58. }
  59. void CollisionChain2D::SetVerticesAttr(const Vector<byte>& value)
  60. {
  61. if (value.Empty())
  62. return;
  63. Vector<Vector2> vertices;
  64. MemoryBuffer buffer(value);
  65. while (!buffer.IsEof())
  66. vertices.Push(buffer.ReadVector2());
  67. SetVertices(vertices);
  68. }
  69. Vector<byte> CollisionChain2D::GetVerticesAttr() const
  70. {
  71. VectorBuffer ret;
  72. for (const Vector2& vertex : vertices_)
  73. ret.WriteVector2(vertex);
  74. return ret.GetBuffer();
  75. }
  76. void CollisionChain2D::ApplyNodeWorldScale()
  77. {
  78. RecreateFixture();
  79. }
  80. void CollisionChain2D::RecreateFixture()
  81. {
  82. ReleaseFixture();
  83. Vector<b2Vec2> b2Vertices;
  84. i32 count = vertices_.Size();
  85. b2Vertices.Resize(count);
  86. Vector2 worldScale(cachedWorldScale_.x_, cachedWorldScale_.y_);
  87. for (i32 i = 0; i < count; ++i)
  88. b2Vertices[i] = ToB2Vec2(vertices_[i] * worldScale);
  89. chainShape_.Clear();
  90. if (loop_)
  91. {
  92. if (count < 2)
  93. return;
  94. chainShape_.CreateLoop(&b2Vertices[0], count);
  95. }
  96. else
  97. {
  98. if (count < 4)
  99. return;
  100. chainShape_.CreateChain(&b2Vertices[1], count - 2, b2Vertices[0], b2Vertices[count - 1]);
  101. }
  102. CreateFixture();
  103. }
  104. }