Implemented getting/setting collision shape values and separated collision shapes from rigidbodies

dev
Shariq Shah 8 years ago
parent 0547958961
commit 0af53d7456
  1. 5
      README.md
  2. 29
      src/common/common.h
  3. 24
      src/game/main.c
  4. 189
      src/game/physics.c
  5. 30
      src/game/physics.h
  6. 7
      src/libsymmetry/game.c

@ -156,6 +156,8 @@
- ## TODO - ## TODO
- Update physics if entity position/rotation/scale etc are changed - Update physics if entity position/rotation/scale etc are changed
- Physics raycasting
- Physics forces/torque etc
- Fix lights type not being correctly saved/loaded from file - Fix lights type not being correctly saved/loaded from file
- Physics Trimesh support - Physics Trimesh support
- Debug physics mesh drawing - Debug physics mesh drawing
@ -358,3 +360,6 @@
* Got rid of pkg-confg and system-installed SDL2 dependancy on linux and instead put custom compiled SDL libs in libs folder similar to how we're handling it in windows * Got rid of pkg-confg and system-installed SDL2 dependancy on linux and instead put custom compiled SDL libs in libs folder similar to how we're handling it in windows
* Proper physics time-step and speed * Proper physics time-step and speed
* Proper handling of rigidbody associated with an entity and notifying it of movement or collision * Proper handling of rigidbody associated with an entity and notifying it of movement or collision
* Added physics spheres and other primitive shapes
* Separated collision shape and rigidbody
* Implemented Getting/Modifying primitive physics shapes' values like length, radius etc

@ -19,6 +19,7 @@ struct Sound_Source_Buffer;
//Physics Decls //Physics Decls
typedef void* Rigidbody; typedef void* Rigidbody;
typedef void* Collision_Shape;
typedef void (*RigidbodyMoveCB)(Rigidbody); typedef void (*RigidbodyMoveCB)(Rigidbody);
typedef void (*RigidbodyColCB)(Rigidbody, Rigidbody); typedef void (*RigidbodyColCB)(Rigidbody, Rigidbody);
@ -59,12 +60,35 @@ struct Physics_Api
void (*step)(float); void (*step)(float);
void (*gravity_set)(float x, float y, float z); void (*gravity_set)(float x, float y, float z);
void (*gravity_get)(float* x, float* y, float* z); void (*gravity_get)(float* x, float* y, float* z);
void (*cs_remove)(Collision_Shape shape);
Collision_Shape (*cs_plane_create)(float a, float b, float c, float d);
void (*cs_plane_params_set)(Collision_Shape shape, float a, float b, float c, float d);
void (*cs_plane_params_get)(Collision_Shape shape, float* a, float* b, float* c, float* d);
Collision_Shape (*cs_box_create)(float x, float y, float z);
void (*cs_box_params_set)(Collision_Shape shape, float x, float y, float z);
void (*cs_box_params_get)(Collision_Shape shape, float* x, float* y, float* z);
Collision_Shape (*cs_sphere_create)(float radius);
void (*cs_shpere_radius_set)(Collision_Shape shape, float radius);
float (*cs_sphere_radius_get)(Collision_Shape shape);
Collision_Shape (*cs_capsule_create)(float radius, float length);
void (*cs_capsule_params_set)(Collision_Shape shape, float radius, float length);
void (*cs_capsule_params_get)(Collision_Shape shape, float* radius, float* length);
void (*body_remove)(Rigidbody body);
Rigidbody (*body_box_create)(float length, float width, float height);
Rigidbody (*body_sphere_create)(float radius);
Rigidbody (*body_capsule_create)(float radius, float height);
Collision_Shape (*body_cs_get)(Rigidbody body);
void (*body_cs_set)(Rigidbody body, Collision_Shape shape);
void (*body_position_set)(Rigidbody body, float x, float y, float z); void (*body_position_set)(Rigidbody body, float x, float y, float z);
void (*body_position_get)(Rigidbody body, float* x, float* y, float* z); void (*body_position_get)(Rigidbody body, float* x, float* y, float* z);
void (*body_rotation_set)(Rigidbody body, float x, float y, float z, float w); void (*body_rotation_set)(Rigidbody body, float x, float y, float z, float w);
void (*body_rotation_get)(Rigidbody body, float* x, float* y, float* z, float* w); void (*body_rotation_get)(Rigidbody body, float* x, float* y, float* z, float* w);
Rigidbody (*plane_create)(float a, float b, float c, float d);
Rigidbody (*box_create)(float length, float width, float height);
void (*body_set_moved_callback)(RigidbodyMoveCB callback); void (*body_set_moved_callback)(RigidbodyMoveCB callback);
void (*body_set_collision_callback)(RigidbodyColCB callback); void (*body_set_collision_callback)(RigidbodyColCB callback);
void (*body_kinematic_set)(Rigidbody body); void (*body_kinematic_set)(Rigidbody body);
@ -72,6 +96,7 @@ struct Physics_Api
float (*body_mass_get)(Rigidbody body); float (*body_mass_get)(Rigidbody body);
void* (*body_data_get)(Rigidbody body); void* (*body_data_get)(Rigidbody body);
void (*body_data_set)(Rigidbody body, void* data); void (*body_data_set)(Rigidbody body, void* data);
void (*body_force_add)(Rigidbody body, float fx, float fy, float fz);
}; };
struct Sound_Api struct Sound_Api

@ -127,6 +127,7 @@ int main(int argc, char** args)
.step = &physics_step, .step = &physics_step,
.gravity_set = &physics_gravity_set, .gravity_set = &physics_gravity_set,
.gravity_get = &physics_gravity_get, .gravity_get = &physics_gravity_get,
.body_position_set = &physics_body_position_set, .body_position_set = &physics_body_position_set,
.body_position_get = &physics_body_position_get, .body_position_get = &physics_body_position_get,
.body_rotation_set = &physics_body_rotation_set, .body_rotation_set = &physics_body_rotation_set,
@ -138,8 +139,27 @@ int main(int argc, char** args)
.body_data_get = &physics_body_data_get, .body_data_get = &physics_body_data_get,
.body_set_moved_callback = &physics_body_set_moved_callback, .body_set_moved_callback = &physics_body_set_moved_callback,
.body_set_collision_callback = &physics_body_set_collision_callback, .body_set_collision_callback = &physics_body_set_collision_callback,
.plane_create = &physics_plane_create, .body_force_add = &physics_body_force_add,
.box_create = &physics_box_create .body_box_create = &physics_body_box_create,
.body_sphere_create = &physics_body_sphere_create,
.body_capsule_create = &physics_body_capsule_create,
.body_remove = &physics_body_remove,
.body_cs_set = &physics_body_cs_set,
.body_cs_get = &physics_body_cs_get,
.cs_box_create = &physics_cs_box_create,
.cs_plane_create = &physics_cs_plane_create,
.cs_sphere_create = &physics_cs_sphere_create,
.cs_capsule_create = &physics_cs_capsule_create,
.cs_remove = &physics_cs_remove,
.cs_plane_params_get = &physics_cs_plane_params_get,
.cs_capsule_params_get = &physics_cs_capsule_params_get,
.cs_box_params_get = &physics_cs_box_params_get,
.cs_sphere_radius_get = &physics_cs_sphere_radius_get,
.cs_plane_params_set = &physics_cs_plane_params_set,
.cs_capsule_params_set = &physics_cs_capsule_params_set,
.cs_box_params_set = &physics_cs_box_params_set,
.cs_shpere_radius_set = &physics_cs_sphere_radius_set
} }
}; };

@ -182,28 +182,184 @@ void physics_near_callback(void* data, dGeomID o1, dGeomID o2)
} }
} }
Collision_Shape physics_body_cs_get(Rigidbody body)
{
return dBodyGetFirstGeom(body);
}
void physics_body_cs_set(Rigidbody body, Collision_Shape shape)
{
dGeomSetBody(shape, body);
}
Rigidbody physics_plane_create(float a, float b, float c, float d) Collision_Shape physics_cs_plane_create(float a, float b, float c, float d)
{ {
dGeomID plane = dCreatePlane(Physics.space, a, b, c, d); dGeomID plane = dCreatePlane(Physics.space, a, b, c, d);
/*dBodyID body = dBodyCreate(Physics.world);
dGeomSetBody(plane, body);*/
return plane; return plane;
} }
Rigidbody physics_box_create(float length, float width, float height) void physics_cs_plane_params_set(Collision_Shape shape, float a, float b, float c, float d)
{
dGeomPlaneSetParams(shape, a, b, c, d);
}
void physics_cs_plane_params_get(Collision_Shape shape, float* a, float* b, float* c, float* d)
{
assert(a && b && c && d);
*a = *b = *c = *d = 0.f;
float result[4] = { 0.f };
dGeomPlaneGetParams(shape, result);
*a = result[0];
*b = result[1];
*c = result[2];
*d = result[3];
}
Collision_Shape physics_cs_box_create(float x, float y, float z)
{
dGeomID box = dCreateBox(Physics.space, x, y, z);
if(!box)
{
log_error("physics:cs_box_create", "Failed to create box collision shape");
}
return box;
}
void physics_cs_box_params_get(Collision_Shape shape, float* x, float* y, float* z)
{
assert(x && y && z);
*x = *y = *z = 0.f;
float lengths[3] = { 0.f };
dGeomBoxGetLengths(shape, lengths);
*x = lengths[0];
*y = lengths[1];
*z = lengths[2];
}
void physics_cs_box_params_set(Collision_Shape shape, float x, float y, float z)
{
dGeomBoxSetLengths(shape, x, y, z);
}
Collision_Shape physics_cs_sphere_create(float radius)
{
dGeomID sphere = dCreateSphere(Physics.space, radius);
if(!sphere)
{
log_error("physics:cs_sphere_create", "Failed to create sphere collision shape");
}
return sphere;
}
float physics_cs_sphere_radius_get(Collision_Shape shape)
{
return dGeomSphereGetRadius(shape);
}
void physics_cs_sphere_radius_set(Collision_Shape shape, float radius)
{
dGeomSphereSetRadius(shape, radius);
}
Collision_Shape physics_cs_capsule_create(float radius, float length)
{ {
dGeomID box = dCreateBox(Physics.space, length, height, width); dGeomID capsule = dCreateCapsule(Physics.space, radius, length);
dBodyID body = dBodyCreate(Physics.world); if(!capsule)
dGeomSetBody(box, body); {
dBodySetAngularVel(body, 0, 0, 0); log_error("physics:cs_capsule_create", "Failed to create capsule collision shape");
dBodySetLinearVel(body, 0, 0, 0); }
dBodySetTorque(body, 0, 0, 0); return capsule;
}
void physics_cs_capsule_params_get(Collision_Shape shape, float* radius, float* length)
{
assert(radius && length);
*radius = *length = 0.f;
dGeomCapsuleGetParams(shape, radius, length);
}
void physics_cs_capsule_params_set(Collision_Shape shape, float radius, float length)
{
dGeomCapsuleSetParams(shape, radius, length);
}
void physics_box_params_get(Rigidbody body, float* x, float* y, float* z)
{
assert(x && y && z);
*x = *y = *z = 0.f;
dGeomID box = dBodyGetFirstGeom(body);
if(box == 0)
{
log_error("physics:box_get_params", "Body has invalid geometry");
return;
}
float lengths[3] = { 0.f };
dGeomBoxGetLengths(box, lengths);
*x = lengths[0];
*y = lengths[1];
*z = lengths[2];
}
void physics_box_params_set(Rigidbody body, float x, float y, float z)
{
assert(x && y && z);
dGeomID box = dBodyGetFirstGeom(body);
if(box == 0)
{
log_error("physics:box_get_params", "Body has invalid geometry");
return;
}
dGeomBoxSetLengths(box, x, y, z);
}
Rigidbody physics_body_box_create(float x, float y, float z)
{
Rigidbody body = NULL;
Collision_Shape box = physics_cs_box_create(x, y, z);
if(box)
{
body = dBodyCreate(Physics.world);
physics_body_cs_set(body, box);
dBodySetMovedCallback(body, Physics.on_move); dBodySetMovedCallback(body, Physics.on_move);
}
return body; return body;
} }
Rigidbody physics_body_sphere_create(float radius)
{
Rigidbody body = NULL;
Collision_Shape sphere = physics_cs_sphere_create(radius);
if(sphere)
{
body = dBodyCreate(Physics.world);
physics_body_cs_set(body, sphere);
dBodySetMovedCallback(body, Physics.on_move);
}
return body;
}
Rigidbody physics_body_capsule_create(float radius, float length)
{
Rigidbody body = NULL;
Collision_Shape capsule = physics_cs_capsule_create(radius, length);
if(capsule)
{
body = dBodyCreate(Physics.world);
physics_body_cs_set(body, capsule);
dBodySetMovedCallback(body, Physics.on_move);
}
return body;
}
void physics_body_force_add(Rigidbody body, float fx, float fy, float fz)
{
dBodyAddForce(body, fx, fy, fz);
}
void physics_body_set_moved_callback(RigidbodyMoveCB callback) void physics_body_set_moved_callback(RigidbodyMoveCB callback)
{ {
Physics.on_move = callback; Physics.on_move = callback;
@ -240,3 +396,16 @@ void physics_body_kinematic_set(Rigidbody body)
{ {
dBodySetKinematic(body); dBodySetKinematic(body);
} }
void physics_body_remove(Rigidbody body)
{
dGeomID shape = dBodyGetFirstGeom(body);
if(shape)
physics_cs_remove(shape);
dBodyDestroy(body);
}
void physics_cs_remove(Collision_Shape shape)
{
dGeomDestroy(shape);
}

@ -15,8 +15,32 @@ void physics_body_position_set(Rigidbody body, float x, float y, float z);
void physics_body_rotation_get(Rigidbody body, float* x, float* y, float* z, float* w); void physics_body_rotation_get(Rigidbody body, float* x, float* y, float* z, float* w);
void physics_body_rotation_set(Rigidbody body, float x, float y, float z, float w); void physics_body_rotation_set(Rigidbody body, float x, float y, float z, float w);
Rigidbody physics_plane_create(float a, float b, float c, float d); Collision_Shape physics_body_cs_get(Rigidbody body);
Rigidbody physics_box_create(float length, float width, float height); void physics_body_cs_set(Rigidbody body, Collision_Shape shape);
void physics_cs_remove(Collision_Shape shape);
Collision_Shape physics_cs_plane_create(float a, float b, float c, float d);
void physics_cs_plane_params_set(Collision_Shape shape, float a, float b, float c, float d);
void physics_cs_plane_params_get(Collision_Shape shape, float* a, float* b, float* c, float* d);
Collision_Shape physics_cs_box_create(float x, float y, float z);
void physics_cs_box_params_get(Collision_Shape shape, float* x, float* y, float* z);
void physics_cs_box_params_set(Collision_Shape shape, float x, float y, float z);
Collision_Shape physics_cs_sphere_create(float radius);
float physics_cs_sphere_radius_get(Collision_Shape shape);
void physics_cs_sphere_radius_set(Collision_Shape shape, float radius);
Collision_Shape physics_cs_capsule_create(float radius, float height);
void physics_cs_capsule_params_get(Collision_Shape shape, float* radius, float* height);
void physics_cs_capsule_params_set(Collision_Shape shape, float radius, float height);
Rigidbody physics_body_box_create(float x, float y, float z);
Rigidbody physics_body_sphere_create(float radius);
Rigidbody physics_body_capsule_create(float radius, float height);
void physics_body_remove(Rigidbody body);
void physics_body_set_moved_callback(RigidbodyMoveCB callback); void physics_body_set_moved_callback(RigidbodyMoveCB callback);
void physics_body_set_collision_callback(RigidbodyColCB callback); void physics_body_set_collision_callback(RigidbodyColCB callback);
@ -27,6 +51,8 @@ void physics_body_mass_set(Rigidbody body, float mass);
void physics_body_data_set(Rigidbody body, void* data); void physics_body_data_set(Rigidbody body, void* data);
void* physics_body_data_get(Rigidbody body); void* physics_body_data_get(Rigidbody body);
void physics_body_force_add(Rigidbody body, float fx, float fy, float fz);
void physics_body_kinematic_set(Rigidbody body); void physics_body_kinematic_set(Rigidbody body);
#endif #endif

@ -252,14 +252,15 @@ void scene_setup(void)
camera_update_proj(player);*/ camera_update_proj(player);*/
} }
platform->physics.plane_create(0, 1, 0, 0); platform->physics.cs_plane_create(0, 1, 0, 0);
Rigidbody box = platform->physics.box_create(2.5, 2.5, 2.5); Rigidbody box = platform->physics.body_box_create(2.5, 2.5, 2.5);
platform->physics.body_position_set(box, 0.f, 50.f, 0.f); platform->physics.body_position_set(box, 0.f, 50.f, 0.f);
platform->physics.body_mass_set(box, 10.f); platform->physics.body_mass_set(box, 10.f);
platform->physics.body_data_set(box, (void*)suz_id); platform->physics.body_data_set(box, (void*)suz_id);
platform->physics.body_force_add(box, -100.f, 0.f, 0.f);
/*Rigidbody plane = platform->physics.plane_create(0, 1, 0, 0);*/ /*Rigidbody plane = platform->physics.plane_create(0, 1, 0, 0);*/
Rigidbody ground_box = platform->physics.box_create(10, 10, 10); Rigidbody ground_box = platform->physics.body_box_create(10, 10, 10);
platform->physics.body_position_set(ground_box, 0.f, 0.f, 0.f); platform->physics.body_position_set(ground_box, 0.f, 0.f, 0.f);
platform->physics.body_kinematic_set(ground_box); platform->physics.body_kinematic_set(ground_box);
struct Entity* ground = entity_find("Ground"); struct Entity* ground = entity_find("Ground");

Loading…
Cancel
Save