MouseJoint.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /**
  2. * Copyright (c) 2006-2022 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "MouseJoint.h"
  21. // Module
  22. #include "Body.h"
  23. #include "World.h"
  24. #include "Physics.h"
  25. #include <float.h>
  26. namespace love
  27. {
  28. namespace physics
  29. {
  30. namespace box2d
  31. {
  32. love::Type MouseJoint::type("MouseJoint", &Joint::type);
  33. MouseJoint::MouseJoint(Body *body1, float x, float y)
  34. : Joint(body1)
  35. , joint(NULL)
  36. {
  37. if (body1->getType() == Body::BODY_KINEMATIC)
  38. throw love::Exception("Cannot attach a MouseJoint to a kinematic body");
  39. b2MouseJointDef def;
  40. def.bodyA = body1->world->getGroundBody();
  41. def.bodyB = body1->body;
  42. def.maxForce = 1000.0f * body1->body->GetMass();
  43. def.target = Physics::scaleDown(b2Vec2(x,y));
  44. b2LinearStiffness(def.stiffness, def.damping, 5.0f, 0.7f, def.bodyA, def.bodyB);
  45. joint = (b2MouseJoint *)createJoint(&def);
  46. }
  47. MouseJoint::~MouseJoint()
  48. {
  49. }
  50. void MouseJoint::setTarget(float x, float y)
  51. {
  52. joint->SetTarget(Physics::scaleDown(b2Vec2(x, y)));
  53. }
  54. int MouseJoint::getTarget(lua_State *L)
  55. {
  56. lua_pushnumber(L, Physics::scaleUp(joint->GetTarget().x));
  57. lua_pushnumber(L, Physics::scaleUp(joint->GetTarget().y));
  58. return 2;
  59. }
  60. void MouseJoint::setMaxForce(float force)
  61. {
  62. joint->SetMaxForce(Physics::scaleDown(force));
  63. }
  64. float MouseJoint::getMaxForce() const
  65. {
  66. return Physics::scaleUp(joint->GetMaxForce());
  67. }
  68. void MouseJoint::setFrequency(float hz)
  69. {
  70. // This is kind of a crappy check. The Stiffness is used in an internal
  71. // box2d calculation whose result must be > FLT_EPSILON, but other variables
  72. // go into that calculation...
  73. if (hz <= FLT_EPSILON * 2)
  74. throw love::Exception("MouseJoint Stiffness must be a positive number.");
  75. float stiffness, damping;
  76. b2LinearStiffness(stiffness, damping, hz, getDampingRatio(), joint->GetBodyA(), joint->GetBodyB());
  77. joint->SetStiffness(stiffness);
  78. }
  79. float MouseJoint::getFrequency() const
  80. {
  81. float frequency, ratio;
  82. Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
  83. return frequency;
  84. }
  85. void MouseJoint::setDampingRatio(float ratio)
  86. {
  87. float stiffness, damping;
  88. b2LinearStiffness(stiffness, damping, getFrequency(), ratio, joint->GetBodyA(), joint->GetBodyB());
  89. joint->SetDamping(damping);
  90. }
  91. float MouseJoint::getDampingRatio() const
  92. {
  93. float frequency, ratio;
  94. Physics::b2LinearFrequency(frequency, ratio, joint->GetStiffness(), joint->GetDamping(), joint->GetBodyA(), joint->GetBodyB());
  95. return ratio;
  96. }
  97. void MouseJoint::setStiffness(float k)
  98. {
  99. // This is kind of a crappy check. The Stiffness is used in an internal
  100. // box2d calculation whose result must be > FLT_EPSILON, but other variables
  101. // go into that calculation...
  102. if (k <= FLT_EPSILON * 2)
  103. throw love::Exception("MouseJoint Stiffness must be a positive number.");
  104. joint->SetStiffness(k);
  105. }
  106. float MouseJoint::getStiffness() const
  107. {
  108. return joint->GetStiffness();
  109. }
  110. void MouseJoint::setDamping(float d)
  111. {
  112. joint->SetDamping(d);
  113. }
  114. float MouseJoint::getDamping() const
  115. {
  116. return joint->GetDamping();
  117. }
  118. Body *MouseJoint::getBodyA() const
  119. {
  120. return Joint::getBodyB();
  121. }
  122. Body *MouseJoint::getBodyB() const
  123. {
  124. return nullptr;
  125. }
  126. } // box2d
  127. } // physics
  128. } // love