Shape.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /**
  2. * Copyright (c) 2006-2009 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. // STD
  25. #include <bitset>
  26. namespace love
  27. {
  28. namespace physics
  29. {
  30. namespace box2d
  31. {
  32. Shape::Shape(Body * body)
  33. : body(body)
  34. {
  35. body->retain();
  36. data = new shapeudata();
  37. data->ref = 0;
  38. }
  39. Shape::~Shape()
  40. {
  41. if(data->ref != 0)
  42. delete data->ref;
  43. delete data;
  44. data = 0;
  45. }
  46. int Shape::getType() const
  47. {
  48. switch(shape->GetType())
  49. {
  50. case e_circleShape:
  51. return SHAPE_CIRCLE;
  52. case e_polygonShape:
  53. return SHAPE_POLYGON;
  54. default:
  55. return -1;
  56. }
  57. }
  58. void Shape::setFriction(float friction)
  59. {
  60. shape->m_friction = friction;
  61. }
  62. void Shape::setRestitution(float restitution)
  63. {
  64. shape->m_restitution = restitution;
  65. }
  66. void Shape::setDensity(float density)
  67. {
  68. shape->m_density = density;
  69. }
  70. void Shape::setSensor(bool sensor)
  71. {
  72. shape->m_isSensor = sensor;
  73. }
  74. float Shape::getFriction() const
  75. {
  76. return shape->GetFriction();
  77. }
  78. float Shape::getRestituion() const
  79. {
  80. return shape->GetRestitution();
  81. }
  82. float Shape::getDensity() const
  83. {
  84. return shape->m_density;
  85. }
  86. bool Shape::isSensor() const
  87. {
  88. return shape->IsSensor();
  89. }
  90. Body * Shape::getBody() const
  91. {
  92. return body;
  93. }
  94. bool Shape::testPoint(float x, float y) const
  95. {
  96. return shape->TestPoint(shape->GetBody()->GetXForm(), body->world->scaleDown(b2Vec2(x, y)));
  97. }
  98. int Shape::testSegment(lua_State * L)
  99. {
  100. love::luax_assert_argc(L, 4, 4);
  101. b2Segment s;
  102. s.p1.x = (float)lua_tonumber(L, 1);
  103. s.p1.y = (float)lua_tonumber(L, 2);
  104. s.p2.x = (float)lua_tonumber(L, 3);
  105. s.p2.y = (float)lua_tonumber(L, 4);
  106. s.p1 = body->world->scaleDown(s.p1);
  107. s.p2 = body->world->scaleDown(s.p2);
  108. float lambda;
  109. b2Vec2 normal;
  110. if(shape->TestSegment(shape->GetBody()->GetXForm(), &lambda, &normal, s, 1.0f))
  111. {
  112. lua_pushnumber(L, lambda);
  113. normal = body->world->scaleUp(normal);
  114. lua_pushnumber(L, normal.x);
  115. lua_pushnumber(L, normal.y);
  116. return 3;
  117. }
  118. return 0;
  119. }
  120. void Shape::setFilterData(int * v)
  121. {
  122. b2FilterData f;
  123. f.categoryBits = (unsigned short)v[0];
  124. f.maskBits = (unsigned short)v[1];
  125. f.groupIndex = v[2];
  126. shape->SetFilterData(f);
  127. shape->GetBody()->GetWorld()->Refilter(shape);
  128. }
  129. void Shape::getFilterData(int * v)
  130. {
  131. b2FilterData f = shape->GetFilterData();
  132. v[0] = (int)f.categoryBits;
  133. v[1] = (int)f.maskBits;
  134. v[2] = f.groupIndex;
  135. }
  136. int Shape::setCategory(lua_State * L)
  137. {
  138. b2FilterData f = shape->GetFilterData();
  139. f.categoryBits = (uint16)getBits(L);
  140. shape->SetFilterData(f);
  141. shape->GetBody()->GetWorld()->Refilter(shape);
  142. return 0;
  143. }
  144. int Shape::setMask(lua_State * L)
  145. {
  146. b2FilterData f = shape->GetFilterData();
  147. f.maskBits = ~(uint16)getBits(L);
  148. shape->SetFilterData(f);
  149. shape->GetBody()->GetWorld()->Refilter(shape);
  150. return 0;
  151. }
  152. int Shape::getCategory(lua_State * L)
  153. {
  154. return pushBits(L, shape->GetFilterData().categoryBits);
  155. }
  156. int Shape::getMask(lua_State * L)
  157. {
  158. return pushBits(L, ~(shape->GetFilterData().maskBits));
  159. }
  160. uint16 Shape::getBits(lua_State * L)
  161. {
  162. // Get number of args.
  163. int argc = lua_gettop(L);
  164. // The new bitset.
  165. std::bitset<16> b;
  166. for(int i = 1;i<=argc;i++)
  167. {
  168. size_t bpos = (size_t)(lua_tointeger(L, i)-1);
  169. if(bpos < 0 || bpos > 16)
  170. return luaL_error(L, "Values must be in range 1-16.");
  171. b.set(bpos, true);
  172. }
  173. return (uint16)b.to_ulong();
  174. }
  175. int Shape::pushBits(lua_State * L, uint16 bits)
  176. {
  177. // Create a bitset.
  178. std::bitset<16> b((unsigned long)bits);
  179. // Push all set bits.
  180. for(int i = 0;i<16;i++)
  181. if(b.test(i))
  182. lua_pushinteger(L, i+1);
  183. // Count number of set bits.
  184. return (int)b.count();
  185. }
  186. int Shape::setData(lua_State * L)
  187. {
  188. love::luax_assert_argc(L, 1, 1);
  189. if(data->ref != 0)
  190. {
  191. delete data->ref;
  192. data->ref = 0;
  193. }
  194. data->ref = new Reference(L);
  195. return 0;
  196. }
  197. int Shape::getData(lua_State * L)
  198. {
  199. love::luax_assert_argc(L, 0, 0);
  200. if(data->ref != 0)
  201. data->ref->push();
  202. else
  203. lua_pushnil(L);
  204. return 1;
  205. }
  206. int Shape::getBoundingBox(lua_State * L)
  207. {
  208. love::luax_assert_argc(L, 0, 0);
  209. b2AABB bb;
  210. shape->ComputeAABB(&bb, shape->GetBody()->GetXForm());
  211. bb = body->world->scaleUp(bb);
  212. // Top left.
  213. lua_pushnumber(L, bb.lowerBound.x);
  214. lua_pushnumber(L, bb.upperBound.y);
  215. // Bottom left.
  216. lua_pushnumber(L, bb.lowerBound.x);
  217. lua_pushnumber(L, bb.lowerBound.y);
  218. // Bottom right.
  219. lua_pushnumber(L, bb.upperBound.x);
  220. lua_pushnumber(L, bb.lowerBound.y);
  221. // Top right.
  222. lua_pushnumber(L, bb.upperBound.x);
  223. lua_pushnumber(L, bb.upperBound.y);
  224. return 8;
  225. }
  226. } // box2d
  227. } // physics
  228. } // love