box2d_Body.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "box2dw.hpp"
  2. namespace pkpy{
  3. void PyBody::_register(VM* vm, PyObject* mod, PyObject* type){
  4. vm->bind(type, "__new__(cls, world: World, node: _NodeLike = None)",
  5. [](VM* vm, ArgsView args){
  6. PyWorld& world = CAST(PyWorld&, args[1]);
  7. PyObject* node = args[2];
  8. PyObject* obj = vm->heap.gcnew<PyBody>(PyBody::_type(vm));
  9. PyBody& body = _CAST(PyBody&, obj);
  10. b2BodyDef def;
  11. def.type = b2_dynamicBody;
  12. // a weak reference to this object
  13. def.userData.pointer = reinterpret_cast<uintptr_t>(obj);
  14. body.body = world.world.CreateBody(&def);
  15. body.node_like = node;
  16. return obj;
  17. });
  18. PY_PROPERTY(PyBody, "type: int", _b2Body, GetType, SetType)
  19. PY_PROPERTY(PyBody, "gravity_scale: float", _b2Body, GetGravityScale, SetGravityScale)
  20. PY_PROPERTY(PyBody, "fixed_rotation: bool", _b2Body, IsFixedRotation, SetFixedRotation)
  21. PY_PROPERTY(PyBody, "enabled: bool", _b2Body, IsEnabled, SetEnabled)
  22. PY_PROPERTY(PyBody, "bullet: bool", _b2Body, IsBullet, SetBullet)
  23. PY_READONLY_PROPERTY(PyBody, "mass: float", _b2Body, GetMass)
  24. PY_READONLY_PROPERTY(PyBody, "inertia: float", _b2Body, GetInertia)
  25. PY_PROPERTY(PyBody, "position: vec2", _, get_position, set_position)
  26. PY_PROPERTY(PyBody, "rotation: float", _, get_rotation, set_rotation)
  27. PY_PROPERTY(PyBody, "velocity: vec2", _, get_velocity, set_velocity)
  28. PY_PROPERTY(PyBody, "angular_velocity: float", _b2Body, GetAngularVelocity, SetAngularVelocity)
  29. PY_PROPERTY(PyBody, "damping: float", _b2Body, GetLinearDamping, SetLinearDamping)
  30. PY_PROPERTY(PyBody, "angular_damping: float", _b2Body, GetAngularDamping, SetAngularDamping)
  31. PY_PROPERTY(PyBody, "density: float", _b2Fixture, GetDensity, SetDensity)
  32. PY_PROPERTY(PyBody, "friction: float", _b2Fixture, GetFriction, SetFriction)
  33. PY_PROPERTY(PyBody, "restitution: float", _b2Fixture, GetRestitution, SetRestitution)
  34. PY_PROPERTY(PyBody, "restitution_threshold: float", _b2Fixture, GetRestitutionThreshold, SetRestitutionThreshold)
  35. PY_PROPERTY(PyBody, "is_sensor: bool", _b2Fixture, IsSensor, SetSensor)
  36. vm->bind(type, "set_box_shape(self, hx: float, hy: float)",
  37. [](VM* vm, ArgsView args){
  38. PyBody& body = CAST(PyBody&, args[0]);
  39. float hx = CAST(float, args[1]);
  40. float hy = CAST(float, args[2]);
  41. b2PolygonShape shape;
  42. shape.SetAsBox(hx, hy);
  43. body._set_b2Fixture(body.body->CreateFixture(&shape, 1.0f));
  44. return vm->None;
  45. });
  46. vm->bind(type, "set_circle_shape(self, radius: float)",
  47. [](VM* vm, ArgsView args){
  48. PyBody& body = CAST(PyBody&, args[0]);
  49. float radius = CAST(float, args[1]);
  50. b2CircleShape shape;
  51. shape.m_radius = radius;
  52. body._set_b2Fixture(body.body->CreateFixture(&shape, 1.0f));
  53. return vm->None;
  54. });
  55. vm->bind(type, "set_polygon_shape(self, points: list[vec2])",
  56. [](VM* vm, ArgsView args){
  57. PyBody& body = CAST(PyBody&, args[0]);
  58. List& points = CAST(List&, args[1]);
  59. if(points.size() < 3 || points.size() > b2_maxPolygonVertices){
  60. vm->ValueError("invalid vertices count");
  61. }
  62. b2PolygonShape shape;
  63. std::vector<b2Vec2> vertices;
  64. for(auto& point : points){
  65. Vec2 vec = CAST(Vec2, point);
  66. vertices.push_back(b2Vec2(vec.x, vec.y));
  67. }
  68. shape.Set(vertices.data(), vertices.size());
  69. body._set_b2Fixture(body.body->CreateFixture(&shape, 1.0f));
  70. return vm->None;
  71. });
  72. vm->bind(type, "set_chain_shape(self, points: list[vec2])",
  73. [](VM* vm, ArgsView args){
  74. PyBody& body = CAST(PyBody&, args[0]);
  75. List& points = CAST(List&, args[1]);
  76. if(points.size() < 3){
  77. vm->ValueError("invalid vertices count");
  78. }
  79. b2ChainShape shape;
  80. std::vector<b2Vec2> vertices;
  81. for(auto& point : points){
  82. Vec2 vec = CAST(Vec2, point);
  83. vertices.push_back(b2Vec2(vec.x, vec.y));
  84. }
  85. shape.CreateLoop(vertices.data(), vertices.size());
  86. body._set_b2Fixture(body.body->CreateFixture(&shape, 1.0f));
  87. return vm->None;
  88. });
  89. // methods
  90. _bind(vm, type, "apply_force(self, force: vec2, point: vec2)", &PyBody::apply_force);
  91. _bind(vm, type, "apply_force_to_center(self, force: vec2)", &PyBody::apply_force_to_center);
  92. _bind(vm, type, "apply_torque(self, torque: float)", &PyBody::apply_torque);
  93. _bind(vm, type, "apply_impulse(self, impulse: vec2, point: vec2)", &PyBody::apply_impulse);
  94. _bind(vm, type, "apply_impulse_to_center(self, impulse: vec2)", &PyBody::apply_impulse_to_center);
  95. _bind(vm, type, "apply_angular_impulse(self, impulse: float)", &PyBody::apply_angular_impulse);
  96. // get_node
  97. vm->bind(type, "get_node(self)", [](VM* vm, ArgsView args){
  98. PyBody& body = CAST(PyBody&, args[0]);
  99. return body.node_like;
  100. });
  101. // get_contacts
  102. vm->bind(type, "get_contacts(self) -> list[Body]", [](VM* vm, ArgsView args){
  103. PyBody& self = _CAST(PyBody&, args[0]);
  104. b2ContactEdge* edge = self.body->GetContactList();
  105. List list;
  106. while(edge){
  107. b2Fixture* fixtureB = edge->contact->GetFixtureB();
  108. b2Body* bodyB = fixtureB->GetBody();
  109. list.push_back(get_body_object(bodyB));
  110. edge = edge->next;
  111. }
  112. return VAR(std::move(list));
  113. });
  114. // destroy
  115. vm->bind(type, "destroy(self)", [](VM* vm, ArgsView args){
  116. PyBody& body = CAST(PyBody&, args[0]);
  117. body._is_destroyed = true; // mark as destroyed
  118. return vm->None;
  119. });
  120. }
  121. } // namespace pkpy