From ee403e5de95726a1e8d92283b4e9141725153d0a Mon Sep 17 00:00:00 2001 From: Boscop Date: Fri, 4 Nov 2016 10:28:51 +0100 Subject: [PATCH 01/12] add b2PolygonShape_Set() --- .../Box2D/Collision/Shapes/c_b2PolygonShape.cpp | 4 ++++ liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h | 1 + src/box2d/collision/shapes/polygon_shape.rs | 10 ++++++++++ 3 files changed, 15 insertions(+) diff --git a/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp b/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp index f495615..21fa152 100644 --- a/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp +++ b/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp @@ -26,6 +26,10 @@ extern "C" { self->SetAsBox(hx, hy, center, angle); } + void b2PolygonShape_Set(b2PolygonShape* self, const b2Vec2* vertices, int32 count) { + self->Set(vertices, count); + } + b2Shape* b2PolygonShape_Upcast(b2PolygonShape* self) { return static_cast(reinterpret_cast(self)); } diff --git a/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h b/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h index 4259a27..c0afce2 100644 --- a/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h +++ b/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h @@ -11,6 +11,7 @@ extern "C" { int32 b2PolygonShape_GetVertexCount(const b2PolygonShape* self); void b2PolygonShape_SetAsBox(b2PolygonShape* self, float32 hx, float32 hy); void b2PolygonShape_SetAsBox_Oriented(b2PolygonShape* self, float32 hx, float32 hy, const b2Vec2& center, float32 angle); + void b2PolygonShape_Set(b2PolygonShape* self, const b2Vec2* vertices, int32 count); b2Shape* b2PolygonShape_Upcast(b2PolygonShape* self); diff --git a/src/box2d/collision/shapes/polygon_shape.rs b/src/box2d/collision/shapes/polygon_shape.rs index 4198e35..e78412a 100644 --- a/src/box2d/collision/shapes/polygon_shape.rs +++ b/src/box2d/collision/shapes/polygon_shape.rs @@ -11,6 +11,7 @@ extern { fn b2PolygonShape_New() -> *mut B2PolygonShape; fn b2PolygonShape_SetAsBox(ptr: *mut B2PolygonShape, hx: Float32, hy: Float32); fn b2PolygonShape_SetAsBox_Oriented(ptr: *mut B2PolygonShape, hx: Float32, hy: Float32, center: &Vec2, angle: Float32); + fn b2PolygonShape_Set(ptr: *mut B2PolygonShape, vertices: *const Vec2, count: Int32); fn b2PolygonShape_Upcast(ptr: *mut B2PolygonShape) -> *mut B2Shape; } @@ -79,6 +80,15 @@ impl PolygonShape { b2PolygonShape_SetAsBox_Oriented(self.ptr, hx, hy, center, angle); } } + + /// Build vertices to represent an axis-aligned box centered on the local origin. + /// @param hx the half-width. + /// @param hy the half-height. + pub fn set(&mut self, vertices: &[Vec2]) { + unsafe { + b2PolygonShape_Set(self.ptr, vertices.as_ptr(), vertices.len() as Int32); + } + } } impl Drop for PolygonShape { From 80eff3af24f0d7d51352235822704c316670d338 Mon Sep 17 00:00:00 2001 From: Boscop Date: Fri, 4 Nov 2016 15:19:18 +0100 Subject: [PATCH 02/12] add Body.set_transform() --- liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp | 8 ++++---- liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h | 3 +-- liquidfun-c/Box2D/Dynamics/c_b2Body.cpp | 4 ++++ liquidfun-c/Box2D/Dynamics/c_b2Body.h | 1 + src/box2d/collision/shapes/polygon_shape.rs | 2 +- src/box2d/dynamics/body.rs | 6 ++++++ src/lib.rs | 2 ++ 7 files changed, 19 insertions(+), 7 deletions(-) diff --git a/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp b/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp index 21fa152..9c31624 100644 --- a/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp +++ b/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp @@ -26,12 +26,12 @@ extern "C" { self->SetAsBox(hx, hy, center, angle); } - void b2PolygonShape_Set(b2PolygonShape* self, const b2Vec2* vertices, int32 count) { - self->Set(vertices, count); - } - b2Shape* b2PolygonShape_Upcast(b2PolygonShape* self) { return static_cast(reinterpret_cast(self)); } + void b2PolygonShape_Set(b2PolygonShape* self, const b2Vec2* vertices, int32 count) { + self->Set(vertices, count); + } + } // extern C \ No newline at end of file diff --git a/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h b/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h index c0afce2..0280755 100644 --- a/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h +++ b/liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h @@ -11,9 +11,8 @@ extern "C" { int32 b2PolygonShape_GetVertexCount(const b2PolygonShape* self); void b2PolygonShape_SetAsBox(b2PolygonShape* self, float32 hx, float32 hy); void b2PolygonShape_SetAsBox_Oriented(b2PolygonShape* self, float32 hx, float32 hy, const b2Vec2& center, float32 angle); - void b2PolygonShape_Set(b2PolygonShape* self, const b2Vec2* vertices, int32 count); b2Shape* b2PolygonShape_Upcast(b2PolygonShape* self); - + void b2PolygonShape_Set(b2PolygonShape* self, const b2Vec2* vertices, int32 count); #ifdef __cplusplus } // extern C diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp index d3e1adb..02035b5 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp @@ -39,5 +39,9 @@ extern "C" { return self->GetLocalPoint(worldPoint); } + void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle) { + self->SetTransform(position, angle); + } + } // extern C diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.h b/liquidfun-c/Box2D/Dynamics/c_b2Body.h index 162d8a7..fb28936 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.h +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.h @@ -14,6 +14,7 @@ extern "C" { void* b2Body_GetUserData(const b2Body* self); b2World* b2Body_GetWorld(b2Body* self); b2Vec2 b2Body_GetLocalPoint(const b2Body* self, const b2Vec2& worldPoint); + void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle); #ifdef __cplusplus } // extern C diff --git a/src/box2d/collision/shapes/polygon_shape.rs b/src/box2d/collision/shapes/polygon_shape.rs index e78412a..c39a894 100644 --- a/src/box2d/collision/shapes/polygon_shape.rs +++ b/src/box2d/collision/shapes/polygon_shape.rs @@ -11,8 +11,8 @@ extern { fn b2PolygonShape_New() -> *mut B2PolygonShape; fn b2PolygonShape_SetAsBox(ptr: *mut B2PolygonShape, hx: Float32, hy: Float32); fn b2PolygonShape_SetAsBox_Oriented(ptr: *mut B2PolygonShape, hx: Float32, hy: Float32, center: &Vec2, angle: Float32); - fn b2PolygonShape_Set(ptr: *mut B2PolygonShape, vertices: *const Vec2, count: Int32); fn b2PolygonShape_Upcast(ptr: *mut B2PolygonShape) -> *mut B2Shape; + fn b2PolygonShape_Set(ptr: *mut B2PolygonShape, vertices: *const Vec2, count: Int32); } /// A convex polygon. It is assumed that the interior of the polygon is to diff --git a/src/box2d/dynamics/body.rs b/src/box2d/dynamics/body.rs index eee3090..7c401f1 100644 --- a/src/box2d/dynamics/body.rs +++ b/src/box2d/dynamics/body.rs @@ -111,6 +111,7 @@ extern { fn b2Body_GetUserData(this: *const B2Body) -> usize; fn b2Body_GetWorld(this: *const B2Body) -> *mut B2World; fn b2Body_GetLocalPoint(this: *const B2Body, worldPoint: &Vec2) -> Vec2; + fn b2Body_SetTransform(this: *mut B2Body, position: &Vec2, angle: Float32); } /// A rigid body. These are created via b2World::CreateBody. @@ -213,4 +214,9 @@ impl Body { } } + pub fn set_transform(&mut self, position: &Vec2, angle: f32) { + unsafe { + b2Body_SetTransform(self.ptr, position, angle) + } + } } diff --git a/src/lib.rs b/src/lib.rs index 7b03920..b2e7187 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,8 @@ //! } //! ``` +#![allow(renamed_and_removed_lints)] + extern crate libc; #[macro_use] extern crate bitflags; From 708bd0779c4a70d76f7b210fe955788dc1a1f110 Mon Sep 17 00:00:00 2001 From: Boscop Date: Mon, 7 Nov 2016 08:50:45 +0100 Subject: [PATCH 03/12] Body.set_linear_velocity() --- liquidfun-c/Box2D/Dynamics/c_b2Body.cpp | 4 ++++ liquidfun-c/Box2D/Dynamics/c_b2Body.h | 1 + src/box2d/dynamics/body.rs | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp index 02035b5..46f6ab5 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp @@ -43,5 +43,9 @@ extern "C" { self->SetTransform(position, angle); } + void b2Body_SetLinearVelocity(b2Body* self, const b2Vec2& v) { + self->SetLinearVelocity(v); + } + } // extern C diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.h b/liquidfun-c/Box2D/Dynamics/c_b2Body.h index fb28936..ccaba11 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.h +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.h @@ -15,6 +15,7 @@ extern "C" { b2World* b2Body_GetWorld(b2Body* self); b2Vec2 b2Body_GetLocalPoint(const b2Body* self, const b2Vec2& worldPoint); void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle); + void b2Body_SetLinearVelocity(b2Body* self, const b2Vec2& v); #ifdef __cplusplus } // extern C diff --git a/src/box2d/dynamics/body.rs b/src/box2d/dynamics/body.rs index 7c401f1..041653e 100644 --- a/src/box2d/dynamics/body.rs +++ b/src/box2d/dynamics/body.rs @@ -112,6 +112,7 @@ extern { fn b2Body_GetWorld(this: *const B2Body) -> *mut B2World; fn b2Body_GetLocalPoint(this: *const B2Body, worldPoint: &Vec2) -> Vec2; fn b2Body_SetTransform(this: *mut B2Body, position: &Vec2, angle: Float32); + fn b2Body_SetLinearVelocity(this: *mut B2Body, v: &Vec2); } /// A rigid body. These are created via b2World::CreateBody. @@ -219,4 +220,10 @@ impl Body { b2Body_SetTransform(self.ptr, position, angle) } } + + pub fn set_linear_velocity(&mut self, v: &Vec2) { + unsafe { + b2Body_SetLinearVelocity(self.ptr, v) + } + } } From 4eb0b9c6a3e50016e50752050ed578bd7f2b45f3 Mon Sep 17 00:00:00 2001 From: Boscop Date: Tue, 8 Nov 2016 14:14:03 +0100 Subject: [PATCH 04/12] Body.get_linear_velocity() --- liquidfun-c/Box2D/Dynamics/c_b2Body.cpp | 16 ++++++++++------ liquidfun-c/Box2D/Dynamics/c_b2Body.h | 1 + src/box2d/collision/shapes/polygon_shape.rs | 2 +- src/box2d/dynamics/body.rs | 7 +++++++ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp index 46f6ab5..64ced60 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp @@ -39,13 +39,17 @@ extern "C" { return self->GetLocalPoint(worldPoint); } - void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle) { - self->SetTransform(position, angle); - } + void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle) { + self->SetTransform(position, angle); + } + + void b2Body_SetLinearVelocity(b2Body* self, const b2Vec2& v) { + self->SetLinearVelocity(v); + } - void b2Body_SetLinearVelocity(b2Body* self, const b2Vec2& v) { - self->SetLinearVelocity(v); - } + b2Vec2 b2Body_GetLinearVelocity(b2Body* self) { + return self->GetLinearVelocity(); + } } // extern C diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.h b/liquidfun-c/Box2D/Dynamics/c_b2Body.h index ccaba11..f42f8eb 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.h +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.h @@ -16,6 +16,7 @@ extern "C" { b2Vec2 b2Body_GetLocalPoint(const b2Body* self, const b2Vec2& worldPoint); void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle); void b2Body_SetLinearVelocity(b2Body* self, const b2Vec2& v); + b2Vec2 b2Body_GetLinearVelocity(b2Body* self); #ifdef __cplusplus } // extern C diff --git a/src/box2d/collision/shapes/polygon_shape.rs b/src/box2d/collision/shapes/polygon_shape.rs index c39a894..b4d119a 100644 --- a/src/box2d/collision/shapes/polygon_shape.rs +++ b/src/box2d/collision/shapes/polygon_shape.rs @@ -81,7 +81,7 @@ impl PolygonShape { } } - /// Build vertices to represent an axis-aligned box centered on the local origin. + /// Build a convex polygon. /// @param hx the half-width. /// @param hy the half-height. pub fn set(&mut self, vertices: &[Vec2]) { diff --git a/src/box2d/dynamics/body.rs b/src/box2d/dynamics/body.rs index 041653e..5cb06eb 100644 --- a/src/box2d/dynamics/body.rs +++ b/src/box2d/dynamics/body.rs @@ -113,6 +113,7 @@ extern { fn b2Body_GetLocalPoint(this: *const B2Body, worldPoint: &Vec2) -> Vec2; fn b2Body_SetTransform(this: *mut B2Body, position: &Vec2, angle: Float32); fn b2Body_SetLinearVelocity(this: *mut B2Body, v: &Vec2); + fn b2Body_GetLinearVelocity(this: *mut B2Body) -> Vec2; } /// A rigid body. These are created via b2World::CreateBody. @@ -226,4 +227,10 @@ impl Body { b2Body_SetLinearVelocity(self.ptr, v) } } + + pub fn get_linear_velocity(&mut self) -> Vec2 { + unsafe { + b2Body_GetLinearVelocity(self.ptr) + } + } } From 616f2cfaa66f7f3c456fb967ee35020f07ca4606 Mon Sep 17 00:00:00 2001 From: Boscop Date: Tue, 8 Nov 2016 14:51:57 +0100 Subject: [PATCH 05/12] b2Body_GetLinearVelocity() returns &Vec2 --- liquidfun-c/Box2D/Dynamics/c_b2Body.cpp | 2 +- liquidfun-c/Box2D/Dynamics/c_b2Body.h | 2 +- src/box2d/dynamics/body.rs | 8 ++++---- tests/hello-world.rs | 3 ++- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp index 64ced60..cc80190 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp @@ -47,7 +47,7 @@ extern "C" { self->SetLinearVelocity(v); } - b2Vec2 b2Body_GetLinearVelocity(b2Body* self) { + const b2Vec2& b2Body_GetLinearVelocity(const b2Body* self) { return self->GetLinearVelocity(); } diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.h b/liquidfun-c/Box2D/Dynamics/c_b2Body.h index f42f8eb..dbb1278 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.h +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.h @@ -16,7 +16,7 @@ extern "C" { b2Vec2 b2Body_GetLocalPoint(const b2Body* self, const b2Vec2& worldPoint); void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle); void b2Body_SetLinearVelocity(b2Body* self, const b2Vec2& v); - b2Vec2 b2Body_GetLinearVelocity(b2Body* self); + const b2Vec2& b2Body_GetLinearVelocity(const b2Body* self); #ifdef __cplusplus } // extern C diff --git a/src/box2d/dynamics/body.rs b/src/box2d/dynamics/body.rs index 5cb06eb..ae2bed0 100644 --- a/src/box2d/dynamics/body.rs +++ b/src/box2d/dynamics/body.rs @@ -104,16 +104,16 @@ pub enum B2Body {} extern { fn b2Body_CreateFixture_FromShape(this: *mut B2Body, shape: *const B2Shape, density: Float32) -> *mut B2Fixture; fn b2Body_CreateFixture(this: *mut B2Body, def: *mut FixtureDef) -> *mut B2Fixture; - fn b2Body_GetAngle(this: *mut B2Body) -> Float32; + fn b2Body_GetAngle(this: *const B2Body) -> Float32; fn b2Body_GetFixtureList(this: *mut B2Body) -> *mut B2Fixture; fn b2Body_GetNext(this: *mut B2Body) -> *mut B2Body; - fn b2Body_GetPosition(this: *mut B2Body) -> &Vec2; + fn b2Body_GetPosition(this: *const B2Body) -> &Vec2; fn b2Body_GetUserData(this: *const B2Body) -> usize; fn b2Body_GetWorld(this: *const B2Body) -> *mut B2World; fn b2Body_GetLocalPoint(this: *const B2Body, worldPoint: &Vec2) -> Vec2; fn b2Body_SetTransform(this: *mut B2Body, position: &Vec2, angle: Float32); fn b2Body_SetLinearVelocity(this: *mut B2Body, v: &Vec2); - fn b2Body_GetLinearVelocity(this: *mut B2Body) -> Vec2; + fn b2Body_GetLinearVelocity(this: *const B2Body) -> &Vec2; } /// A rigid body. These are created via b2World::CreateBody. @@ -228,7 +228,7 @@ impl Body { } } - pub fn get_linear_velocity(&mut self) -> Vec2 { + pub fn get_linear_velocity(&self) -> &Vec2 { unsafe { b2Body_GetLinearVelocity(self.ptr) } diff --git a/tests/hello-world.rs b/tests/hello-world.rs index 6e767b6..e2bda85 100644 --- a/tests/hello-world.rs +++ b/tests/hello-world.rs @@ -73,8 +73,9 @@ fn hello_world() { // Now print the position and angle of the body. let position = body.get_position(); let angle = body.get_angle(); + let vel = body.get_linear_velocity(); - println!("{:?} angle: {:?}", position, angle); + println!("{:?} angle: {:?}, vel: {:?}", position, angle, vel); } // When the world destructor is called, all bodies and joints are freed. This can From 04f4a66a379782cf04b8b434f3be37ebeb939747 Mon Sep 17 00:00:00 2001 From: Boscop Date: Wed, 9 Nov 2016 11:01:35 +0100 Subject: [PATCH 06/12] Added support for debug draw --- liquidfun-c/Box2D/Common/c_b2Draw.cpp | 51 ++++++++ liquidfun-c/Box2D/Common/c_b2Draw.h | 23 ++++ liquidfun-c/Box2D/Dynamics/c_b2Body.cpp | 12 +- liquidfun-c/Box2D/Dynamics/c_b2Body.h | 8 +- liquidfun-c/Box2D/Dynamics/c_b2World.cpp | 3 + liquidfun-c/Box2D/Dynamics/c_b2World.h | 1 + liquidfun-c/c_box2d.cpp | 1 + src/box2d/common/draw.rs | 141 +++++++++++++++++++++++ src/box2d/common/math.rs | 11 ++ src/box2d/common/mod.rs | 3 +- src/box2d/dynamics/world.rs | 13 ++- 11 files changed, 255 insertions(+), 12 deletions(-) create mode 100644 liquidfun-c/Box2D/Common/c_b2Draw.cpp create mode 100644 liquidfun-c/Box2D/Common/c_b2Draw.h create mode 100644 src/box2d/common/draw.rs diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.cpp b/liquidfun-c/Box2D/Common/c_b2Draw.cpp new file mode 100644 index 0000000..1433114 --- /dev/null +++ b/liquidfun-c/Box2D/Common/c_b2Draw.cpp @@ -0,0 +1,51 @@ +#include +#include "c_b2Draw.h" + +extern "C" { + + void b2Draw_SetFlags(b2Draw* self, uint32 flags) { + self->SetFlags(flags); + } + + uint32 b2Draw_GetFlags(const b2Draw* self) { + return self->GetFlags(); + } + + void b2Draw_AppendFlags(b2Draw* self, uint32 flags) { + self->AppendFlags(flags); + } + + void b2Draw_ClearFlags(b2Draw* self, uint32 flags) { + self->ClearFlags(flags); + } + + void b2Draw_DrawPolygon(b2Draw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color) { + self->DrawPolygon(vertices, vertexCount, color); + } + + void b2Draw_DrawSolidPolygon(b2Draw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color) { + self->DrawSolidPolygon(vertices, vertexCount, color); + } + + void b2Draw_DrawCircle(b2Draw* self, const b2Vec2& center, float32 radius, const b2Color& color) { + self->DrawCircle(center, radius, color); + } + + void b2Draw_DrawSolidCircle(b2Draw* self, const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) { + self->DrawSolidCircle(center, radius, axis, color); + } + + void b2Draw_DrawParticles(b2Draw* self, const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count) { + self->DrawParticles(centers, radius, colors, count); + } + + void b2Draw_DrawSegment(b2Draw* self, const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) { + self->DrawSegment(p1, p2, color); + } + + void b2Draw_DrawTransform(b2Draw* self, const b2Transform& xf) { + self->DrawTransform(xf); + } + +} // extern C + diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.h b/liquidfun-c/Box2D/Common/c_b2Draw.h new file mode 100644 index 0000000..2688d68 --- /dev/null +++ b/liquidfun-c/Box2D/Common/c_b2Draw.h @@ -0,0 +1,23 @@ +#ifndef C_B2_DRAW +#define C_B2_DRAW + +#ifdef __cplusplus +extern "C" { +#endif + + void b2Draw_SetFlags(b2Draw* self, uint32 flags); + uint32 b2Draw_GetFlags(const b2Draw* self); + void b2Draw_AppendFlags(b2Draw* self, uint32 flags); + void b2Draw_ClearFlags(b2Draw* self, uint32 flags); + void b2Draw_DrawPolygon(b2Draw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); + void b2Draw_DrawSolidPolygon(b2Draw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); + void b2Draw_DrawCircle(b2Draw* self, const b2Vec2& center, float32 radius, const b2Color& color); + void b2Draw_DrawSolidCircle(b2Draw* self, const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color); + void b2Draw_DrawParticles(b2Draw* self, const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count); + void b2Draw_DrawSegment(b2Draw* self, const b2Vec2& p1, const b2Vec2& p2, const b2Color& color); + void b2Draw_DrawTransform(b2Draw* self, const b2Transform& xf); + +#ifdef __cplusplus +} // extern C +#endif +#endif \ No newline at end of file diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp index cc80190..4c314d6 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.cpp @@ -4,16 +4,16 @@ extern "C" { b2Fixture* b2Body_CreateFixture(b2Body* self, const b2FixtureDef* def) { - return self->CreateFixture(def); + return self->CreateFixture(def); } b2Fixture* b2Body_CreateFixture_FromShape(b2Body* self, const b2Shape* shape, float32 density) { - return self->CreateFixture(shape, density); + return self->CreateFixture(shape, density); } float32 b2Body_GetAngle(const b2Body* self) { - return self->GetAngle(); - } + return self->GetAngle(); + } b2Fixture* b2Body_GetFixtureList(b2Body* self) { return self->GetFixtureList(); @@ -24,7 +24,7 @@ extern "C" { } const b2Vec2& b2Body_GetPosition(const b2Body* self) { - return self->GetPosition(); + return self->GetPosition(); } void* b2Body_GetUserData(const b2Body* self) { @@ -35,7 +35,7 @@ extern "C" { return self->GetWorld(); } - b2Vec2 b2Body_GetLocalPoint(const b2Body* self, const b2Vec2& worldPoint) { + const b2Vec2& b2Body_GetLocalPoint(const b2Body* self, const b2Vec2& worldPoint) { return self->GetLocalPoint(worldPoint); } diff --git a/liquidfun-c/Box2D/Dynamics/c_b2Body.h b/liquidfun-c/Box2D/Dynamics/c_b2Body.h index dbb1278..904bf67 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2Body.h +++ b/liquidfun-c/Box2D/Dynamics/c_b2Body.h @@ -13,10 +13,10 @@ extern "C" { b2Body* b2Body_GetNext(b2Body* self); void* b2Body_GetUserData(const b2Body* self); b2World* b2Body_GetWorld(b2Body* self); - b2Vec2 b2Body_GetLocalPoint(const b2Body* self, const b2Vec2& worldPoint); - void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle); - void b2Body_SetLinearVelocity(b2Body* self, const b2Vec2& v); - const b2Vec2& b2Body_GetLinearVelocity(const b2Body* self); + const b2Vec2& b2Body_GetLocalPoint(const b2Body* self, const b2Vec2& worldPoint); + void b2Body_SetTransform(b2Body* self, const b2Vec2& position, float32 angle); + void b2Body_SetLinearVelocity(b2Body* self, const b2Vec2& v); + const b2Vec2& b2Body_GetLinearVelocity(const b2Body* self); #ifdef __cplusplus } // extern C diff --git a/liquidfun-c/Box2D/Dynamics/c_b2World.cpp b/liquidfun-c/Box2D/Dynamics/c_b2World.cpp index f5514c3..a8bd6c4 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2World.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2World.cpp @@ -87,6 +87,9 @@ extern "C" { self->Step(timeStep, velocityIterations, positionIterations); } + void b2World_SetDebugDraw(b2World* self, b2Draw* debugDraw) { + self->SetDebugDraw(debugDraw); + } } // extern C diff --git a/liquidfun-c/Box2D/Dynamics/c_b2World.h b/liquidfun-c/Box2D/Dynamics/c_b2World.h index 4e3a36f..a382a6e 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2World.h +++ b/liquidfun-c/Box2D/Dynamics/c_b2World.h @@ -38,6 +38,7 @@ extern "C" { b2ParticleSystem* b2World_CreateParticleSystem(b2World* self, const b2ParticleSystemDef* def); void b2World_Step(b2World* self, float32 timeStep, int32 velocityIterations, int32 positionIterations); + void b2World_SetDebugDraw(b2World* self, b2Draw* debugDraw); #ifdef __cplusplus } // extern C diff --git a/liquidfun-c/c_box2d.cpp b/liquidfun-c/c_box2d.cpp index 43285f4..8ea73b2 100644 --- a/liquidfun-c/c_box2d.cpp +++ b/liquidfun-c/c_box2d.cpp @@ -57,6 +57,7 @@ #include "Box2D/Collision/Shapes/c_b2ChainShape.cpp" #include "Box2D/Collision/Shapes/c_b2PolygonShape.cpp" #include "Box2D/Common/c_b2Math.cpp" +#include "Box2D/Common/c_b2Draw.cpp" #include "Box2D/Dynamics/c_b2Body.cpp" #include "Box2D/Dynamics/c_b2Fixture.cpp" #include "Box2D/Dynamics/c_b2World.cpp" diff --git a/src/box2d/common/draw.rs b/src/box2d/common/draw.rs new file mode 100644 index 0000000..f320725 --- /dev/null +++ b/src/box2d/common/draw.rs @@ -0,0 +1,141 @@ +use super::super::common::math::*; +use super::super::common::settings::*; + +/// Flags for specifying what to draw, using set_flags() +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum DrawFlags { + /// draw shapes + ShapeBit = 0x0001, + + /// draw joint connections + JointBit = 0x0002, + + /// draw axis aligned bounding boxes + AabbBit = 0x0004, + + /// draw broad-phase pairs + PairBit = 0x0008, + + /// draw center of mass frame + CenterOfMassBit = 0x0010, + + /// draw particles + ParticleBit = 0x0020, +} + +/// Color for debug drawing. Each value has the range [0,1]. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq)] +pub struct Color { pub r: f32, pub g: f32, pub b: f32 } + +/// Small color object for each particle +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)] +pub struct ParticleColor { pub r: u8, pub g: u8, pub b: u8, pub a: u8 } + +pub enum B2Draw {} + +extern { + fn b2Draw_SetFlags(this: *mut B2Draw, flags: UInt32); + fn b2Draw_GetFlags(this: *const B2Draw) -> UInt32; + fn b2Draw_AppendFlags(this: *mut B2Draw, flags: UInt32); + fn b2Draw_ClearFlags(this: *mut B2Draw, flags: UInt32); + fn b2Draw_DrawPolygon(this: *mut B2Draw, vertices: *const Vec2, vertexCount: Int32, color: &Color); + fn b2Draw_DrawSolidPolygon(this: *mut B2Draw, vertices: *const Vec2, vertexCount: Int32, color: &Color); + fn b2Draw_DrawCircle(this: *mut B2Draw, center: &Vec2, radius: f32, color: &Color); + fn b2Draw_DrawSolidCircle(this: *mut B2Draw, center: &Vec2, radius: f32, axis: &Vec2, color: &Color); + fn b2Draw_DrawParticles(this: *mut B2Draw, centers: *const Vec2, radius: f32, colors: *const ParticleColor, count: Int32); + fn b2Draw_DrawSegment(this: *mut B2Draw, p1: &Vec2, p2: &Vec2, color: &Color); + fn b2Draw_DrawTransform(this: *mut B2Draw, xf: &Transform); +} + +/// Implement and register this class with a b2World to provide debug drawing of physics +/// entities in your game. +#[allow(raw_pointer_derive)] +#[derive(Clone, Debug)] +pub struct Draw { + pub ptr: *mut B2Draw +} + +impl Draw { + + /// Set the drawing flags. + pub fn set_flags(&mut self, flags: UInt32) { + unsafe { + b2Draw_SetFlags(self.ptr, flags); + } + } + + /// Get the drawing flags. + pub fn get_flags(&self) -> UInt32 { + unsafe { + b2Draw_GetFlags(self.ptr) + } + } + + /// Append flags to the current flags. + pub fn append_flags(&mut self, flags: UInt32) { + unsafe { + b2Draw_AppendFlags(self.ptr, flags); + } + } + + /// Clear flags from the current flags. + pub fn clear_flags(&mut self, flags: UInt32) { + unsafe { + b2Draw_ClearFlags(self.ptr, flags); + } + } + + /// Draw a closed polygon provided in CCW order. + pub fn draw_polygon(&mut self, vertices: &[Vec2], color: &Color) { + unsafe { + b2Draw_DrawPolygon(self.ptr, vertices.as_ptr(), vertices.len() as Int32, color); + } + } + + /// Draw a solid closed polygon provided in CCW order. + pub fn draw_solid_polygon(&mut self, vertices: &[Vec2], color: &Color) { + unsafe { + b2Draw_DrawSolidPolygon(self.ptr, vertices.as_ptr(), vertices.len() as Int32, color); + } + } + + /// Draw a circle. + pub fn draw_circle(&mut self, center: &Vec2, radius: f32, color: &Color) { + unsafe { + b2Draw_DrawCircle(self.ptr, center, radius, color); + } + } + + /// Draw a solid circle. + pub fn draw_solid_circle(&mut self, center: &Vec2, radius: f32, axis: &Vec2, color: &Color) { + unsafe { + b2Draw_DrawSolidCircle(self.ptr, center, radius, axis, color); + } + } + + /// Draw a particle array + /// centers and colors must have the same length + pub fn draw_particles(&mut self, centers: &[Vec2], radius: f32, colors: &[ParticleColor]) { + // assert_eq!(centers.len(), colors.len()); + unsafe { + b2Draw_DrawParticles(self.ptr, centers.as_ptr(), radius, colors.as_ptr(), colors.len() as Int32); + } + } + + /// Draw a line segment. + pub fn draw_segment(&mut self, p1: &Vec2, p2: &Vec2, color: &Color) { + unsafe { + b2Draw_DrawSegment(self.ptr, p1, p2, color); + } + } + + /// Draw a transform. Choose your own length scale. + pub fn draw_transform(&mut self, xf: &Transform) { + unsafe { + b2Draw_DrawTransform(self.ptr, xf); + } + } +} diff --git a/src/box2d/common/math.rs b/src/box2d/common/math.rs index 6f2c8de..08fc821 100644 --- a/src/box2d/common/math.rs +++ b/src/box2d/common/math.rs @@ -27,3 +27,14 @@ impl Vec2 { } } +/// A transform contains translation and rotation. It is used to represent +/// the position and orientation of rigid frames. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq)] +pub struct Transform { pub p: Vec2, pub q: Rot } + +/// Rotation +/// Sine and cosine +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq)] +pub struct Rot { pub s: f32, pub c: f32 } diff --git a/src/box2d/common/mod.rs b/src/box2d/common/mod.rs index 83f2df1..efd85d8 100644 --- a/src/box2d/common/mod.rs +++ b/src/box2d/common/mod.rs @@ -1,2 +1,3 @@ pub mod math; -pub mod settings; \ No newline at end of file +pub mod settings; +pub mod draw; \ No newline at end of file diff --git a/src/box2d/dynamics/world.rs b/src/box2d/dynamics/world.rs index bfa7c89..25aecd8 100644 --- a/src/box2d/dynamics/world.rs +++ b/src/box2d/dynamics/world.rs @@ -5,6 +5,7 @@ use super::super::common::math::*; use super::super::common::settings::*; use super::super::particle::particle_system::*; use super::joints; +use super::super::common::draw::{Draw, B2Draw}; pub enum B2World {} @@ -40,6 +41,7 @@ extern { max_motor_torque: Float32 ) -> *mut joints::revolute_joint::B2RevoluteJoint; + fn b2World_SetDebugDraw(this: *mut B2World, debugDraw: *mut B2Draw); } /// The world class manages all physics entities, dynamic simulation, @@ -171,7 +173,16 @@ impl World { unsafe { b2World_Step(self.ptr, time_step, velocity_iterations, position_iterations); } - } + } + + /// Register a routine for debug drawing. The debug draw functions are called + /// inside with b2World::DrawDebugData method. The debug draw object is owned + /// by you and must remain in scope. + pub fn set_debug_draw(&mut self, debug_draw: Draw) { + unsafe { + b2World_SetDebugDraw(self.ptr, debug_draw.ptr); + } + } } From 8888c404d926e05b4a59afb4e1e98ab829eb75d4 Mon Sep 17 00:00:00 2001 From: Boscop Date: Wed, 9 Nov 2016 13:51:37 +0100 Subject: [PATCH 07/12] added C++ wrapper around Draw trait --- liquidfun-c/Box2D/Common/c_b2Draw.cpp | 51 -------- liquidfun-c/Box2D/Common/c_b2Draw.h | 89 +++++++++++-- liquidfun-c/Box2D/Dynamics/c_b2World.cpp | 1 + liquidfun-c/c_box2d.cpp | 1 - src/box2d/common/draw.rs | 153 +++++++++++------------ src/box2d/dynamics/world.rs | 14 ++- 6 files changed, 161 insertions(+), 148 deletions(-) delete mode 100644 liquidfun-c/Box2D/Common/c_b2Draw.cpp diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.cpp b/liquidfun-c/Box2D/Common/c_b2Draw.cpp deleted file mode 100644 index 1433114..0000000 --- a/liquidfun-c/Box2D/Common/c_b2Draw.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include "c_b2Draw.h" - -extern "C" { - - void b2Draw_SetFlags(b2Draw* self, uint32 flags) { - self->SetFlags(flags); - } - - uint32 b2Draw_GetFlags(const b2Draw* self) { - return self->GetFlags(); - } - - void b2Draw_AppendFlags(b2Draw* self, uint32 flags) { - self->AppendFlags(flags); - } - - void b2Draw_ClearFlags(b2Draw* self, uint32 flags) { - self->ClearFlags(flags); - } - - void b2Draw_DrawPolygon(b2Draw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color) { - self->DrawPolygon(vertices, vertexCount, color); - } - - void b2Draw_DrawSolidPolygon(b2Draw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color) { - self->DrawSolidPolygon(vertices, vertexCount, color); - } - - void b2Draw_DrawCircle(b2Draw* self, const b2Vec2& center, float32 radius, const b2Color& color) { - self->DrawCircle(center, radius, color); - } - - void b2Draw_DrawSolidCircle(b2Draw* self, const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) { - self->DrawSolidCircle(center, radius, axis, color); - } - - void b2Draw_DrawParticles(b2Draw* self, const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count) { - self->DrawParticles(centers, radius, colors, count); - } - - void b2Draw_DrawSegment(b2Draw* self, const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) { - self->DrawSegment(p1, p2, color); - } - - void b2Draw_DrawTransform(b2Draw* self, const b2Transform& xf) { - self->DrawTransform(xf); - } - -} // extern C - diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.h b/liquidfun-c/Box2D/Common/c_b2Draw.h index 2688d68..23e96f9 100644 --- a/liquidfun-c/Box2D/Common/c_b2Draw.h +++ b/liquidfun-c/Box2D/Common/c_b2Draw.h @@ -1,23 +1,90 @@ #ifndef C_B2_DRAW #define C_B2_DRAW +struct BoxDebugDraw {}; + +#ifdef __cplusplus +extern "C" { +#endif + + void BoxDebugDraw_SetFlags(BoxDebugDraw* self, uint32 flags); + uint32 BoxDebugDraw_GetFlags(const BoxDebugDraw* self); + void BoxDebugDraw_AppendFlags(BoxDebugDraw* self, uint32 flags); + void BoxDebugDraw_ClearFlags(BoxDebugDraw* self, uint32 flags); + void BoxDebugDraw_DrawPolygon(BoxDebugDraw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); + void BoxDebugDraw_DrawSolidPolygon(BoxDebugDraw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); + void BoxDebugDraw_DrawCircle(BoxDebugDraw* self, const b2Vec2& center, float32 radius, const b2Color& color); + void BoxDebugDraw_DrawSolidCircle(BoxDebugDraw* self, const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color); + void BoxDebugDraw_DrawParticles(BoxDebugDraw* self, const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count); + void BoxDebugDraw_DrawSegment(BoxDebugDraw* self, const b2Vec2& p1, const b2Vec2& p2, const b2Color& color); + void BoxDebugDraw_DrawTransform(BoxDebugDraw* self, const b2Transform& xf); + +#ifdef __cplusplus +} // extern C +#endif + +class CppDebugDraw: b2Draw { +public: + CppDebugDraw(BoxDebugDraw* debugDraw): self(debugDraw) {} + + void SetFlags(uint32 flags) { + BoxDebugDraw_SetFlags(self, flags); + } + + uint32 GetFlags() const { + return BoxDebugDraw_GetFlags(self); + } + + void AppendFlags(uint32 flags) { + BoxDebugDraw_AppendFlags(self, flags); + } + + void ClearFlags(uint32 flags) { + BoxDebugDraw_ClearFlags(self, flags); + } + + virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) { + BoxDebugDraw_DrawPolygon(self, vertices, vertexCount, color); + } + + virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) { + BoxDebugDraw_DrawSolidPolygon(self, vertices, vertexCount, color); + } + + virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) { + BoxDebugDraw_DrawCircle(self, center, radius, color); + } + + virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) { + BoxDebugDraw_DrawSolidCircle(self, center, radius, axis, color); + } + + virtual void DrawParticles(const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count) { + BoxDebugDraw_DrawParticles(self, centers, radius, colors, count); + } + + virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) { + BoxDebugDraw_DrawSegment(self, p1, p2, color); + } + + virtual void DrawTransform(const b2Transform& xf) { + BoxDebugDraw_DrawTransform(self, xf); + } + +protected: + BoxDebugDraw* self; +}; + #ifdef __cplusplus extern "C" { #endif - void b2Draw_SetFlags(b2Draw* self, uint32 flags); - uint32 b2Draw_GetFlags(const b2Draw* self); - void b2Draw_AppendFlags(b2Draw* self, uint32 flags); - void b2Draw_ClearFlags(b2Draw* self, uint32 flags); - void b2Draw_DrawPolygon(b2Draw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); - void b2Draw_DrawSolidPolygon(b2Draw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); - void b2Draw_DrawCircle(b2Draw* self, const b2Vec2& center, float32 radius, const b2Color& color); - void b2Draw_DrawSolidCircle(b2Draw* self, const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color); - void b2Draw_DrawParticles(b2Draw* self, const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count); - void b2Draw_DrawSegment(b2Draw* self, const b2Vec2& p1, const b2Vec2& p2, const b2Color& color); - void b2Draw_DrawTransform(b2Draw* self, const b2Transform& xf); + CppDebugDraw* DebugDraw_new(BoxDebugDraw* debugDraw) { + return new CppDebugDraw(debugDraw); + } #ifdef __cplusplus } // extern C #endif + #endif \ No newline at end of file diff --git a/liquidfun-c/Box2D/Dynamics/c_b2World.cpp b/liquidfun-c/Box2D/Dynamics/c_b2World.cpp index a8bd6c4..b7cc50e 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2World.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2World.cpp @@ -88,6 +88,7 @@ extern "C" { } void b2World_SetDebugDraw(b2World* self, b2Draw* debugDraw) { + // self->SetDebugDraw(new CppDebugDraw(debugDraw)); self->SetDebugDraw(debugDraw); } diff --git a/liquidfun-c/c_box2d.cpp b/liquidfun-c/c_box2d.cpp index 8ea73b2..43285f4 100644 --- a/liquidfun-c/c_box2d.cpp +++ b/liquidfun-c/c_box2d.cpp @@ -57,7 +57,6 @@ #include "Box2D/Collision/Shapes/c_b2ChainShape.cpp" #include "Box2D/Collision/Shapes/c_b2PolygonShape.cpp" #include "Box2D/Common/c_b2Math.cpp" -#include "Box2D/Common/c_b2Draw.cpp" #include "Box2D/Dynamics/c_b2Body.cpp" #include "Box2D/Dynamics/c_b2Fixture.cpp" #include "Box2D/Dynamics/c_b2World.cpp" diff --git a/src/box2d/common/draw.rs b/src/box2d/common/draw.rs index f320725..ecceaf0 100644 --- a/src/box2d/common/draw.rs +++ b/src/box2d/common/draw.rs @@ -1,3 +1,7 @@ +#![allow(non_snake_case)] + +use std::slice::from_raw_parts; + use super::super::common::math::*; use super::super::common::settings::*; @@ -34,108 +38,97 @@ pub struct Color { pub r: f32, pub g: f32, pub b: f32 } #[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)] pub struct ParticleColor { pub r: u8, pub g: u8, pub b: u8, pub a: u8 } -pub enum B2Draw {} - -extern { - fn b2Draw_SetFlags(this: *mut B2Draw, flags: UInt32); - fn b2Draw_GetFlags(this: *const B2Draw) -> UInt32; - fn b2Draw_AppendFlags(this: *mut B2Draw, flags: UInt32); - fn b2Draw_ClearFlags(this: *mut B2Draw, flags: UInt32); - fn b2Draw_DrawPolygon(this: *mut B2Draw, vertices: *const Vec2, vertexCount: Int32, color: &Color); - fn b2Draw_DrawSolidPolygon(this: *mut B2Draw, vertices: *const Vec2, vertexCount: Int32, color: &Color); - fn b2Draw_DrawCircle(this: *mut B2Draw, center: &Vec2, radius: f32, color: &Color); - fn b2Draw_DrawSolidCircle(this: *mut B2Draw, center: &Vec2, radius: f32, axis: &Vec2, color: &Color); - fn b2Draw_DrawParticles(this: *mut B2Draw, centers: *const Vec2, radius: f32, colors: *const ParticleColor, count: Int32); - fn b2Draw_DrawSegment(this: *mut B2Draw, p1: &Vec2, p2: &Vec2, color: &Color); - fn b2Draw_DrawTransform(this: *mut B2Draw, xf: &Transform); -} - -/// Implement and register this class with a b2World to provide debug drawing of physics -/// entities in your game. -#[allow(raw_pointer_derive)] -#[derive(Clone, Debug)] -pub struct Draw { - pub ptr: *mut B2Draw +/// Implement and register this trait with a World to provide debug drawing of physics +/// using World.set_debug_draw() +pub trait Draw { + fn set_flags(&mut self, flags: UInt32); + fn get_flags(&self) -> UInt32; + fn append_flags(&mut self, flags: UInt32); + fn clear_flags(&mut self, flags: UInt32); + fn draw_polygon(&mut self, vertices: &[Vec2], color: &Color); + fn draw_solid_polygon(&mut self, vertices: &[Vec2], color: &Color); + fn draw_circle(&mut self, center: &Vec2, radius: f32, color: &Color); + fn draw_solid_circle(&mut self, center: &Vec2, radius: f32, axis: &Vec2, color: &Color); + fn draw_particles(&mut self, centers: &[Vec2], colors: &[ParticleColor], radius: f32); + fn draw_segment(&mut self, p1: &Vec2, p2: &Vec2, color: &Color); + fn draw_transform(&mut self, xf: &Transform); } -impl Draw { +pub type BoxDebugDraw = Box; - /// Set the drawing flags. - pub fn set_flags(&mut self, flags: UInt32) { - unsafe { - b2Draw_SetFlags(self.ptr, flags); - } +#[no_mangle] +pub extern fn BoxDebugDraw_SetFlags(this: *mut BoxDebugDraw, flags: UInt32) { + unsafe { + (*this).set_flags(flags); } +} - /// Get the drawing flags. - pub fn get_flags(&self) -> UInt32 { - unsafe { - b2Draw_GetFlags(self.ptr) - } +#[no_mangle] +pub extern fn BoxDebugDraw_GetFlags(this: *mut BoxDebugDraw) -> UInt32 { + unsafe { + (*this).get_flags() } +} - /// Append flags to the current flags. - pub fn append_flags(&mut self, flags: UInt32) { - unsafe { - b2Draw_AppendFlags(self.ptr, flags); - } +#[no_mangle] +pub extern fn BoxDebugDraw_AppendFlags(this: *mut BoxDebugDraw, flags: UInt32) { + unsafe { + (*this).append_flags(flags); } +} - /// Clear flags from the current flags. - pub fn clear_flags(&mut self, flags: UInt32) { - unsafe { - b2Draw_ClearFlags(self.ptr, flags); - } +#[no_mangle] +pub extern fn BoxDebugDraw_ClearFlags(this: *mut BoxDebugDraw, flags: UInt32) { + unsafe { + (*this).clear_flags(flags); } +} - /// Draw a closed polygon provided in CCW order. - pub fn draw_polygon(&mut self, vertices: &[Vec2], color: &Color) { - unsafe { - b2Draw_DrawPolygon(self.ptr, vertices.as_ptr(), vertices.len() as Int32, color); - } +#[no_mangle] +pub extern fn BoxDebugDraw_DrawPolygon(this: *mut BoxDebugDraw, vertices: *const Vec2, vertexCount: Int32, color: &Color) { + unsafe { + (*this).draw_polygon(from_raw_parts(vertices, vertexCount as usize), color); } +} - /// Draw a solid closed polygon provided in CCW order. - pub fn draw_solid_polygon(&mut self, vertices: &[Vec2], color: &Color) { - unsafe { - b2Draw_DrawSolidPolygon(self.ptr, vertices.as_ptr(), vertices.len() as Int32, color); - } +#[no_mangle] +pub extern fn BoxDebugDraw_DrawSolidPolygon(this: *mut BoxDebugDraw, vertices: *const Vec2, vertexCount: Int32, color: &Color) { + unsafe { + (*this).draw_solid_polygon(from_raw_parts(vertices, vertexCount as usize), color); } +} - /// Draw a circle. - pub fn draw_circle(&mut self, center: &Vec2, radius: f32, color: &Color) { - unsafe { - b2Draw_DrawCircle(self.ptr, center, radius, color); - } +#[no_mangle] +pub extern fn BoxDebugDraw_DrawCircle(this: *mut BoxDebugDraw, center: &Vec2, radius: f32, color: &Color) { + unsafe { + (*this).draw_circle(center, radius, color); } +} - /// Draw a solid circle. - pub fn draw_solid_circle(&mut self, center: &Vec2, radius: f32, axis: &Vec2, color: &Color) { - unsafe { - b2Draw_DrawSolidCircle(self.ptr, center, radius, axis, color); - } +#[no_mangle] +pub extern fn BoxDebugDraw_DrawSolidCircle(this: *mut BoxDebugDraw, center: &Vec2, radius: f32, axis: &Vec2, color: &Color) { + unsafe { + (*this).draw_solid_circle(center, radius, axis, color); } +} - /// Draw a particle array - /// centers and colors must have the same length - pub fn draw_particles(&mut self, centers: &[Vec2], radius: f32, colors: &[ParticleColor]) { - // assert_eq!(centers.len(), colors.len()); - unsafe { - b2Draw_DrawParticles(self.ptr, centers.as_ptr(), radius, colors.as_ptr(), colors.len() as Int32); - } +#[no_mangle] +pub extern fn BoxDebugDraw_DrawParticles(this: *mut BoxDebugDraw, centers: *const Vec2, radius: f32, colors: *const ParticleColor, count: Int32) { + unsafe { + (*this).draw_particles(from_raw_parts(centers, count as usize), from_raw_parts(colors, count as usize), radius); } +} - /// Draw a line segment. - pub fn draw_segment(&mut self, p1: &Vec2, p2: &Vec2, color: &Color) { - unsafe { - b2Draw_DrawSegment(self.ptr, p1, p2, color); - } +#[no_mangle] +pub extern fn BoxDebugDraw_DrawSegment(this: *mut BoxDebugDraw, p1: &Vec2, p2: &Vec2, color: &Color) { + unsafe { + (*this).draw_segment(p1, p2, color); } +} - /// Draw a transform. Choose your own length scale. - pub fn draw_transform(&mut self, xf: &Transform) { - unsafe { - b2Draw_DrawTransform(self.ptr, xf); - } +#[no_mangle] +pub extern fn BoxDebugDraw_DrawTransform(this: *mut BoxDebugDraw, xf: &Transform) { + unsafe { + (*this).draw_transform(xf); } } diff --git a/src/box2d/dynamics/world.rs b/src/box2d/dynamics/world.rs index 25aecd8..8b9a4f1 100644 --- a/src/box2d/dynamics/world.rs +++ b/src/box2d/dynamics/world.rs @@ -5,7 +5,7 @@ use super::super::common::math::*; use super::super::common::settings::*; use super::super::particle::particle_system::*; use super::joints; -use super::super::common::draw::{Draw, B2Draw}; +use super::super::common::draw::BoxDebugDraw; pub enum B2World {} @@ -41,14 +41,18 @@ extern { max_motor_torque: Float32 ) -> *mut joints::revolute_joint::B2RevoluteJoint; - fn b2World_SetDebugDraw(this: *mut B2World, debugDraw: *mut B2Draw); + fn b2World_SetDebugDraw(this: *mut B2World, debug_draw: *mut CppDebugDraw); + + fn CppDebugDraw_new(debug_draw: *mut BoxDebugDraw) -> *mut CppDebugDraw; } +pub enum CppDebugDraw {} + /// The world class manages all physics entities, dynamic simulation, /// and asynchronous queries. The world also contains efficient memory /// management facilities. pub struct World { - pub ptr: *mut B2World + pub ptr: *mut B2World, } impl World { @@ -178,9 +182,9 @@ impl World { /// Register a routine for debug drawing. The debug draw functions are called /// inside with b2World::DrawDebugData method. The debug draw object is owned /// by you and must remain in scope. - pub fn set_debug_draw(&mut self, debug_draw: Draw) { + pub fn set_debug_draw(&mut self, debug_draw: &mut BoxDebugDraw) { unsafe { - b2World_SetDebugDraw(self.ptr, debug_draw.ptr); + b2World_SetDebugDraw(self.ptr, CppDebugDraw_new(debug_draw)); } } From d7c04662b16fd014bc655db57e953aa41d87e687 Mon Sep 17 00:00:00 2001 From: Boscop Date: Wed, 9 Nov 2016 15:03:12 +0100 Subject: [PATCH 08/12] World.draw_debug_data() --- liquidfun-c/Box2D/Dynamics/c_b2World.cpp | 4 ++++ liquidfun-c/Box2D/Dynamics/c_b2World.h | 1 + src/box2d/common/draw.rs | 4 ++-- src/box2d/dynamics/world.rs | 11 +++++++++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/liquidfun-c/Box2D/Dynamics/c_b2World.cpp b/liquidfun-c/Box2D/Dynamics/c_b2World.cpp index b7cc50e..9bf6e9f 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2World.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2World.cpp @@ -92,5 +92,9 @@ extern "C" { self->SetDebugDraw(debugDraw); } + void b2World_DrawDebugData(b2World* self) { + self->DrawDebugData(); + } + } // extern C diff --git a/liquidfun-c/Box2D/Dynamics/c_b2World.h b/liquidfun-c/Box2D/Dynamics/c_b2World.h index a382a6e..796627d 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2World.h +++ b/liquidfun-c/Box2D/Dynamics/c_b2World.h @@ -39,6 +39,7 @@ extern "C" { b2ParticleSystem* b2World_CreateParticleSystem(b2World* self, const b2ParticleSystemDef* def); void b2World_Step(b2World* self, float32 timeStep, int32 velocityIterations, int32 positionIterations); void b2World_SetDebugDraw(b2World* self, b2Draw* debugDraw); + void b2World_DrawDebugData(b2World* self); #ifdef __cplusplus } // extern C diff --git a/src/box2d/common/draw.rs b/src/box2d/common/draw.rs index ecceaf0..d3e34c8 100644 --- a/src/box2d/common/draw.rs +++ b/src/box2d/common/draw.rs @@ -2,8 +2,8 @@ use std::slice::from_raw_parts; -use super::super::common::math::*; -use super::super::common::settings::*; +use super::math::*; +use super::settings::*; /// Flags for specifying what to draw, using set_flags() #[repr(u32)] diff --git a/src/box2d/dynamics/world.rs b/src/box2d/dynamics/world.rs index 8b9a4f1..29697ab 100644 --- a/src/box2d/dynamics/world.rs +++ b/src/box2d/dynamics/world.rs @@ -41,9 +41,9 @@ extern { max_motor_torque: Float32 ) -> *mut joints::revolute_joint::B2RevoluteJoint; - fn b2World_SetDebugDraw(this: *mut B2World, debug_draw: *mut CppDebugDraw); - fn CppDebugDraw_new(debug_draw: *mut BoxDebugDraw) -> *mut CppDebugDraw; + fn b2World_SetDebugDraw(this: *mut B2World, debug_draw: *mut CppDebugDraw); + fn b2World_DrawDebugData(this: *mut B2World); } pub enum CppDebugDraw {} @@ -188,6 +188,13 @@ impl World { } } + /// Call this to draw shapes and other debug draw data. This is intentionally non-const. + pub fn draw_debug_data(&mut self) { + unsafe { + b2World_DrawDebugData(self.ptr); + } + } + } impl Drop for World { From 7477a20dab0c0e2fe57e3e027a1e26b2a5734e8d Mon Sep 17 00:00:00 2001 From: Boscop Date: Wed, 9 Nov 2016 16:23:34 +0100 Subject: [PATCH 09/12] put DebugDraw_new() in c_b2Draw.cpp --- liquidfun-c/Box2D/Common/c_b2Draw.cpp | 10 ++++++++++ liquidfun-c/Box2D/Common/c_b2Draw.h | 4 +--- liquidfun-c/c_box2d.cpp | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 liquidfun-c/Box2D/Common/c_b2Draw.cpp diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.cpp b/liquidfun-c/Box2D/Common/c_b2Draw.cpp new file mode 100644 index 0000000..e3c117f --- /dev/null +++ b/liquidfun-c/Box2D/Common/c_b2Draw.cpp @@ -0,0 +1,10 @@ +#include +#include "c_b2Draw.h" + +extern "C" { + + CppDebugDraw* DebugDraw_new(BoxDebugDraw* debugDraw) { + return new CppDebugDraw(debugDraw); + } + +} // extern C diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.h b/liquidfun-c/Box2D/Common/c_b2Draw.h index 23e96f9..003dfb3 100644 --- a/liquidfun-c/Box2D/Common/c_b2Draw.h +++ b/liquidfun-c/Box2D/Common/c_b2Draw.h @@ -79,9 +79,7 @@ class CppDebugDraw: b2Draw { extern "C" { #endif - CppDebugDraw* DebugDraw_new(BoxDebugDraw* debugDraw) { - return new CppDebugDraw(debugDraw); - } + CppDebugDraw* DebugDraw_new(BoxDebugDraw* debugDraw); #ifdef __cplusplus } // extern C diff --git a/liquidfun-c/c_box2d.cpp b/liquidfun-c/c_box2d.cpp index 43285f4..8ea73b2 100644 --- a/liquidfun-c/c_box2d.cpp +++ b/liquidfun-c/c_box2d.cpp @@ -57,6 +57,7 @@ #include "Box2D/Collision/Shapes/c_b2ChainShape.cpp" #include "Box2D/Collision/Shapes/c_b2PolygonShape.cpp" #include "Box2D/Common/c_b2Math.cpp" +#include "Box2D/Common/c_b2Draw.cpp" #include "Box2D/Dynamics/c_b2Body.cpp" #include "Box2D/Dynamics/c_b2Fixture.cpp" #include "Box2D/Dynamics/c_b2World.cpp" From 712b3b97e2da0b15148555f2e1e3316e69ddee94 Mon Sep 17 00:00:00 2001 From: Boscop Date: Wed, 9 Nov 2016 17:27:34 +0100 Subject: [PATCH 10/12] DebugDraw_new -> CppDebugDraw_new --- liquidfun-c/Box2D/Common/c_b2Draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.cpp b/liquidfun-c/Box2D/Common/c_b2Draw.cpp index e3c117f..0400ea4 100644 --- a/liquidfun-c/Box2D/Common/c_b2Draw.cpp +++ b/liquidfun-c/Box2D/Common/c_b2Draw.cpp @@ -3,7 +3,7 @@ extern "C" { - CppDebugDraw* DebugDraw_new(BoxDebugDraw* debugDraw) { + CppDebugDraw* CppDebugDraw_new(BoxDebugDraw* debugDraw) { return new CppDebugDraw(debugDraw); } From 2ef514d159171dee4f08dbdcc89d8954d79f4a92 Mon Sep 17 00:00:00 2001 From: Boscop Date: Wed, 9 Nov 2016 19:35:14 +0100 Subject: [PATCH 11/12] use pointer for Draw instead of Box --- src/box2d/common/draw.rs | 24 ++++++++++++------------ src/box2d/dynamics/world.rs | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/box2d/common/draw.rs b/src/box2d/common/draw.rs index d3e34c8..93f5c97 100644 --- a/src/box2d/common/draw.rs +++ b/src/box2d/common/draw.rs @@ -54,81 +54,81 @@ pub trait Draw { fn draw_transform(&mut self, xf: &Transform); } -pub type BoxDebugDraw = Box; +pub type BoxDebugDraw = *mut Draw; #[no_mangle] pub extern fn BoxDebugDraw_SetFlags(this: *mut BoxDebugDraw, flags: UInt32) { unsafe { - (*this).set_flags(flags); + (**this).set_flags(flags); } } #[no_mangle] pub extern fn BoxDebugDraw_GetFlags(this: *mut BoxDebugDraw) -> UInt32 { unsafe { - (*this).get_flags() + (**this).get_flags() } } #[no_mangle] pub extern fn BoxDebugDraw_AppendFlags(this: *mut BoxDebugDraw, flags: UInt32) { unsafe { - (*this).append_flags(flags); + (**this).append_flags(flags); } } #[no_mangle] pub extern fn BoxDebugDraw_ClearFlags(this: *mut BoxDebugDraw, flags: UInt32) { unsafe { - (*this).clear_flags(flags); + (**this).clear_flags(flags); } } #[no_mangle] pub extern fn BoxDebugDraw_DrawPolygon(this: *mut BoxDebugDraw, vertices: *const Vec2, vertexCount: Int32, color: &Color) { unsafe { - (*this).draw_polygon(from_raw_parts(vertices, vertexCount as usize), color); + (**this).draw_polygon(from_raw_parts(vertices, vertexCount as usize), color); } } #[no_mangle] pub extern fn BoxDebugDraw_DrawSolidPolygon(this: *mut BoxDebugDraw, vertices: *const Vec2, vertexCount: Int32, color: &Color) { unsafe { - (*this).draw_solid_polygon(from_raw_parts(vertices, vertexCount as usize), color); + (**this).draw_solid_polygon(from_raw_parts(vertices, vertexCount as usize), color); } } #[no_mangle] pub extern fn BoxDebugDraw_DrawCircle(this: *mut BoxDebugDraw, center: &Vec2, radius: f32, color: &Color) { unsafe { - (*this).draw_circle(center, radius, color); + (**this).draw_circle(center, radius, color); } } #[no_mangle] pub extern fn BoxDebugDraw_DrawSolidCircle(this: *mut BoxDebugDraw, center: &Vec2, radius: f32, axis: &Vec2, color: &Color) { unsafe { - (*this).draw_solid_circle(center, radius, axis, color); + (**this).draw_solid_circle(center, radius, axis, color); } } #[no_mangle] pub extern fn BoxDebugDraw_DrawParticles(this: *mut BoxDebugDraw, centers: *const Vec2, radius: f32, colors: *const ParticleColor, count: Int32) { unsafe { - (*this).draw_particles(from_raw_parts(centers, count as usize), from_raw_parts(colors, count as usize), radius); + (**this).draw_particles(from_raw_parts(centers, count as usize), from_raw_parts(colors, count as usize), radius); } } #[no_mangle] pub extern fn BoxDebugDraw_DrawSegment(this: *mut BoxDebugDraw, p1: &Vec2, p2: &Vec2, color: &Color) { unsafe { - (*this).draw_segment(p1, p2, color); + (**this).draw_segment(p1, p2, color); } } #[no_mangle] pub extern fn BoxDebugDraw_DrawTransform(this: *mut BoxDebugDraw, xf: &Transform) { unsafe { - (*this).draw_transform(xf); + (**this).draw_transform(xf); } } diff --git a/src/box2d/dynamics/world.rs b/src/box2d/dynamics/world.rs index 29697ab..a3faa56 100644 --- a/src/box2d/dynamics/world.rs +++ b/src/box2d/dynamics/world.rs @@ -182,7 +182,7 @@ impl World { /// Register a routine for debug drawing. The debug draw functions are called /// inside with b2World::DrawDebugData method. The debug draw object is owned /// by you and must remain in scope. - pub fn set_debug_draw(&mut self, debug_draw: &mut BoxDebugDraw) { + pub fn set_debug_draw(&mut self, debug_draw: *mut BoxDebugDraw) { unsafe { b2World_SetDebugDraw(self.ptr, CppDebugDraw_new(debug_draw)); } From 42bdd8fbc3157d0e0033bbaaa8c821d87ec78dea Mon Sep 17 00:00:00 2001 From: Boscop Date: Thu, 10 Nov 2016 09:42:22 +0100 Subject: [PATCH 12/12] fixes and debug draw example --- examples/debug_draw.rs | 128 +++++++ liquidfun-c/Box2D/Common/c_b2Draw.cpp | 22 +- liquidfun-c/Box2D/Common/c_b2Draw.h | 63 ++- liquidfun-c/Box2D/Dynamics/c_b2World.cpp | 4 + liquidfun-c/Box2D/Dynamics/c_b2World.h | 1 + liquidfun-cpp/Box2D/Dynamics/b2World.h | 4 + src/box2d/common/draw.rs | 66 ++-- src/box2d/dynamics/world.rs | 466 ++++++++++++++--------- src/lib.rs | 1 + 9 files changed, 495 insertions(+), 260 deletions(-) create mode 100644 examples/debug_draw.rs diff --git a/examples/debug_draw.rs b/examples/debug_draw.rs new file mode 100644 index 0000000..248222e --- /dev/null +++ b/examples/debug_draw.rs @@ -0,0 +1,128 @@ +#![feature(box_syntax)] +use std::any::Any; + +extern crate libc; +extern crate liquidfun; + +use liquidfun::box2d::collision::shapes::polygon_shape::*; +use liquidfun::box2d::common::math::*; +use liquidfun::box2d::dynamics::body::*; +use liquidfun::box2d::dynamics::fixture::*; +use liquidfun::box2d::dynamics::world::*; +use liquidfun::box2d::common::draw::*; + +fn main() { + + // Define the gravity vector. + let gravity = Vec2::new(0.0, -10.0); + + // Construct a world object, which will hold and simulate the rigid bodies. + let mut world = World::new(&gravity); + + // Define the ground body. + let mut ground_body_def = BodyDef::default(); + ground_body_def.position.set(0.0, -10.0); + + // Call the body factory which allocates memory for the ground body + // from a pool and creates the ground box shape (also from a pool). + // The body is also added to the world. + let ground_body = world.create_body(&ground_body_def); + + // Define the ground box shape. + let mut ground_box = PolygonShape::new(); + + // The extents are the half-widths of the box. + ground_box.set_as_box(50.0, 10.0); + + // Add the ground fixture to the ground body. + ground_body.create_fixture_from_shape(&ground_box, 0.0); + + // Define the dynamic body. We set its position and call the body factory. + let mut body_def = BodyDef::default(); + body_def.body_type = BodyType::DynamicBody; + body_def.position.set(0.0, 4.0); + let body = world.create_body(&body_def); + + // Define another box shape for our dynamic body. + let mut dynamic_box = PolygonShape::new(); + dynamic_box.set_as_box(1.0, 1.0); + + // Define the dynamic body fixture. + let mut fixture_def = FixtureDef::new(&dynamic_box); + + // Set the box density to be non-zero, so it will be dynamic. + fixture_def.density = 1.0; + + // Override the default friction. + fixture_def.friction = 0.3; + + // Add the shape to the body. + body.create_fixture(&fixture_def); + + // Register a routine for debug drawing. The debug draw functions are called + // inside with World::draw_debug_data() method. The debug draw object is owned + // by you and must remain in scope. + let mut debug_draw = DebugDraw::new(MyDebugDraw::new()); + debug_draw.get().scale = 10.; + world.set_debug_draw(&mut debug_draw); + debug_draw.set_flags(!0); + + world.draw_debug_data(); + + /* this would crash: + { + let mut debug_draw = DebugDraw::new(MyDebugDraw::new()); + debug_draw.get().scale = 10.; + world.set_debug_draw(&mut debug_draw); + debug_draw.set_flags(!0); + } // debug_draw goes out of scope here but world still has pointer to it + + world.draw_debug_data(); + + // if debug_draw goes out of scope before world, call world.clear_debug_draw() + */ +} + +struct MyDebugDraw { + scale: f32, +} + +impl MyDebugDraw { + pub fn new() -> Self { + Self { + scale: 1., + } + } +} + +impl Drop for MyDebugDraw { + fn drop(&mut self) { + println!("drop MyDebugDraw"); + } +} + +impl Draw for MyDebugDraw { + fn as_any(&mut self) -> &mut Any { self } + fn draw_polygon(&mut self, vertices: &[Vec2], color: &Color) { + println!("self.scale {}", self.scale); + println!("draw_polygon {:?} {:?}", vertices, color); + } + fn draw_solid_polygon(&mut self, vertices: &[Vec2], color: &Color) { + println!("draw_solid_polygon {:?} {:?}", vertices, color); + } + fn draw_circle(&mut self, center: &Vec2, radius: f32, color: &Color) { + println!("draw_circle {:?} {:?} {:?}", center, radius, color); + } + fn draw_solid_circle(&mut self, center: &Vec2, radius: f32, axis: &Vec2, color: &Color) { + println!("draw_solid_circle {:?} {:?} {:?} {:?}", center, radius, axis, color); + } + fn draw_particles(&mut self, centers: &[Vec2], colors: &[ParticleColor], radius: f32) { + println!("draw_particles {:?} {:?} {:?}", centers, colors, radius); + } + fn draw_segment(&mut self, p1: &Vec2, p2: &Vec2, color: &Color) { + println!("draw_segment {:?} {:?} {:?}", p1, p2, color); + } + fn draw_transform(&mut self, xf: &Transform) { + println!("draw_transform {:?}", xf); + } +} diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.cpp b/liquidfun-c/Box2D/Common/c_b2Draw.cpp index 0400ea4..3af92da 100644 --- a/liquidfun-c/Box2D/Common/c_b2Draw.cpp +++ b/liquidfun-c/Box2D/Common/c_b2Draw.cpp @@ -3,8 +3,28 @@ extern "C" { - CppDebugDraw* CppDebugDraw_new(BoxDebugDraw* debugDraw) { + CppDebugDraw* CppDebugDraw_new(DrawTrait* debugDraw) { return new CppDebugDraw(debugDraw); } + void CppDebugDraw_delete(CppDebugDraw* debugDraw) { + delete debugDraw; + } + + void CppDebugDraw_SetFlags(CppDebugDraw* self, uint32 flags) { + return self->SetFlags(flags); + } + + uint32 CppDebugDraw_GetFlags(CppDebugDraw* self) { + return self->GetFlags(); + } + + void CppDebugDraw_AppendFlags(CppDebugDraw* self, uint32 flags) { + return self->AppendFlags(flags); + } + + void CppDebugDraw_ClearFlags(CppDebugDraw* self, uint32 flags) { + return self->ClearFlags(flags); + } + } // extern C diff --git a/liquidfun-c/Box2D/Common/c_b2Draw.h b/liquidfun-c/Box2D/Common/c_b2Draw.h index 003dfb3..8f80741 100644 --- a/liquidfun-c/Box2D/Common/c_b2Draw.h +++ b/liquidfun-c/Box2D/Common/c_b2Draw.h @@ -1,85 +1,70 @@ #ifndef C_B2_DRAW #define C_B2_DRAW -struct BoxDebugDraw {}; +struct DrawTrait {}; #ifdef __cplusplus extern "C" { #endif - void BoxDebugDraw_SetFlags(BoxDebugDraw* self, uint32 flags); - uint32 BoxDebugDraw_GetFlags(const BoxDebugDraw* self); - void BoxDebugDraw_AppendFlags(BoxDebugDraw* self, uint32 flags); - void BoxDebugDraw_ClearFlags(BoxDebugDraw* self, uint32 flags); - void BoxDebugDraw_DrawPolygon(BoxDebugDraw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); - void BoxDebugDraw_DrawSolidPolygon(BoxDebugDraw* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); - void BoxDebugDraw_DrawCircle(BoxDebugDraw* self, const b2Vec2& center, float32 radius, const b2Color& color); - void BoxDebugDraw_DrawSolidCircle(BoxDebugDraw* self, const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color); - void BoxDebugDraw_DrawParticles(BoxDebugDraw* self, const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count); - void BoxDebugDraw_DrawSegment(BoxDebugDraw* self, const b2Vec2& p1, const b2Vec2& p2, const b2Color& color); - void BoxDebugDraw_DrawTransform(BoxDebugDraw* self, const b2Transform& xf); + void DrawTrait_DrawPolygon(DrawTrait* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); + void DrawTrait_DrawSolidPolygon(DrawTrait* self, const b2Vec2* vertices, int32 vertexCount, const b2Color& color); + void DrawTrait_DrawCircle(DrawTrait* self, const b2Vec2& center, float32 radius, const b2Color& color); + void DrawTrait_DrawSolidCircle(DrawTrait* self, const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color); + void DrawTrait_DrawParticles(DrawTrait* self, const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count); + void DrawTrait_DrawSegment(DrawTrait* self, const b2Vec2& p1, const b2Vec2& p2, const b2Color& color); + void DrawTrait_DrawTransform(DrawTrait* self, const b2Transform& xf); #ifdef __cplusplus } // extern C #endif -class CppDebugDraw: b2Draw { +class CppDebugDraw: public b2Draw { public: - CppDebugDraw(BoxDebugDraw* debugDraw): self(debugDraw) {} - - void SetFlags(uint32 flags) { - BoxDebugDraw_SetFlags(self, flags); - } - - uint32 GetFlags() const { - return BoxDebugDraw_GetFlags(self); - } - - void AppendFlags(uint32 flags) { - BoxDebugDraw_AppendFlags(self, flags); - } - - void ClearFlags(uint32 flags) { - BoxDebugDraw_ClearFlags(self, flags); - } + CppDebugDraw(DrawTrait* debugDraw): self(debugDraw) {} virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) { - BoxDebugDraw_DrawPolygon(self, vertices, vertexCount, color); + DrawTrait_DrawPolygon(self, vertices, vertexCount, color); } virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) { - BoxDebugDraw_DrawSolidPolygon(self, vertices, vertexCount, color); + DrawTrait_DrawSolidPolygon(self, vertices, vertexCount, color); } virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) { - BoxDebugDraw_DrawCircle(self, center, radius, color); + DrawTrait_DrawCircle(self, center, radius, color); } virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) { - BoxDebugDraw_DrawSolidCircle(self, center, radius, axis, color); + DrawTrait_DrawSolidCircle(self, center, radius, axis, color); } virtual void DrawParticles(const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count) { - BoxDebugDraw_DrawParticles(self, centers, radius, colors, count); + DrawTrait_DrawParticles(self, centers, radius, colors, count); } virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) { - BoxDebugDraw_DrawSegment(self, p1, p2, color); + DrawTrait_DrawSegment(self, p1, p2, color); } virtual void DrawTransform(const b2Transform& xf) { - BoxDebugDraw_DrawTransform(self, xf); + DrawTrait_DrawTransform(self, xf); } protected: - BoxDebugDraw* self; + DrawTrait* self; }; #ifdef __cplusplus extern "C" { #endif - CppDebugDraw* DebugDraw_new(BoxDebugDraw* debugDraw); + CppDebugDraw* CppDebugDraw_new(DrawTrait* debugDraw); + void CppDebugDraw_delete(CppDebugDraw* self); + void CppDebugDraw_SetFlags(CppDebugDraw* self, uint32 flags); + uint32 CppDebugDraw_GetFlags(CppDebugDraw* self); + void CppDebugDraw_AppendFlags(CppDebugDraw* self, uint32 flags); + void CppDebugDraw_ClearFlags(CppDebugDraw* self, uint32 flags); #ifdef __cplusplus } // extern C diff --git a/liquidfun-c/Box2D/Dynamics/c_b2World.cpp b/liquidfun-c/Box2D/Dynamics/c_b2World.cpp index 9bf6e9f..9b93e6f 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2World.cpp +++ b/liquidfun-c/Box2D/Dynamics/c_b2World.cpp @@ -92,6 +92,10 @@ extern "C" { self->SetDebugDraw(debugDraw); } + /*b2Draw* b2World_GetDebugDraw(b2World* self) { + return self->GetDebugDraw(); + }*/ + void b2World_DrawDebugData(b2World* self) { self->DrawDebugData(); } diff --git a/liquidfun-c/Box2D/Dynamics/c_b2World.h b/liquidfun-c/Box2D/Dynamics/c_b2World.h index 796627d..3702e8c 100644 --- a/liquidfun-c/Box2D/Dynamics/c_b2World.h +++ b/liquidfun-c/Box2D/Dynamics/c_b2World.h @@ -39,6 +39,7 @@ extern "C" { b2ParticleSystem* b2World_CreateParticleSystem(b2World* self, const b2ParticleSystemDef* def); void b2World_Step(b2World* self, float32 timeStep, int32 velocityIterations, int32 positionIterations); void b2World_SetDebugDraw(b2World* self, b2Draw* debugDraw); + // b2Draw* b2World_GetDebugDraw(b2World* self); void b2World_DrawDebugData(b2World* self); #ifdef __cplusplus diff --git a/liquidfun-cpp/Box2D/Dynamics/b2World.h b/liquidfun-cpp/Box2D/Dynamics/b2World.h index ce0b8c1..ae098d9 100644 --- a/liquidfun-cpp/Box2D/Dynamics/b2World.h +++ b/liquidfun-cpp/Box2D/Dynamics/b2World.h @@ -69,6 +69,10 @@ class b2World /// by you and must remain in scope. void SetDebugDraw(b2Draw* debugDraw); + /*b2Draw* GetDebugDraw() { + return m_debugDraw; + }*/ + /// Create a rigid body given a definition. No reference to the definition /// is retained. /// @warning This function is locked during callbacks. diff --git a/src/box2d/common/draw.rs b/src/box2d/common/draw.rs index 93f5c97..d65d422 100644 --- a/src/box2d/common/draw.rs +++ b/src/box2d/common/draw.rs @@ -1,6 +1,7 @@ #![allow(non_snake_case)] use std::slice::from_raw_parts; +use std::any::Any; use super::math::*; use super::settings::*; @@ -41,93 +42,78 @@ pub struct ParticleColor { pub r: u8, pub g: u8, pub b: u8, pub a: u8 } /// Implement and register this trait with a World to provide debug drawing of physics /// using World.set_debug_draw() pub trait Draw { - fn set_flags(&mut self, flags: UInt32); - fn get_flags(&self) -> UInt32; - fn append_flags(&mut self, flags: UInt32); - fn clear_flags(&mut self, flags: UInt32); + + /// Put this in your impl: fn as_any(&mut self) -> &mut Any { self } + fn as_any(&mut self) -> &mut Any; + + /// Draw a closed polygon provided in CCW order. fn draw_polygon(&mut self, vertices: &[Vec2], color: &Color); + + /// Draw a solid closed polygon provided in CCW order. fn draw_solid_polygon(&mut self, vertices: &[Vec2], color: &Color); + + /// Draw a circle. fn draw_circle(&mut self, center: &Vec2, radius: f32, color: &Color); - fn draw_solid_circle(&mut self, center: &Vec2, radius: f32, axis: &Vec2, color: &Color); - fn draw_particles(&mut self, centers: &[Vec2], colors: &[ParticleColor], radius: f32); - fn draw_segment(&mut self, p1: &Vec2, p2: &Vec2, color: &Color); - fn draw_transform(&mut self, xf: &Transform); -} -pub type BoxDebugDraw = *mut Draw; + /// Draw a solid circle. + fn draw_solid_circle(&mut self, center: &Vec2, radius: f32, axis: &Vec2, color: &Color); -#[no_mangle] -pub extern fn BoxDebugDraw_SetFlags(this: *mut BoxDebugDraw, flags: UInt32) { - unsafe { - (**this).set_flags(flags); - } -} + /// Draw a particle array + fn draw_particles(&mut self, centers: &[Vec2], colors: &[ParticleColor], radius: f32); -#[no_mangle] -pub extern fn BoxDebugDraw_GetFlags(this: *mut BoxDebugDraw) -> UInt32 { - unsafe { - (**this).get_flags() - } -} + /// Draw a line segment. + fn draw_segment(&mut self, p1: &Vec2, p2: &Vec2, color: &Color); -#[no_mangle] -pub extern fn BoxDebugDraw_AppendFlags(this: *mut BoxDebugDraw, flags: UInt32) { - unsafe { - (**this).append_flags(flags); - } + /// Draw a transform. Choose your own length scale. + fn draw_transform(&mut self, xf: &Transform); } -#[no_mangle] -pub extern fn BoxDebugDraw_ClearFlags(this: *mut BoxDebugDraw, flags: UInt32) { - unsafe { - (**this).clear_flags(flags); - } -} +pub type DrawTrait = Box; #[no_mangle] -pub extern fn BoxDebugDraw_DrawPolygon(this: *mut BoxDebugDraw, vertices: *const Vec2, vertexCount: Int32, color: &Color) { +pub extern fn DrawTrait_DrawPolygon(this: *mut DrawTrait, vertices: *const Vec2, vertexCount: Int32, color: &Color) { unsafe { (**this).draw_polygon(from_raw_parts(vertices, vertexCount as usize), color); } } #[no_mangle] -pub extern fn BoxDebugDraw_DrawSolidPolygon(this: *mut BoxDebugDraw, vertices: *const Vec2, vertexCount: Int32, color: &Color) { +pub extern fn DrawTrait_DrawSolidPolygon(this: *mut DrawTrait, vertices: *const Vec2, vertexCount: Int32, color: &Color) { unsafe { (**this).draw_solid_polygon(from_raw_parts(vertices, vertexCount as usize), color); } } #[no_mangle] -pub extern fn BoxDebugDraw_DrawCircle(this: *mut BoxDebugDraw, center: &Vec2, radius: f32, color: &Color) { +pub extern fn DrawTrait_DrawCircle(this: *mut DrawTrait, center: &Vec2, radius: f32, color: &Color) { unsafe { (**this).draw_circle(center, radius, color); } } #[no_mangle] -pub extern fn BoxDebugDraw_DrawSolidCircle(this: *mut BoxDebugDraw, center: &Vec2, radius: f32, axis: &Vec2, color: &Color) { +pub extern fn DrawTrait_DrawSolidCircle(this: *mut DrawTrait, center: &Vec2, radius: f32, axis: &Vec2, color: &Color) { unsafe { (**this).draw_solid_circle(center, radius, axis, color); } } #[no_mangle] -pub extern fn BoxDebugDraw_DrawParticles(this: *mut BoxDebugDraw, centers: *const Vec2, radius: f32, colors: *const ParticleColor, count: Int32) { +pub extern fn DrawTrait_DrawParticles(this: *mut DrawTrait, centers: *const Vec2, radius: f32, colors: *const ParticleColor, count: Int32) { unsafe { (**this).draw_particles(from_raw_parts(centers, count as usize), from_raw_parts(colors, count as usize), radius); } } #[no_mangle] -pub extern fn BoxDebugDraw_DrawSegment(this: *mut BoxDebugDraw, p1: &Vec2, p2: &Vec2, color: &Color) { +pub extern fn DrawTrait_DrawSegment(this: *mut DrawTrait, p1: &Vec2, p2: &Vec2, color: &Color) { unsafe { (**this).draw_segment(p1, p2, color); } } #[no_mangle] -pub extern fn BoxDebugDraw_DrawTransform(this: *mut BoxDebugDraw, xf: &Transform) { +pub extern fn DrawTrait_DrawTransform(this: *mut DrawTrait, xf: &Transform) { unsafe { (**this).draw_transform(xf); } diff --git a/src/box2d/dynamics/world.rs b/src/box2d/dynamics/world.rs index a3faa56..89ba76e 100644 --- a/src/box2d/dynamics/world.rs +++ b/src/box2d/dynamics/world.rs @@ -1,52 +1,52 @@ use libc::size_t; use std::ptr; +use std::marker::PhantomData; + use super::body::*; use super::super::common::math::*; use super::super::common::settings::*; use super::super::particle::particle_system::*; use super::joints; -use super::super::common::draw::BoxDebugDraw; +use super::super::common::draw::*; pub enum B2World {} extern { - fn b2World_CreateBody(world: *mut B2World, bd: *const BodyDef) -> *mut B2Body; - fn b2World_CreateParticleSystem(world: *mut B2World, def: *const ParticleSystemDef) -> *mut B2ParticleSystem; - fn b2World_Delete(world: *mut B2World); - fn b2World_GetBodyCount(world: *const B2World) -> Int32; - fn b2World_GetJointCount(world: *const B2World) -> Int32; - fn b2World_GetBodyList(world: *const B2World) -> *mut B2Body; - fn b2World_GetGravity(world: *mut B2World) -> Vec2; - fn b2World_GetParticleSystemList(world: *const B2World) -> *mut B2ParticleSystem; - fn b2World_New(gravity: *const Vec2) -> *mut B2World; - fn b2World_Step(this: *mut B2World, timeStep: Float32, velocityIterations: Int32, positionIterations: Int32); - - fn b2World_CreateRevoluteJoint( - world: *mut B2World, - - joint_type: joints::JointType, - user_data: size_t, - body_a: *mut B2Body, - body_b: *mut B2Body, - collide_connected: bool, - - local_anchor_a: Vec2, - local_anchor_b: Vec2, - reference_angle: Float32, - enable_limit: bool, - lower_angle: Float32, - upper_angle: Float32, - enable_motor: bool, - motor_speed: Float32, - max_motor_torque: Float32 - ) -> *mut joints::revolute_joint::B2RevoluteJoint; - - fn CppDebugDraw_new(debug_draw: *mut BoxDebugDraw) -> *mut CppDebugDraw; - fn b2World_SetDebugDraw(this: *mut B2World, debug_draw: *mut CppDebugDraw); - fn b2World_DrawDebugData(this: *mut B2World); -} + fn b2World_CreateBody(world: *mut B2World, bd: *const BodyDef) -> *mut B2Body; + fn b2World_CreateParticleSystem(world: *mut B2World, def: *const ParticleSystemDef) -> *mut B2ParticleSystem; + fn b2World_Delete(world: *mut B2World); + fn b2World_GetBodyCount(world: *const B2World) -> Int32; + fn b2World_GetJointCount(world: *const B2World) -> Int32; + fn b2World_GetBodyList(world: *const B2World) -> *mut B2Body; + fn b2World_GetGravity(world: *mut B2World) -> Vec2; + fn b2World_GetParticleSystemList(world: *const B2World) -> *mut B2ParticleSystem; + fn b2World_New(gravity: *const Vec2) -> *mut B2World; + fn b2World_Step(this: *mut B2World, timeStep: Float32, velocityIterations: Int32, positionIterations: Int32); -pub enum CppDebugDraw {} + fn b2World_CreateRevoluteJoint( + world: *mut B2World, + + joint_type: joints::JointType, + user_data: size_t, + body_a: *mut B2Body, + body_b: *mut B2Body, + collide_connected: bool, + + local_anchor_a: Vec2, + local_anchor_b: Vec2, + reference_angle: Float32, + enable_limit: bool, + lower_angle: Float32, + upper_angle: Float32, + enable_motor: bool, + motor_speed: Float32, + max_motor_torque: Float32 + ) -> *mut joints::revolute_joint::B2RevoluteJoint; + + fn b2World_SetDebugDraw(this: *mut B2World, debug_draw: *mut CppDebugDraw); + // fn b2World_GetDebugDraw(this: *mut B2World) -> *mut CppDebugDraw; + fn b2World_DrawDebugData(this: *mut B2World); +} /// The world class manages all physics entities, dynamic simulation, /// and asynchronous queries. The world also contains efficient memory @@ -57,150 +57,256 @@ pub struct World { impl World { - /// Construct a world object. - /// @param gravity the world gravity vector. - pub fn new(gravity: &Vec2) -> World { - unsafe { - World { ptr: b2World_New(gravity) } - } - } - - /// Create a rigid body given a definition. No reference to the definition - /// is retained. - /// @warning This function is locked during callbacks. - pub fn create_body(&mut self, def: &BodyDef) -> Body { - unsafe { - Body { ptr: b2World_CreateBody(self.ptr, def) } - } - } - - /// Create a revolute joint to constrain bodies together. No reference to the definition - /// is retained. This may cause the connected bodies to cease colliding. - /// @warning This function is locked during callbacks. - pub fn create_revolute_joint(&mut self, def: &(joints::JointDef, joints::revolute_joint::RevoluteJointDef)) -> joints::revolute_joint::RevoluteJoint { - unsafe { - joints::revolute_joint::RevoluteJoint {ptr: b2World_CreateRevoluteJoint( - self.ptr, - def.0.joint_type, - def.0.user_data, - match def.0.body_a { - Some(ref b) =>b.ptr, - None => ptr::null_mut() - }, - match def.0.body_b { - Some(ref b) =>b.ptr, - None => ptr::null_mut() - }, - def.0.collide_connected, - def.1.local_anchor_a, - def.1.local_anchor_b, - def.1.reference_angle, - def.1.enable_limit, - def.1.lower_angle, - def.1.upper_angle, - def.1.enable_motor, - def.1.motor_speed, - def.1.max_motor_torque - )} - } - } - - /// Create a particle system given a definition. No reference to the - /// definition is retained. - /// @warning This function is locked during callbacks. - pub fn create_particle_system(&self, def: &ParticleSystemDef) -> ParticleSystem { - unsafe { - ParticleSystem { ptr: b2World_CreateParticleSystem(self.ptr, def) } - } - } - - /// Get the number of bodies. - pub fn get_body_count(&self) -> i32 { - unsafe { - b2World_GetBodyCount(self.ptr) - } - } - - /// Get the number of joints. - pub fn get_joint_count(&self) -> i32 { - unsafe { - b2World_GetJointCount(self.ptr) - } - } - - /// Get the world body list. With the returned body, use b2Body::GetNext to get - /// the next body in the world list. A NULL body indicates the end of the list. - /// @return the head of the world body list. - pub fn get_body_list(&self) -> Option { - let ptr; - unsafe { - ptr = b2World_GetBodyList(self.ptr); - } - - if ptr.is_null() { - None - } else { - Some(Body { ptr: ptr }) - } - } - - /// Get the world particle-system list. With the returned body, use - /// b2ParticleSystem::GetNext to get the next particle-system in the world - /// list. A NULL particle-system indicates the end of the list. - /// @return the head of the world particle-system list. - pub fn get_particle_system_list(&self) -> Option { - let ptr; - unsafe { - ptr = b2World_GetParticleSystemList(self.ptr); - } - - if ptr.is_null() { - None - } else { - Some(ParticleSystem { ptr: ptr }) - } - } - - /// Get the global gravity vector. - pub fn get_gravity(&mut self) -> Vec2 { - unsafe { - b2World_GetGravity(self.ptr) - } - } - - /// Take a time step. This performs collision detection, integration, - /// and constraint solution. - /// @param timeStep the amount of time to simulate, this should not vary. - /// @param velocityIterations for the velocity constraint solver. - /// @param positionIterations for the position constraint solver. - pub fn step(&mut self, time_step: f32, velocity_iterations: i32, position_iterations: i32) { - unsafe { - b2World_Step(self.ptr, time_step, velocity_iterations, position_iterations); - } - } - - /// Register a routine for debug drawing. The debug draw functions are called - /// inside with b2World::DrawDebugData method. The debug draw object is owned - /// by you and must remain in scope. - pub fn set_debug_draw(&mut self, debug_draw: *mut BoxDebugDraw) { - unsafe { - b2World_SetDebugDraw(self.ptr, CppDebugDraw_new(debug_draw)); - } - } - - /// Call this to draw shapes and other debug draw data. This is intentionally non-const. - pub fn draw_debug_data(&mut self) { - unsafe { - b2World_DrawDebugData(self.ptr); - } - } + /// Construct a world object. + /// @param gravity the world gravity vector. + pub fn new(gravity: &Vec2) -> World { + unsafe { + World { ptr: b2World_New(gravity) } + } + } + + /// Create a rigid body given a definition. No reference to the definition + /// is retained. + /// @warning This function is locked during callbacks. + pub fn create_body(&mut self, def: &BodyDef) -> Body { + unsafe { + Body { ptr: b2World_CreateBody(self.ptr, def) } + } + } + + /// Create a revolute joint to constrain bodies together. No reference to the definition + /// is retained. This may cause the connected bodies to cease colliding. + /// @warning This function is locked during callbacks. + pub fn create_revolute_joint(&mut self, def: &(joints::JointDef, joints::revolute_joint::RevoluteJointDef)) -> joints::revolute_joint::RevoluteJoint { + unsafe { + joints::revolute_joint::RevoluteJoint {ptr: b2World_CreateRevoluteJoint( + self.ptr, + def.0.joint_type, + def.0.user_data, + match def.0.body_a { + Some(ref b) =>b.ptr, + None => ptr::null_mut() + }, + match def.0.body_b { + Some(ref b) =>b.ptr, + None => ptr::null_mut() + }, + def.0.collide_connected, + def.1.local_anchor_a, + def.1.local_anchor_b, + def.1.reference_angle, + def.1.enable_limit, + def.1.lower_angle, + def.1.upper_angle, + def.1.enable_motor, + def.1.motor_speed, + def.1.max_motor_torque + )} + } + } + + /// Create a particle system given a definition. No reference to the + /// definition is retained. + /// @warning This function is locked during callbacks. + pub fn create_particle_system(&self, def: &ParticleSystemDef) -> ParticleSystem { + unsafe { + ParticleSystem { ptr: b2World_CreateParticleSystem(self.ptr, def) } + } + } + + /// Get the number of bodies. + pub fn get_body_count(&self) -> i32 { + unsafe { + b2World_GetBodyCount(self.ptr) + } + } + + /// Get the number of joints. + pub fn get_joint_count(&self) -> i32 { + unsafe { + b2World_GetJointCount(self.ptr) + } + } + /// Get the world body list. With the returned body, use b2Body::GetNext to get + /// the next body in the world list. A NULL body indicates the end of the list. + /// @return the head of the world body list. + pub fn get_body_list(&self) -> Option { + let ptr; + unsafe { + ptr = b2World_GetBodyList(self.ptr); + } + + if ptr.is_null() { + None + } else { + Some(Body { ptr: ptr }) + } + } + + /// Get the world particle-system list. With the returned body, use + /// b2ParticleSystem::GetNext to get the next particle-system in the world + /// list. A NULL particle-system indicates the end of the list. + /// @return the head of the world particle-system list. + pub fn get_particle_system_list(&self) -> Option { + let ptr; + unsafe { + ptr = b2World_GetParticleSystemList(self.ptr); + } + + if ptr.is_null() { + None + } else { + Some(ParticleSystem { ptr: ptr }) + } + } + + /// Get the global gravity vector. + pub fn get_gravity(&mut self) -> Vec2 { + unsafe { + b2World_GetGravity(self.ptr) + } + } + + /// Take a time step. This performs collision detection, integration, + /// and constraint solution. + /// @param timeStep the amount of time to simulate, this should not vary. + /// @param velocityIterations for the velocity constraint solver. + /// @param positionIterations for the position constraint solver. + pub fn step(&mut self, time_step: f32, velocity_iterations: i32, position_iterations: i32) { + unsafe { + b2World_Step(self.ptr, time_step, velocity_iterations, position_iterations); + } + } + + /// Register a routine for debug drawing. The debug draw functions are called + /// inside with World::draw_debug_data() method. The debug draw object is owned + /// by you and must remain in scope. + pub fn set_debug_draw(&mut self, debug_draw: &mut DebugDraw) { + unsafe { + b2World_SetDebugDraw(self.ptr, debug_draw.handle.ptr); + } + } + + /// World stores a pointer to DebugDraw when you call World.set_debug_draw(). + /// You have to make sure your DebugDraw instance stays alive as long as the world. + /// If the world outlives your DebugDraw instance, draw_debug_data() would dereference + /// an invalid pointer. So call this function to set the internal DebugDraw pointer to null. + pub fn clear_debug_draw(&mut self) { + unsafe { + b2World_SetDebugDraw(self.ptr, ptr::null_mut()); + } + } + + /// Call this to draw shapes and other debug draw data. This is intentionally non-const. + pub fn draw_debug_data(&mut self) { + unsafe { + b2World_DrawDebugData(self.ptr); + } + } } impl Drop for World { - fn drop(&mut self) { - unsafe { - b2World_Delete(self.ptr); - } - } -} \ No newline at end of file + fn drop(&mut self) { + unsafe { + b2World_Delete(self.ptr); + } + } +} + +pub enum CppDebugDraw {} + +extern { + fn CppDebugDraw_new(debug_draw: *mut DrawTrait) -> *mut CppDebugDraw; + fn CppDebugDraw_delete(this: *mut CppDebugDraw); + fn CppDebugDraw_SetFlags(this: *mut CppDebugDraw, flags: UInt32); + fn CppDebugDraw_GetFlags(this: *mut CppDebugDraw) -> UInt32; + fn CppDebugDraw_AppendFlags(this: *mut CppDebugDraw, flags: UInt32); + fn CppDebugDraw_ClearFlags(this: *mut CppDebugDraw, flags: UInt32); +} + +struct CppDebugDrawHandle { + draw_trait: *mut DrawTrait, + ptr: *mut CppDebugDraw, +} + +impl CppDebugDrawHandle { + pub fn new(debug_draw: *mut DrawTrait) -> Self { + unsafe { + Self { + draw_trait: debug_draw, + ptr: CppDebugDraw_new(debug_draw) + } + } + } +} + +impl Drop for CppDebugDrawHandle { + fn drop(&mut self) { + unsafe { + CppDebugDraw_delete(self.ptr); + } + } +} + +/// Call DebugDraw::new() to create a new DebugDraw instance from an instance of your type +/// that implements the Draw trait and pass this to World::set_debug_draw() +pub struct DebugDraw { + handle: CppDebugDrawHandle, + phantom: PhantomData, +} + +impl DebugDraw { + + /// Creates a new DebugDraw instance. + pub fn new(debug_draw: T) -> Self { + Self { + handle: CppDebugDrawHandle::new(Box::into_raw(box (box debug_draw as Box))), + phantom: PhantomData, + } + } + + /// Get direct access to your Draw instance. + pub fn get(&mut self) -> &mut T { + match unsafe { (*self.handle.draw_trait).as_any().downcast_mut::() } { + Some(x) => x, + None => panic!("invalid downcast of Box to Box where T: Draw") + } + } + + /// Set the drawing flags. + pub fn set_flags(&mut self, flags: u32) { + unsafe { + CppDebugDraw_SetFlags(self.handle.ptr, flags); + } + } + + /// Get the drawing flags. + pub fn get_flags(&mut self) -> u32 { + unsafe { + CppDebugDraw_GetFlags(self.handle.ptr) + } + } + + /// Append flags to the current flags. + pub fn append_flags(&mut self, flags: u32) { + unsafe { + CppDebugDraw_AppendFlags(self.handle.ptr, flags); + } + } + + /// Clear flags from the current flags. + pub fn clear_flags(&mut self, flags: u32) { + unsafe { + CppDebugDraw_ClearFlags(self.handle.ptr, flags); + } + } +} + +impl Drop for DebugDraw { + fn drop(&mut self) { + unsafe { + drop(Box::from_raw(self.handle.draw_trait)); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index b2e7187..6bd79ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,6 +51,7 @@ //! ``` #![allow(renamed_and_removed_lints)] +#![feature(box_syntax)] extern crate libc; #[macro_use]