Shape.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /**
  2. * Copyright (c) 2006-2012 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 "Shape.h"
  21. // Module
  22. #include "Body.h"
  23. #include "World.h"
  24. #include "Physics.h"
  25. #include <common/Memoizer.h>
  26. // STD
  27. #include <bitset>
  28. namespace love
  29. {
  30. namespace physics
  31. {
  32. namespace box2d
  33. {
  34. Shape::Shape()
  35. : shape(NULL)
  36. {
  37. }
  38. Shape::Shape(b2Shape * shape)
  39. : shape(shape)
  40. {
  41. Memoizer::add(shape, this);
  42. }
  43. Shape::~Shape()
  44. {
  45. if (shape)
  46. {
  47. Memoizer::remove(shape);
  48. delete shape;
  49. }
  50. shape = 0;
  51. }
  52. Shape::Type Shape::getType() const
  53. {
  54. switch(shape->GetType())
  55. {
  56. case b2Shape::e_circle:
  57. return SHAPE_CIRCLE;
  58. case b2Shape::e_polygon:
  59. return SHAPE_POLYGON;
  60. case b2Shape::e_edge:
  61. return SHAPE_EDGE;
  62. case b2Shape::e_chain:
  63. return SHAPE_CHAIN;
  64. default:
  65. return SHAPE_INVALID;
  66. }
  67. }
  68. float Shape::getRadius() const
  69. {
  70. return Physics::scaleUp(shape->m_radius);
  71. }
  72. int Shape::getChildCount() const
  73. {
  74. return shape->GetChildCount();
  75. }
  76. bool Shape::testPoint(float x, float y, float r, float px, float py) const
  77. {
  78. b2Vec2 point(px, py);
  79. b2Transform transform(Physics::scaleDown(b2Vec2(x, y)), b2Rot(r));
  80. return shape->TestPoint(transform, Physics::scaleDown(point));
  81. }
  82. int Shape::rayCast(lua_State * L) const
  83. {
  84. float p1x = Physics::scaleDown((float)luaL_checknumber(L, 1));
  85. float p1y = Physics::scaleDown((float)luaL_checknumber(L, 2));
  86. float p2x = Physics::scaleDown((float)luaL_checknumber(L, 3));
  87. float p2y = Physics::scaleDown((float)luaL_checknumber(L, 4));
  88. float maxFraction = (float)luaL_checknumber(L, 5);
  89. float x = Physics::scaleDown((float)luaL_checknumber(L, 6));
  90. float y = Physics::scaleDown((float)luaL_checknumber(L, 7));
  91. float r = (float)luaL_checknumber(L, 8);
  92. int childIndex = (int)luaL_optint(L, 9, 1) - 1; // Convert from 1-based index
  93. b2RayCastInput input;
  94. input.p1.Set(p1x, p1y);
  95. input.p2.Set(p2x, p2y);
  96. input.maxFraction = maxFraction;
  97. b2Transform transform(b2Vec2(x, y), b2Rot(r));
  98. b2RayCastOutput output;
  99. if (!shape->RayCast(&output, input, transform, childIndex))
  100. return 0; // No hit.
  101. lua_pushnumber(L, Physics::scaleUp(output.normal.x));
  102. lua_pushnumber(L, Physics::scaleUp(output.normal.y));
  103. lua_pushnumber(L, output.fraction);
  104. return 3;
  105. }
  106. int Shape::computeAABB(lua_State * L) const
  107. {
  108. float x = Physics::scaleDown((float)luaL_checknumber(L, 1));
  109. float y = Physics::scaleDown((float)luaL_checknumber(L, 2));
  110. float r = (float)luaL_checknumber(L, 3);
  111. int childIndex = (int)luaL_optint(L, 4, 1) - 1; // Convert from 1-based index
  112. b2Transform transform(b2Vec2(x, y), b2Rot(r));
  113. b2AABB box;
  114. shape->ComputeAABB(&box, transform, childIndex);
  115. box = Physics::scaleUp(box);
  116. lua_pushnumber(L, box.lowerBound.x);
  117. lua_pushnumber(L, box.lowerBound.y);
  118. lua_pushnumber(L, box.upperBound.x);
  119. lua_pushnumber(L, box.upperBound.y);
  120. return 4;
  121. }
  122. int Shape::computeMass(lua_State * L) const
  123. {
  124. float density = (float)luaL_checknumber(L, 1);
  125. b2MassData data;
  126. shape->ComputeMass(&data, density);
  127. b2Vec2 center = Physics::scaleUp(data.center);
  128. lua_pushnumber(L, center.x);
  129. lua_pushnumber(L, center.y);
  130. lua_pushnumber(L, data.mass);
  131. lua_pushnumber(L, Physics::scaleUp(Physics::scaleUp(data.I)));
  132. return 4;
  133. }
  134. } // box2d
  135. } // physics
  136. } // love