box2d_bindings.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #pragma once
  2. #include "box2d/box2d.h"
  3. #include "pocketpy/pocketpy.h"
  4. #include <cstdlib>
  5. namespace pkpy{
  6. template<>
  7. inline b2Vec2 py_cast<b2Vec2>(VM* vm, PyObject* obj){
  8. Vec2 v = py_cast<Vec2>(vm, obj);
  9. return b2Vec2(v.x, v.y);
  10. }
  11. template<>
  12. inline b2Vec2 _py_cast<b2Vec2>(VM* vm, PyObject* obj){
  13. Vec2 v = _py_cast<Vec2>(vm, obj);
  14. return b2Vec2(v.x, v.y);
  15. }
  16. inline PyObject* py_var(VM* vm, b2Vec2 v){
  17. return py_var(vm, Vec2(v.x, v.y));
  18. }
  19. namespace imbox2d{
  20. struct Body final{
  21. b2Body* body;
  22. b2Fixture* fixture;
  23. PyObject* obj;
  24. Vec4 debug_color;
  25. Body(b2World* world, PyObject* obj){
  26. b2BodyDef def;
  27. def.type = b2_dynamicBody;
  28. // a weak reference to the object, no need to mark it
  29. def.userData.pointer = reinterpret_cast<uintptr_t>(this);
  30. body = world->CreateBody(&def);
  31. fixture = nullptr;
  32. this->obj = obj;
  33. this->debug_color = Vec4(std::rand() / float(RAND_MAX), std::rand() / float(RAND_MAX), std::rand() / float(RAND_MAX), 1.0f);
  34. }
  35. void _update_fixture(b2Shape* shape){
  36. body->DestroyFixture(fixture); // this takes care of NULL case
  37. fixture = body->CreateFixture(shape, 1.0f);
  38. }
  39. Vec4 get_debug_color() const{ return debug_color; }
  40. b2Vec2 get_position() const{ return body->GetPosition(); }
  41. void set_position(b2Vec2 v){ body->SetTransform(v, get_rotation()); }
  42. void set_rotation(float angle){ body->SetTransform(get_position(), angle); }
  43. float get_rotation() const{ return body->GetAngle(); }
  44. void set_velocity(b2Vec2 v){ body->SetLinearVelocity(v); }
  45. b2Vec2 get_velocity() const{ return body->GetLinearVelocity(); }
  46. void set_angular_velocity(float omega){ body->SetAngularVelocity(omega); }
  47. float get_angular_velocity() const{ return body->GetAngularVelocity(); }
  48. void set_damping(float damping){ body->SetLinearDamping(damping); }
  49. float get_damping(){ return body->GetLinearDamping(); }
  50. void set_angular_damping(float damping){ body->SetAngularDamping(damping); }
  51. float get_angular_damping() const{ return body->GetAngularDamping(); }
  52. void set_gravity_scale(float scale){ body->SetGravityScale(scale); }
  53. float get_gravity_scale() const{ return body->GetGravityScale(); }
  54. void set_type(int type){ body->SetType(static_cast<b2BodyType>(type)); }
  55. int get_type() const{ return static_cast<int>(body->GetType()); }
  56. float get_mass() const{ return body->GetMass(); }
  57. float get_inertia() const{ return body->GetInertia(); }
  58. bool get_fixed_rotation() const{ return body->IsFixedRotation(); }
  59. void set_fixed_rotation(bool fixed){ body->SetFixedRotation(fixed); }
  60. // fixture settings
  61. float get_density() const{ return fixture->GetDensity(); }
  62. void set_density(float density){ fixture->SetDensity(density); }
  63. float get_friction() const{ return fixture->GetFriction(); }
  64. void set_friction(float friction){ fixture->SetFriction(friction); }
  65. float get_restitution() const{ return fixture->GetRestitution(); }
  66. void set_restitution(float restitution){ fixture->SetRestitution(restitution); }
  67. float get_restitution_threshold() const{ return fixture->GetRestitutionThreshold(); }
  68. void set_restitution_threshold(float threshold){ fixture->SetRestitutionThreshold(threshold); }
  69. bool get_is_trigger() const{ return fixture->IsSensor(); }
  70. void set_is_trigger(bool trigger){ fixture->SetSensor(trigger); }
  71. // methods
  72. void apply_force(b2Vec2 force, b2Vec2 point){
  73. body->ApplyForce(force, point, true);
  74. }
  75. void apply_force_to_center(b2Vec2 force){
  76. body->ApplyForceToCenter(force, true);
  77. }
  78. void apply_torque(float torque){
  79. body->ApplyTorque(torque, true);
  80. }
  81. void apply_linear_impulse(b2Vec2 impulse, b2Vec2 point){
  82. body->ApplyLinearImpulse(impulse, point, true);
  83. }
  84. void apply_linear_impulse_to_center(b2Vec2 impulse){
  85. body->ApplyLinearImpulseToCenter(impulse, true);
  86. }
  87. void apply_angular_impulse(float impulse){
  88. body->ApplyAngularImpulse(impulse, true);
  89. }
  90. void destroy(){
  91. if(body == nullptr) return;
  92. body->GetWorld()->DestroyBody(body);
  93. body = nullptr;
  94. }
  95. };
  96. struct PyBody: OpaquePointer<Body>{
  97. PY_CLASS(PyBody, box2d, Body)
  98. using OpaquePointer<Body>::OpaquePointer;
  99. static void _register(VM* vm, PyObject* mod, PyObject* type);
  100. };
  101. struct PyWorld: OpaquePointer<b2World>{
  102. PY_CLASS(PyWorld, box2d, World)
  103. using OpaquePointer<b2World>::OpaquePointer;
  104. static void _register(VM* vm, PyObject* mod, PyObject* type);
  105. };
  106. } // namespace imbox2d
  107. void add_module_box2d(VM* vm);
  108. } // namespace pkpy