Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions examples/debug_draw.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
4 changes: 4 additions & 0 deletions liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ extern "C" {
return static_cast<b2Shape*>(reinterpret_cast<b2PolygonShape*>(self));
}

void b2PolygonShape_Set(b2PolygonShape* self, const b2Vec2* vertices, int32 count) {
self->Set(vertices, count);
}

} // extern C
2 changes: 1 addition & 1 deletion liquidfun-c/Box2D/Collision/Shapes/c_b2PolygonShape.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extern "C" {
void b2PolygonShape_SetAsBox(b2PolygonShape* self, float32 hx, float32 hy);
void b2PolygonShape_SetAsBox_Oriented(b2PolygonShape* self, float32 hx, float32 hy, const b2Vec2& center, float32 angle);
b2Shape* b2PolygonShape_Upcast(b2PolygonShape* self);

void b2PolygonShape_Set(b2PolygonShape* self, const b2Vec2* vertices, int32 count);

#ifdef __cplusplus
} // extern C
Expand Down
30 changes: 30 additions & 0 deletions liquidfun-c/Box2D/Common/c_b2Draw.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <Box2D/Box2D.h>
#include "c_b2Draw.h"

extern "C" {

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
73 changes: 73 additions & 0 deletions liquidfun-c/Box2D/Common/c_b2Draw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#ifndef C_B2_DRAW
#define C_B2_DRAW

struct DrawTrait {};

#ifdef __cplusplus
extern "C" {
#endif

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: public b2Draw {
public:
CppDebugDraw(DrawTrait* debugDraw): self(debugDraw) {}

virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {
DrawTrait_DrawPolygon(self, vertices, vertexCount, color);
}

virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {
DrawTrait_DrawSolidPolygon(self, vertices, vertexCount, color);
}

virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) {
DrawTrait_DrawCircle(self, center, radius, color);
}

virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) {
DrawTrait_DrawSolidCircle(self, center, radius, axis, color);
}

virtual void DrawParticles(const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count) {
DrawTrait_DrawParticles(self, centers, radius, colors, count);
}

virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) {
DrawTrait_DrawSegment(self, p1, p2, color);
}

virtual void DrawTransform(const b2Transform& xf) {
DrawTrait_DrawTransform(self, xf);
}

protected:
DrawTrait* self;
};

#ifdef __cplusplus
extern "C" {
#endif

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
#endif

#endif
24 changes: 18 additions & 6 deletions liquidfun-c/Box2D/Dynamics/c_b2Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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) {
Expand All @@ -35,9 +35,21 @@ 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);
}

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);
}

const b2Vec2& b2Body_GetLinearVelocity(const b2Body* self) {
return self->GetLinearVelocity();
}

} // extern C

5 changes: 4 additions & 1 deletion liquidfun-c/Box2D/Dynamics/c_b2Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +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);
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
Expand Down
12 changes: 12 additions & 0 deletions liquidfun-c/Box2D/Dynamics/c_b2World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ extern "C" {
self->Step(timeStep, velocityIterations, positionIterations);
}

void b2World_SetDebugDraw(b2World* self, b2Draw* debugDraw) {
// self->SetDebugDraw(new CppDebugDraw(debugDraw));
self->SetDebugDraw(debugDraw);
}

/*b2Draw* b2World_GetDebugDraw(b2World* self) {
return self->GetDebugDraw();
}*/

void b2World_DrawDebugData(b2World* self) {
self->DrawDebugData();
}

} // extern C

3 changes: 3 additions & 0 deletions liquidfun-c/Box2D/Dynamics/c_b2World.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ 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
} // extern C
Expand Down
1 change: 1 addition & 0 deletions liquidfun-c/c_box2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions liquidfun-cpp/Box2D/Dynamics/b2World.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions src/box2d/collision/shapes/polygon_shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ extern {
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_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
Expand Down Expand Up @@ -79,6 +80,15 @@ impl PolygonShape {
b2PolygonShape_SetAsBox_Oriented(self.ptr, hx, hy, center, angle);
}
}

/// Build a convex polygon.
/// @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 {
Expand Down
Loading