Add initial prototype.

This commit is contained in:
Rod Kay
2022-07-31 17:34:54 +10:00
commit 54a53b2ac0
1421 changed files with 358874 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
#include "box2d-conversions.h"

View File

@@ -0,0 +1,8 @@
#ifndef C_BOX2D_CONVERSIONS_H
#define C_BOX2D_CONVERSIONS_H
// Placeholder for possible future use.
#endif

View File

@@ -0,0 +1,332 @@
#include "box2d-joint.h"
#include "box2d-space.h"
#include "box2d-conversions.h"
#include "box2d-object-private.h"
#include <box2d/box2d.h>
#include <stdio.h>
////////////////
/// C++ Support
//
class my_b2RevoluteJoint : public b2RevoluteJoint // This is needed to expose the m_localAnchorA/B members for modification.
{
public:
/// The local anchor point relative to bodyA's origin.
b2Vec2& GetLocalAnchorA() { return m_localAnchorA; }
/// The local anchor point relative to bodyB's origin.
b2Vec2& GetLocalAnchorB() { return m_localAnchorB; }
};
extern "C"
{
//////////
/// Forge
//
Joint*
b2d_new_hinge_Joint_with_local_anchors
(Space* in_Space,
Object* Object_A,
Object* Object_B,
Vector_3* Anchor_in_A,
Vector_3* Anchor_in_B,
float low_Limit,
float high_Limit,
bool collide_Connected)
{
b2RevoluteJointDef* Self = new b2RevoluteJointDef();
Self->bodyA = (b2Body*) Object_A; // Using the jointDefs' bodyA/B to hold pointers to our 'fat' Object_A/B.
Self->bodyB = (b2Body*) Object_B; // The actual b2Body will be substituted when the joint is added to the world.
Self->localAnchorA = b2Vec2 (Anchor_in_A->x,
Anchor_in_A->y);
Self->localAnchorB = b2Vec2 (Anchor_in_B->x,
Anchor_in_B->y);
Self->lowerAngle = low_Limit;
Self->upperAngle = high_Limit;
Self->enableLimit = true;
Self->collideConnected = collide_Connected;
return (Joint*) dynamic_cast <b2JointDef*> (Self);
}
Joint*
b2d_new_hinge_Joint (Space* in_Space,
Object* Object_A,
Object* Object_B,
Matrix_4x4* Frame_A,
Matrix_4x4* Frame_B,
float low_Limit,
float high_Limit,
bool collide_Connected)
{
b2RevoluteJointDef* Self = new b2RevoluteJointDef();
Self->bodyA = (b2Body*) Object_A; // Using the jointDefs' bodyA/B to hold pointers to our 'fat' Object.
Self->bodyB = (b2Body*) Object_B; // The actual b2Body will be substituted when the joint is added to the world.
Self->lowerAngle = low_Limit;
Self->upperAngle = high_Limit;
Self->enableLimit = true;
Self->collideConnected = collide_Connected;
return (Joint*) dynamic_cast <b2JointDef*> (Self);
}
Joint*
b2d_new_space_hinge_Joint (Object* Object_A,
Matrix_4x4* Frame_A)
{
return 0;
}
void
b2d_free_hinge_Joint (Joint* Self)
{
b2JointDef* b2_Self = (b2JointDef*) Self;
b2RevoluteJointDef* b2_revolute_Self = (b2RevoluteJointDef*) b2_Self;
delete b2_revolute_Self;
}
Joint*
b2d_new_DoF6_Joint (Object* Object_A,
Object* Object_B,
Matrix_4x4* Frame_A,
Matrix_4x4* Frame_B)
{
return 0;
}
Joint*
b2d_new_cone_twist_Joint (Object* Object_A,
Object* Object_B,
Matrix_4x4* Frame_A,
Matrix_4x4* Frame_B)
{
return 0;
}
Joint*
b2d_new_slider_Joint (Object* Object_A,
Object* Object_B,
Matrix_4x4* Frame_A,
Matrix_4x4* Frame_B)
{
return 0;
}
Joint*
b2d_new_ball_Joint (Object* Object_A,
Object* Object_B,
Vector_3* Pivot_in_A,
Vector_3* Pivot_in_B)
{
return 0;
}
///////////////
/// Attributes
//
void
b2d_Joint_set_local_Anchor (Joint* Self, bool is_Anchor_A,
Vector_3* local_Anchor)
{
b2JointDef* b2_Self = (b2JointDef*) Self;
b2RevoluteJointDef* b2_revolute_Self = (b2RevoluteJointDef*) b2_Self;
b2Joint* b2_Joint = (b2Joint*) b2_revolute_Self->userData.pointer;
my_b2RevoluteJoint* b2_revolute_Joint = static_cast <my_b2RevoluteJoint*> (b2_Joint);
if (is_Anchor_A)
b2_revolute_Joint->GetLocalAnchorA() = (b2Vec2 (local_Anchor->x,
local_Anchor->y));
else
b2_revolute_Joint->GetLocalAnchorB() = (b2Vec2 (local_Anchor->x,
local_Anchor->y));
}
Vector_3
b2d_Joint_reaction_Force (Joint* Self)
{
b2JointDef* b2_Self = (b2JointDef*) Self;
b2Joint* b2_Joint = (b2Joint*) b2_Self->userData.pointer;
b2Vec2 the_Force = b2_Joint->GetReactionForce (1.0 / 60.0);
return {the_Force.x, the_Force.y, 0.0};
}
Real
b2d_Joint_reaction_Torque (Joint* Self)
{
b2JointDef* b2_Self = (b2JointDef*) Self;
b2Joint* b2_Joint = (b2Joint*) b2_Self->userData.pointer;
return b2_Joint->GetReactionTorque (1.0 / 60.0);
}
void*
b2d_Joint_user_Data (Joint* Self)
{
b2JointDef* b2_Self = (b2JointDef*) Self;
b2Joint* b2_Joint = (b2Joint*) b2_Self->userData.pointer;
return (void*) b2_Joint->GetUserData().pointer;
}
//void
//b2d_Joint_user_Data_is (Joint* Self, void* Now)
//{
// b2JointDef* b2_Self = (b2JointDef*) Self;
// b2Joint* b2_Joint = (b2Joint*) b2_Self->userData.pointer;
// return b2_Joint->SetUserData (Now);
//}
Object*
b2d_Joint_Object_A (Joint* Self)
{
return 0;
}
Object*
b2d_Joint_Object_B (Joint* Self)
{
return 0;
}
Matrix_4x4
b2d_Joint_Frame_A (Joint* Self)
{
Matrix_4x4 dummy;
return dummy;
}
Matrix_4x4
b2d_Joint_Frame_B (Joint* Self)
{
Matrix_4x4 dummy;
return dummy;
}
void
b2d_Joint_Frame_A_is (Joint* Self, Matrix_4x4* Now)
{
printf ("TODO: b3d_Joint_Frame_A_is");
}
void
b2d_Joint_Frame_B_is (Joint* Self, Matrix_4x4* Now)
{
printf ("TODO: b2d_Joint_Frame_B_is");
}
bool
b2d_Joint_is_Limited (Joint* Self, int DoF)
{
printf ("TODO: b2d_Joint_is_Limited");
return false;
}
bool
b2d_Joint_Extent (Joint* Self, int DoF)
{
printf ("TODO: b2d_Joint_Extent");
return false;
}
void
b2d_Joint_Velocity_is (Joint* Self, int DoF,
float Real)
{
printf ("TODO: b2d_Joint_Velocity_is");
}
/// Hinge
//
void
b2d_Joint_hinge_Limits_are (Joint* Self, Real Low,
Real High)
{
b2JointDef* b2_Self = (b2JointDef*) Self;
b2Joint* b2_Joint = (b2Joint*) b2_Self->userData.pointer;
b2RevoluteJoint* b2_Hinge = dynamic_cast <b2RevoluteJoint*> (b2_Joint);
if (b2_Hinge)
b2_Hinge->SetLimits (Low, High);
else
{
b2RevoluteJointDef* b2_revolute_Self = (b2RevoluteJointDef*) b2_Self;
b2_revolute_Self->lowerAngle = Low;
b2_revolute_Self->upperAngle = High;
}
}
} // extern "C"

View File

@@ -0,0 +1,106 @@
#ifndef C_BOX2D_JOINT_H
#define C_BOX2D_JOINT_H
#include "box2d.h"
#include "box2d-object.h"
extern "C"
{
struct Joint;
struct Space;
/////////
/// Forge
//
Joint* b2d_new_hinge_Joint_with_local_anchors
(Space* in_Space,
Object* Object_A,
Object* Object_B,
Vector_3* Anchor_in_A,
Vector_3* Anchor_in_B,
float low_Limit,
float high_Limit,
bool collide_Connected);
Joint* b2d_new_hinge_Joint (Space* in_Space,
Object* Object_A,
Object* Object_B,
Matrix_4x4* Frame_A,
Matrix_4x4* Frame_B,
float low_Limit,
float high_Limit,
bool collide_Connected);
void b2d_free_hinge_Joint (Joint* Self);
Joint* b2d_new_space_hinge_Joint (Object* Object_A,
Matrix_4x4* Frame_A);
Joint* b2d_new_DoF6_Joint (Object* Object_A,
Object* Object_B,
Matrix_4x4* Frame_A,
Matrix_4x4* Frame_B);
Joint* b2d_new_cone_twist_Joint (Object* Object_A,
Object* Object_B,
Matrix_4x4* Frame_A,
Matrix_4x4* Frame_B);
Joint* b2d_new_slider_Joint (Object* Object_A,
Object* Object_B,
Matrix_4x4* Frame_A,
Matrix_4x4* Frame_B);
Joint* b2d_new_ball_Joint (Object* Object_A,
Object* Object_B,
Vector_3* Pivot_in_A,
Vector_3* Pivot_in_B);
//////////////
/// Attributes
//
void* b2d_Joint_user_Data (Joint* Self);
void b2d_Joint_user_Data_is (Joint* Self, void* Now);
Object* b2d_Joint_Object_A (Joint* Self);
Object* b2d_Joint_Object_B (Joint* Self);
Matrix_4x4 b2d_Joint_Frame_A (Joint* Self);
Matrix_4x4 b2d_Joint_Frame_B (Joint* Self);
void b2d_Joint_Frame_A_is (Joint* Self, Matrix_4x4* Now);
void b2d_Joint_Frame_B_is (Joint* Self, Matrix_4x4* Now);
void b2d_Joint_set_local_Anchor (Joint* Self, bool is_Anchor_A,
Vector_3* local_Anchor);
bool b2d_Joint_is_Limited (Joint* Self, int DoF);
bool b2d_Joint_Extent (Joint* Self, int DoF);
void b2d_Joint_Velocity_is (Joint* Self, int DoF,
Real Now);
Vector_3 b2d_Joint_reaction_Force (Joint* Self);
Real b2d_Joint_reaction_Torque (Joint* Self);
/// Hinge
//
void b2d_Joint_hinge_Limits_are (Joint* Self, Real Low,
Real High);
} // extern "C"
#endif

View File

@@ -0,0 +1,23 @@
#ifndef C_BOX2D_OBJECT_PRIVATE_H
#define C_BOX2D_OBJECT_PRIVATE_H
#include <box2d/box2d.h>
extern "C"
{
struct Object
{
b2FixtureDef fixtureDef;
b2BodyDef bodyDef;
b2Body* body;
b2Vec2 Scale;
void* userData; // This holds the physics Object pointer (not the box2d Object pointer).
};
} //extern "C"
#endif

View File

@@ -0,0 +1,413 @@
#include "box2d-object.h"
#include "box2d-object-private.h"
#include <box2d/box2d.h>
#include <cmath>
#include <stdio.h>
extern "C" {
struct Object*
b2d_new_Object (Vector_2* Site,
Real Mass,
Real Friction,
Real Restitution,
Shape* the_Shape)
{
Object* Self = new Object;
b2Shape* b2_Shape = (b2Shape*) (the_Shape);
if (Mass > 0.0)
Self->bodyDef.type = b2_dynamicBody;
Self->body = 0;
Self->bodyDef.position.Set (Site->x,
Site->y);
Self->fixtureDef.shape = b2_Shape;
Self->fixtureDef.density = Mass;
Self->fixtureDef.friction = Friction;
Self->fixtureDef.restitution = Restitution;
Self->Scale = b2Vec2 (1.0, 1.0);
return Self;
}
void
b2d_free_Object (Object* Self)
{
delete (Self);
}
void
b2d_Object_Scale_is (Object* Self,
Vector_2* Now)
{
b2Vec2 old_Scale = Self->Scale;
Self->Scale = b2Vec2 (Now->x, Now->y);
// Shape
//
b2Shape* the_Shape = (b2Shape*) Self->fixtureDef.shape;
if (the_Shape->GetType() == b2Shape::e_circle)
{
the_Shape->m_radius = Now->x / 2.0;
}
else if (the_Shape->GetType() == b2Shape::e_polygon)
{
b2PolygonShape* the_Polygon = (b2PolygonShape*) the_Shape;
for (int i = 0; i < the_Polygon->m_count; i++)
{
the_Polygon->m_vertices [i].x = the_Polygon->m_vertices [i].x / old_Scale.x * Self->Scale.x;
the_Polygon->m_vertices [i].y = the_Polygon->m_vertices [i].y / old_Scale.x * Self->Scale.y;
}
the_Polygon->Set (the_Polygon->m_vertices,
the_Polygon->m_count);
}
// Body
//
if (Self->body)
{
Self->body->DestroyFixture (Self->body->GetFixtureList());
Self->body->CreateFixture (&Self->fixtureDef);
}
}
Shape*
b2d_Object_Shape (Object* Self)
{
return (Shape*) Self->fixtureDef.shape;
}
void*
b2d_Object_user_Data (Object* Self)
{
return Self->userData;
}
void b2d_Object_user_Data_is (Object* Self,
void* Now)
{
Self->userData = Now;
}
Real
b2d_Object_Mass (Object* Self)
{
if (Self->body)
return Self->body->GetMass();
return Self->fixtureDef.density;
}
void
b2d_Object_Friction_is (Object* Self,
Real Now)
{
Self->fixtureDef.friction = Now;
}
void
b2d_Object_Restitution_is (Object* Self,
Real Now)
{
Self->fixtureDef.restitution = Now;
}
Vector_3
b2d_Object_Site (Object* Self)
{
Vector_3 the_Site;
if (Self->body)
{
b2Vec2 Pos = Self->body->GetPosition();
the_Site.x = Pos.x;
the_Site.y = Pos.y;
}
else
{
the_Site.x = Self->bodyDef.position (0);
the_Site.y = Self->bodyDef.position (1);
}
the_Site.z = 0.0;
return the_Site;
}
void
b2d_Object_Site_is (Object* Self,
Vector_3* Now)
{
if (Self->body)
{
b2Vec2 the_Site;
the_Site.x = Now->x;
the_Site.y = Now->y;
Self->body->SetTransform (the_Site,
Self->body->GetAngle());
}
else
{
Self->bodyDef.position.Set (Now->x, Now->y);
}
}
Matrix_3x3
b2d_Object_Spin (Object* Self)
{
b2Vec2 x_Axis;
b2Vec2 y_Axis;
b2Rot b2_Rotation;
if (Self->body)
{
b2Transform b2_Transform = Self->body->GetTransform();
b2_Rotation = b2_Transform.q;
}
else
{
b2_Rotation = b2Rot (Self->bodyDef.angle);
}
x_Axis = b2_Rotation.GetXAxis();
y_Axis = b2_Rotation.GetYAxis();
return Matrix_3x3 (x_Axis (0), x_Axis (1), 0.0,
y_Axis (0), y_Axis (1), 0.0,
0.0, 0.0, 1.0);
}
void
b2d_Object_Spin_is (Object* Self,
Matrix_3x3* Now)
{
b2Vec2 Pos = b2Vec2 (Now->m20, Now->m21);
float Angle = atan2 (Now->m10, Now->m00);
if (Self->body)
{
Self->body->SetTransform (Pos, Angle);
}
else
{
Self->bodyDef.position = Pos;
Self->bodyDef.angle = Angle;
}
}
Real
b2d_Object_xy_Spin (Object* Self)
{
b2Vec2 x_Axis;
b2Vec2 y_Axis;
b2Rot b2_Rotation;
if (Self->body)
{
return Self->body->GetAngle();
}
else
{
return Self->bodyDef.angle;
}
}
void b2d_Object_xy_Spin_is (Object* Self,
Real Now)
{
if (Self->body)
{
Self->body->SetTransform (Self->body->GetPosition(),
Now);
}
else
{
Self->bodyDef.angle = Now;
}
}
Matrix_4x4
b2d_Object_Transform (Object* Self)
{
b2Transform T;
Matrix_4x4 M;
if (Self->body)
{
T = Self->body->GetTransform();
}
else
{
T = b2Transform (Self->bodyDef.position,
b2Rot (Self->bodyDef.angle));
}
b2Vec2 x_Axis = T.q.GetXAxis();
b2Vec2 y_Axis = T.q.GetYAxis();
M.m00 = x_Axis (0); M.m01 = x_Axis (1); M.m02 = 0.0; M.m03 = 0.0;
M.m10 = y_Axis (0); M.m11 = y_Axis (1); M.m12 = 0.0; M.m13 = 0.0;
M.m20 = 0.0; M.m21 = 0.0; M.m22 = 1.0; M.m23 = 0.0;
M.m30 = T.p (0); M.m31 = T.p (1); M.m32 = 0.0; M.m33 = 1.0;
return M;
}
void
b2d_Object_Transform_is (Object* Self,
Matrix_4x4* Now)
{
b2Vec2 Pos = b2Vec2 (Now->m30, Now->m31);
float Angle = atan2 (Now->m10, Now->m00);
if (Self->body)
{
Self->body->SetTransform (Pos, Angle);
}
else
{
Self->bodyDef.position = Pos;
Self->bodyDef.angle = Angle;
}
}
Vector_3
b2d_Object_Speed (Object* Self)
{
Vector_3 the_Speed;
if (Self->body)
{
b2Vec2 b2d_Speed = Self->body->GetLinearVelocity();
the_Speed.x = b2d_Speed.x;
the_Speed.y = b2d_Speed.y;
the_Speed.z = 0.0;
}
else
{
the_Speed.x = 0.0;
the_Speed.y = 0.0;
the_Speed.z = 0.0;
}
return the_Speed;
}
void
b2d_Object_Speed_is (Object* Self,
Vector_3* Now)
{
if (Self->body)
{
Self->body->SetLinearVelocity (b2Vec2 (Now->x, Now->y));
}
}
Vector_3
b2d_Object_Gyre (Object* Self)
{
Vector_3 the_Gyre; // TODO
printf ("TODO: b2d_Object_Gyre");
return the_Gyre;
}
void
b2d_Object_Gyre_is (Object* Self,
Vector_3* Now)
{
printf ("TODO: b2d_Object_Gyre_is");
}
void
b2d_Object_apply_Torque (Object* Self,
Vector_3* Torque)
{
printf ("TODO: b2d_Object_apply_Torque");
}
void
b2d_Object_apply_Torque_impulse (Object* Self,
Vector_3* Torque)
{
printf ("TODO: b2d_Object_apply_Torque_impulse");
}
void
b2d_Object_apply_Force (Object* Self,
Vector_3* Force)
{
Self->body->ApplyForceToCenter (b2Vec2 (Force->x, Force->y), 1);
}
void
b2d_dump (Object* Self)
{
Self->body->Dump();
}
} // end extern "C"

View File

@@ -0,0 +1,63 @@
#ifndef C_BOX2D_OBJECT_H
#define C_BOX2D_OBJECT_H
#include "box2d.h"
#include "box2d-shape.h"
extern "C"
{
struct Object;
struct Object* b2d_new_Object (Vector_2* Site,
Real Mass,
Real Friction,
Real Restitution,
Shape* the_Shape);
void b2d_free_Object (Object* Self);
void b2d_Object_Scale_is (Object* Self, Vector_2* Now);
Shape* b2d_Object_Shape (Object* Self);
void* b2d_Object_user_Data (Object* Self);
void b2d_Object_user_Data_is (Object* Self, void* Now);
Real b2d_Object_Mass (Object* Self);
void b2d_Object_Friction_is (Object* Self, Real Now);
void b2d_Object_Restitution_is (Object* Self, Real Now);
Vector_3 b2d_Object_Site (Object* Self);
void b2d_Object_Site_is (Object* Self, Vector_3* Now);
Matrix_3x3 b2d_Object_Spin (Object* Self);
void b2d_Object_Spin_is (Object* Self, Matrix_3x3* Now);
Real b2d_Object_xy_Spin (Object* Self);
void b2d_Object_xy_Spin_is (Object* Self, Real Now);
Matrix_4x4 b2d_Object_Transform (Object* Self);
void b2d_Object_Transform_is (Object* Self, Matrix_4x4* Now);
Vector_3 b2d_Object_Speed (Object* Self);
void b2d_Object_Speed_is (Object* Self, Vector_3* Now);
Vector_3 b2d_Object_Gyre (Object* Self);
void b2d_Object_Gyre_is (Object* Self, Vector_3* Now);
void b2d_Object_apply_Force (Object* Self, Vector_3* Force);
void b2d_Object_apply_Torque (Object* Self, Vector_3* Torque);
void b2d_Object_apply_Torque_impulse (Object* Self, Vector_3* Torque);
void b2d_dump (Object* Self);
} // extern "C"
#endif

View File

@@ -0,0 +1,186 @@
#include "box2d-shape.h"
#include "box2d-space.h"
#include <box2d/box2d.h>
extern "C"
{
/////////
// Forge
//
void
b2d_free_Shape (Shape* Self)
{
b2Shape* the_Shape = (b2Shape*) Self;
delete (the_Shape);
}
Shape*
b2d_new_Circle (Real Radius)
{
b2CircleShape* Self = new b2CircleShape();
Self->m_radius = Radius;
return (Shape*) Self;
}
Shape*
b2d_new_Polygon (Vector_2 Vertices[],
int vertex_Count)
{
b2PolygonShape* Self = new b2PolygonShape();
b2Vec2 Verts [vertex_Count];
for (int i = 0; i < vertex_Count; i++)
{
Verts [i] = b2Vec2 (Vertices [i].x,
Vertices [i].y);
}
// Self->Set (Verts, vertex_Count);
Self->SetAsBox (Verts [2].x, Verts [2].y);
return (Shape*) Self;
}
Shape*
b2d_new_Box (Vector_3* half_Extents)
{
return 0;
}
Shape*
b2d_new_Capsule (Vector_2* Radii,
Real Height)
{
return 0;
}
Shape*
b2d_new_Cone (Real Radius,
Real Height)
{
return 0;
}
Shape*
b2d_new_convex_Hull (Vector_3 Points[],
int point_Count)
{
return 0;
}
Shape*
b2d_new_Cylinder (Vector_3* half_Extents)
{
return 0;
}
Shape*
b2d_new_Heightfield (int Width,
int Depth,
Real Heights[],
Real min_Height,
Real max_Height,
Vector_3* Scale)
{
return 0;
}
Shape*
b2d_new_multiSphere (Vector_3* Positions,
Real* Radii,
int sphere_Count)
{
return 0;
}
Shape*
b2d_new_Plane (Vector_3* Normal,
Real Offset)
{
return 0;
}
Shape*
b2d_new_Sphere (Real Radius)
{
Shape* Self = 0;
return Self;
}
//////////////
// Attributes
//
void
b2d_shape_Scale_is (Shape* Self, Vector_2 Now)
{
return;
b2Shape* the_Shape = (b2Shape*) Self;
if (the_Shape->GetType() == b2Shape::e_circle)
{
the_Shape->m_radius = Now.x / 2.0;
}
else if (the_Shape->GetType() == b2Shape::e_polygon)
{
// todo
}
}
void*
b2d_Shape_user_Data (Shape* Self)
{
return 0;
}
void
b2d_Shape_user_Data_is (Shape* Self, void* Now)
{
// todo
}
} // extern "C"

View File

@@ -0,0 +1,54 @@
#ifndef C_BOX2D_SHAPE_H
#define C_BOX2D_SHAPE_H
#include "box2d.h"
extern "C"
{
struct Shape;
Shape* b2d_new_Circle (Real Radius);
Shape* b2d_new_Polygon (Vector_2 Vertices[],
int vertex_Count);
Shape* b2d_new_Box (Vector_3* half_Extents);
Shape* b2d_new_Capsule (Vector_2* Radii,
Real Height);
Shape* b2d_new_Cone (Real Radius,
Real Height);
Shape* b2d_new_convex_Hull (Vector_3 Points[],
int point_Count);
Shape* b2d_new_Cylinder (Vector_3* half_Extents);
Shape* b2d_new_Heightfield (int Width,
int Depth,
Real* Heights,
Real min_Height,
Real max_Height,
Vector_3* Scale);
Shape* b2d_new_multiSphere (Vector_3 Positions[],
Real* Radii,
int sphere_Count);
Shape* b2d_new_Plane (Vector_3* Normal,
Real Offset);
Shape* b2d_new_Sphere (Real Radius);
void b2d_free_Shape (Shape* Self);
void* b2d_Shape_user_Data (Shape* Self);
void b2d_Shape_user_Data_is (Shape* Self, void* Now);
void b2d_shape_Scale_is (Shape* Self, Vector_2 Now);
} // extern "C"
#endif

View File

@@ -0,0 +1,378 @@
#include "box2d-space.h"
#include "box2d-conversions.h"
#include <box2d/box2d.h>
#include "box2d-object-private.h"
#include <stdio.h>
///////////////
/// Conversions
//
b2World*
to_World (Space* From)
{
return (b2World*) From;
}
Space*
to_Space (b2World* From)
{
return (Space*) From;
}
///////////////
/// C++ Support
//
/// Raycasts
//
class my_raycast_Callback : public b2RayCastCallback
{
public:
b2Fixture* Nearest;
float
ReportFixture
(b2Fixture* fixture,
const b2Vec2& point,
const b2Vec2& normal,
float fraction)
{
Nearest = fixture;
return fraction;
}
};
/// Collisions
//
const int32 k_maxContactPoints = 4 * 2048;
struct ContactPoint
{
b2Fixture* fixtureA;
b2Fixture* fixtureB;
b2Vec2 normal;
b2Vec2 position;
b2PointState state;
float normalImpulse;
float tangentImpulse;
float separation;
};
class contact_Listener : public b2ContactListener
{
public:
contact_Listener();
virtual ~contact_Listener();
virtual void BeginContact (b2Contact* contact) { B2_NOT_USED(contact); }
virtual void EndContact (b2Contact* contact) { B2_NOT_USED(contact); }
virtual void PreSolve (b2Contact* contact, const b2Manifold* oldManifold);
virtual void PostSolve (b2Contact* contact, const b2ContactImpulse* impulse)
{
B2_NOT_USED(contact);
B2_NOT_USED(impulse);
}
ContactPoint m_points[k_maxContactPoints];
int32 m_pointCount;
};
contact_Listener::
contact_Listener()
{
m_pointCount = 0;
}
contact_Listener::
~contact_Listener()
{
}
void
contact_Listener::
PreSolve (b2Contact* contact,
const b2Manifold* oldManifold)
{
if (m_pointCount == k_maxContactPoints)
return;
const b2Manifold* manifold = contact->GetManifold();
if (manifold->pointCount == 0)
return;
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
b2PointState state1 [b2_maxManifoldPoints],
state2 [b2_maxManifoldPoints];
b2GetPointStates (state1, state2,
oldManifold, manifold);
b2WorldManifold worldManifold;
contact->GetWorldManifold (&worldManifold);
ContactPoint* cp = m_points + m_pointCount;
cp->fixtureA = fixtureA;
cp->fixtureB = fixtureB;
cp->position.SetZero();
for (int32 i = 0; i < manifold->pointCount; ++i)
{
cp->position += worldManifold.points [i];
cp->normal = worldManifold.normal;
cp->state = state2 [i];
cp->normalImpulse = manifold->points [i].normalImpulse;
cp->tangentImpulse = manifold->points [i].tangentImpulse;
cp->separation = worldManifold.separations [i];
}
if (manifold->pointCount > 1)
cp->position *= (1.0 / float (manifold->pointCount)); // Calculate middle site.
++m_pointCount;
}
///////////////
/// C Interface
//
extern "C"
{
int
b2d_space_contact_Count (Space* Self)
{
b2World* the_World = to_World (Self);
contact_Listener* the_contact_Listener = dynamic_cast <contact_Listener*> (the_World->GetContactManager().m_contactListener);
return the_contact_Listener->m_pointCount;
}
b2d_Contact
b2d_space_Contact (Space* Self, int contact_Id)
{
b2World* the_World = to_World (Self);
contact_Listener* the_contact_Listener = dynamic_cast <contact_Listener*> (the_World->GetContactManager().m_contactListener);
ContactPoint* point = the_contact_Listener->m_points + contact_Id;
b2Body* body1 = point->fixtureA->GetBody();
b2Body* body2 = point->fixtureB->GetBody();
b2d_Contact the_Contact;
the_Contact.Object_A = (Object*) (body1->GetUserData().pointer);
the_Contact.Object_B = (Object*) (body2->GetUserData().pointer);
the_Contact.Site.x = point->position.x;
the_Contact.Site.y = point->position.y;
the_Contact.Site.z = 0.0;
return the_Contact;
}
struct Space*
b2d_new_Space ()
{
b2World* Self = new b2World (b2Vec2 (0.0, -9.8));
Self->SetContactListener (new contact_Listener());
return to_Space (Self);
}
void
b2d_free_Space (struct Space* Self)
{
b2World* the_World = to_World (Self);
delete the_World->GetContactManager().m_contactListener;
delete the_World;
}
void
b2d_Space_Gravity_is (Space* Self, Vector_3* Now)
{
b2World* the_World = to_World (Self);
the_World->SetGravity (b2Vec2 (Now->x, Now->y));
}
void
b2d_Space_evolve (Space* Self, float By)
{
b2World* the_World = to_World (Self);
contact_Listener* the_contact_Listener = dynamic_cast <contact_Listener*> (the_World->GetContactManager().m_contactListener);
the_contact_Listener->m_pointCount = 0;
the_World->Step (By, 6, 2);
}
void
b2d_Space_add_Object (Space* Self, Object* the_Object)
{
b2World* the_World = (b2World*)Self;
the_Object->body = the_World->CreateBody (&the_Object->bodyDef);
// the_Object->body->SetUserData (the_Object);
the_Object->body->CreateFixture (&the_Object->fixtureDef);
}
void
b2d_Space_rid_Object (Space* Self, Object* the_Object)
{
((b2World*)Self)->DestroyBody (the_Object->body);
the_Object->body = 0;
}
void
b2d_Space_add_Joint (Space* Self, Joint* the_Joint)
{
b2World* the_World = (b2World*) Self;
b2JointDef* jointDef = (b2JointDef*) the_Joint;
Object* Object_A = (Object*) jointDef->bodyA;
Object* Object_B = (Object*) jointDef->bodyB;
jointDef->bodyA = Object_A->body;
jointDef->bodyB = Object_B->body;
if (jointDef->type == e_revoluteJoint)
{
b2RevoluteJointDef* revolute_Def = static_cast <b2RevoluteJointDef*> (jointDef);
b2RevoluteJoint* the_Joint;
the_Joint = (b2RevoluteJoint*) the_World->CreateJoint (revolute_Def);
jointDef->userData.pointer = (uintptr_t) dynamic_cast <b2Joint*> (the_Joint);
}
else
{
printf ("TODO: b2d_Space_add_Joint");
}
}
void
b2d_Space_rid_Joint (Space* Self, Joint* the_Joint)
{
b2World* the_World = (b2World*) Self;
b2JointDef* the_Joint_Def = (b2JointDef*) the_Joint;
b2Joint* b2d_Joint = (b2Joint*) the_Joint_Def->userData.pointer;
Object* Object_A = (Object*) the_Joint_Def->bodyA->GetUserData().pointer;
Object* Object_B = (Object*) the_Joint_Def->bodyB->GetUserData().pointer;
the_World->DestroyJoint (b2d_Joint);
the_Joint_Def->bodyA = (b2Body*) Object_A;
the_Joint_Def->bodyB = (b2Body*) Object_B;
}
void*
b2d_b2Joint_user_Data (b2Joint* the_Joint)
{
return (void*) the_Joint->GetUserData().pointer;
}
/// Joint Cursor
//
joint_Cursor
b2d_Space_first_Joint (Space* Self)
{
b2World* the_World = (b2World*) Self;
return {the_World->GetJointList()};
}
void
b2d_Space_next_Joint (joint_Cursor* Cursor)
{
Cursor->Joint = Cursor->Joint->GetNext();
}
b2Joint*
b2d_Space_joint_Element (joint_Cursor* Cursor)
{
return Cursor->Joint;
}
/// Raycasts
//
b2d_ray_Collision
b2d_Space_cast_Ray (Space* Self, Vector_3* From,
Vector_3* To)
{
b2World* the_World = (b2World*) Self;
my_raycast_Callback the_Callback;
the_Callback.Nearest = 0;
the_World->RayCast (&the_Callback,
b2Vec2 (From->x, From->y),
b2Vec2 (To ->x, To ->y));
b2d_ray_Collision the_Collision;
if (the_Callback.Nearest == 0)
the_Collision.near_Object = 0;
else
the_Collision.near_Object = (Object*) (the_Callback.Nearest->GetBody()->GetUserData().pointer);
the_Collision.hit_Fraction = 0.0;
the_Collision.Normal_world = Vector_3 (0.0, 0.0, 0.0);
the_Collision.Site_world = Vector_3 (0.0, 0.0, 0.0);
return the_Collision;
}
} // extern "C"

View File

@@ -0,0 +1,75 @@
#ifndef C_BOX2D_SPACE_H
#define C_BOX2D_SPACE_H
#include "box2d.h"
#include "box2d-object.h"
#include "box2d-joint.h"
extern "C"
{
struct Space;
struct Space* b2d_new_Space ();
void b2d_free_Space (Space* Self);
void b2d_Space_add_Object (Space* Self, Object* the_Object);
void b2d_Space_rid_Object (Space* Self, Object* the_Object);
void b2d_Space_add_Joint (Space* Self, Joint* the_Joint);
void b2d_Space_rid_Joint (Space* Self, Joint* the_Joint);
struct b2Joint;
void* b2d_b2Joint_user_Data (b2Joint* the_Joint);
struct joint_Cursor
{
b2Joint* Joint;
};
joint_Cursor b2d_Space_first_Joint (Space* Self);
void b2d_Space_next_Joint (joint_Cursor* Cursor);
b2Joint* b2d_Space_joint_Element (joint_Cursor* Cursor);
void b2d_Space_Gravity_is (Space* Self, Vector_3* Now);
void b2d_Space_evolve (Space* Self, float By);
// Ray Casting
//
struct b2d_ray_Collision
{
const Object* near_Object;
Real hit_Fraction;
Vector_3 Normal_world;
Vector_3 Site_world;
};
b2d_ray_Collision b2d_Space_cast_Ray (Space* Self, Vector_3* From,
Vector_3* To);
// Collisions
//
struct b2d_Contact
{
Object* Object_A;
Object* Object_B;
Vector_3 Site;
};
int b2d_space_contact_Count (Space* Self);
b2d_Contact b2d_space_Contact (Space* Self, int contact_Id);
} // extern "C"
#endif

View File

@@ -0,0 +1,8 @@
#ifndef C_BOX2D_H
#define C_BOX2D_H
#include "c_math.h"
// Provides a simple C interface to the Box2D C++ library.
#endif