Constraint2D.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //
  2. // Copyright (c) 2008-2020 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "../Precompiled.h"
  23. #include "../Core/Context.h"
  24. #include "../IO/Log.h"
  25. #include "../Scene/Node.h"
  26. #include "../Scene/Scene.h"
  27. #include "../Urho2D/Constraint2D.h"
  28. #include "../Urho2D/PhysicsUtils2D.h"
  29. #include "../Urho2D/RigidBody2D.h"
  30. #include "../Urho2D/PhysicsWorld2D.h"
  31. #include "../DebugNew.h"
  32. namespace Urho3D
  33. {
  34. extern const char* URHO2D_CATEGORY;
  35. Constraint2D::Constraint2D(Context* context) :
  36. Component(context)
  37. {
  38. }
  39. Constraint2D::~Constraint2D()
  40. {
  41. ReleaseJoint();
  42. }
  43. void Constraint2D::RegisterObject(Context* context)
  44. {
  45. URHO3D_ACCESSOR_ATTRIBUTE("Collide Connected", GetCollideConnected, SetCollideConnected, bool, false, AM_DEFAULT);
  46. URHO3D_ATTRIBUTE_EX("Other Body NodeID", unsigned, otherBodyNodeID_, MarkOtherBodyNodeIDDirty, 0, AM_DEFAULT | AM_NODEID);
  47. }
  48. void Constraint2D::ApplyAttributes()
  49. {
  50. // If other body node ID dirty, try to find it now and apply
  51. if (otherBodyNodeIDDirty_)
  52. {
  53. Scene* scene = GetScene();
  54. if (scene)
  55. {
  56. Node* otherNode = scene->GetNode(otherBodyNodeID_);
  57. if (otherNode)
  58. SetOtherBody(otherNode->GetComponent<RigidBody2D>());
  59. }
  60. otherBodyNodeIDDirty_ = false;
  61. }
  62. }
  63. void Constraint2D::OnSetEnabled()
  64. {
  65. if (IsEnabledEffective())
  66. CreateJoint();
  67. else
  68. ReleaseJoint();
  69. }
  70. void Constraint2D::CreateJoint()
  71. {
  72. if (joint_)
  73. return;
  74. b2JointDef* jointDef = GetJointDef();
  75. if (jointDef)
  76. {
  77. joint_ = physicsWorld_->GetWorld()->CreateJoint(jointDef);
  78. joint_->SetUserData(this);
  79. if (ownerBody_)
  80. ownerBody_->AddConstraint2D(this);
  81. if (otherBody_)
  82. otherBody_->AddConstraint2D(this);
  83. }
  84. }
  85. void Constraint2D::ReleaseJoint()
  86. {
  87. if (!joint_)
  88. return;
  89. if (ownerBody_)
  90. ownerBody_->RemoveConstraint2D(this);
  91. if (otherBody_)
  92. otherBody_->RemoveConstraint2D(this);
  93. if (physicsWorld_)
  94. physicsWorld_->GetWorld()->DestroyJoint(joint_);
  95. joint_ = nullptr;
  96. }
  97. void Constraint2D::SetOtherBody(RigidBody2D* body)
  98. {
  99. if (body == otherBody_)
  100. return;
  101. otherBody_ = body;
  102. Node* otherNode = body ? body->GetNode() : nullptr;
  103. otherBodyNodeID_ = otherNode ? otherNode->GetID() : 0;
  104. RecreateJoint();
  105. MarkNetworkUpdate();
  106. }
  107. void Constraint2D::SetCollideConnected(bool collideConnected)
  108. {
  109. if (collideConnected == collideConnected_)
  110. return;
  111. collideConnected_ = collideConnected;
  112. RecreateJoint();
  113. MarkNetworkUpdate();
  114. }
  115. void Constraint2D::SetAttachedConstraint(Constraint2D* constraint)
  116. {
  117. attachedConstraint_ = constraint;
  118. }
  119. void Constraint2D::OnNodeSet(Node* node)
  120. {
  121. Component::OnNodeSet(node);
  122. if (node)
  123. {
  124. ownerBody_ = node->GetComponent<RigidBody2D>();
  125. if (!ownerBody_)
  126. {
  127. URHO3D_LOGERROR("No right body component in node, can not create constraint");
  128. return;
  129. }
  130. }
  131. }
  132. void Constraint2D::OnSceneSet(Scene* scene)
  133. {
  134. if (scene)
  135. {
  136. physicsWorld_ = scene->GetDerivedComponent<PhysicsWorld2D>();
  137. if (!physicsWorld_)
  138. physicsWorld_ = scene->CreateComponent<PhysicsWorld2D>();
  139. }
  140. }
  141. void Constraint2D::InitializeJointDef(b2JointDef* jointDef)
  142. {
  143. jointDef->bodyA = ownerBody_->GetBody();
  144. jointDef->bodyB = otherBody_->GetBody();
  145. jointDef->collideConnected = collideConnected_;
  146. }
  147. void Constraint2D::RecreateJoint()
  148. {
  149. if (attachedConstraint_)
  150. attachedConstraint_->ReleaseJoint();
  151. ReleaseJoint();
  152. CreateJoint();
  153. if (attachedConstraint_)
  154. attachedConstraint_->CreateJoint();
  155. }
  156. }