box2ddistancejoint.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Box2D QML plugin
  3. * Copyright (C) 2010 Nokia Corporation
  4. *
  5. * This file is part of the Box2D QML plugin.
  6. *
  7. * This library is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation; either version 2.1 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  15. * License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with this library; If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "box2ddistancejoint.h"
  21. #include "box2dworld.h"
  22. #include "box2dbody.h"
  23. Box2DDistanceJoint::Box2DDistanceJoint(QDeclarativeItem *parent) :
  24. Box2DJoint(parent),
  25. mDistanceJointDef(),
  26. mDistanceJoint(0),
  27. mOverrideAnchorLength(false),
  28. mLength(0),
  29. mOverrideLocalAnchorA(false),
  30. mOverrideLocalAnchorB(false)
  31. {
  32. }
  33. /*Box2DDistanceJoint::~Box2DDistanceJoint()
  34. {
  35. cleanup(world());
  36. }*/
  37. float Box2DDistanceJoint::length() const
  38. {
  39. return mOverrideAnchorLength ? mLength : mDistanceJointDef.length;
  40. }
  41. void Box2DDistanceJoint::setLength(float length)
  42. {
  43. if (mLength == length / scaleRatio)
  44. return;
  45. mOverrideAnchorLength = true;
  46. mLength = length / scaleRatio;
  47. if (mDistanceJoint)
  48. mDistanceJoint->SetLength(length / scaleRatio);
  49. emit lengthChanged();
  50. }
  51. float Box2DDistanceJoint::frequencyHz() const
  52. {
  53. return mDistanceJointDef.frequencyHz;
  54. }
  55. void Box2DDistanceJoint::setFrequencyHz(float frequencyHz)
  56. {
  57. if (mDistanceJointDef.frequencyHz == frequencyHz)
  58. return;
  59. mDistanceJointDef.frequencyHz = frequencyHz;
  60. if (mDistanceJoint)
  61. mDistanceJoint->SetFrequency(frequencyHz);
  62. emit frequencyHzChanged();
  63. }
  64. float Box2DDistanceJoint::dampingRatio() const
  65. {
  66. return mDistanceJointDef.dampingRatio;
  67. }
  68. void Box2DDistanceJoint::setDampingRatio(float dampingRatio)
  69. {
  70. if (mDistanceJointDef.dampingRatio == dampingRatio)
  71. return;
  72. mDistanceJointDef.dampingRatio = dampingRatio;
  73. if (mDistanceJoint)
  74. mDistanceJoint->SetDampingRatio(dampingRatio);
  75. emit dampingRatioChanged();
  76. }
  77. QPointF Box2DDistanceJoint::localAnchorA() const
  78. {
  79. if (mOverrideLocalAnchorA)
  80. return mLocalAnchorA;
  81. else
  82. return QPointF(mDistanceJointDef.localAnchorA.x * scaleRatio,
  83. -mDistanceJointDef.localAnchorA.y * scaleRatio);
  84. }
  85. void Box2DDistanceJoint::setLocalAnchorA(const QPointF &localAnchorA)
  86. {
  87. if (mOverrideLocalAnchorA && mLocalAnchorA == localAnchorA)
  88. return;
  89. mOverrideLocalAnchorA = true;
  90. mLocalAnchorA = localAnchorA;
  91. emit localAnchorAChanged();
  92. }
  93. QPointF Box2DDistanceJoint::localAnchorB() const
  94. {
  95. if (mOverrideLocalAnchorB)
  96. return mLocalAnchorB;
  97. else
  98. return QPointF(mDistanceJointDef.localAnchorB.x * scaleRatio,
  99. -mDistanceJointDef.localAnchorB.y * scaleRatio);
  100. }
  101. void Box2DDistanceJoint::setLocalAnchorB(const QPointF &localAnchorB)
  102. {
  103. if (mOverrideLocalAnchorB && mLocalAnchorB == localAnchorB)
  104. return;
  105. mOverrideLocalAnchorB = true;
  106. mLocalAnchorB = localAnchorB;
  107. emit localAnchorBChanged();
  108. }
  109. void Box2DDistanceJoint::createJoint()
  110. {
  111. b2Vec2 anchorA = mOverrideLocalAnchorA ?
  112. b2Vec2(mLocalAnchorA.x() / scaleRatio, -mLocalAnchorA.y() / scaleRatio) + bodyA()->body()->GetPosition() :
  113. bodyA()->body()->GetWorldCenter();
  114. b2Vec2 anchorB = mOverrideLocalAnchorB ?
  115. b2Vec2(mLocalAnchorB.x() / scaleRatio, -mLocalAnchorB.y() / scaleRatio) + bodyB()->body()->GetPosition() :
  116. bodyB()->body()->GetWorldCenter();
  117. mDistanceJointDef.Initialize(bodyA()->body(), bodyB()->body(),
  118. anchorA, anchorB);
  119. mDistanceJointDef.collideConnected = collideConnected();
  120. if (mOverrideAnchorLength)
  121. mDistanceJointDef.length = mLength;
  122. mDistanceJoint = static_cast<b2DistanceJoint*>(world()->CreateJoint(&mDistanceJointDef));
  123. mInitializePending = false;
  124. }
  125. void Box2DDistanceJoint::release()
  126. {
  127. if (!mReleased)
  128. mReleased = true;
  129. cleanup(world());
  130. }
  131. void Box2DDistanceJoint::grab()
  132. {
  133. if (mReleased)
  134. mReleased = false;
  135. createJoint();
  136. }
  137. void Box2DDistanceJoint::cleanup(b2World *world)
  138. {
  139. if (mDistanceJoint && bodyA() && bodyB()) {
  140. mDistanceJoint->SetUserData(0);
  141. world->DestroyJoint(mDistanceJoint);
  142. mDistanceJoint = 0;
  143. }
  144. }