Shape.cpp 5.8 KB

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