Proper handling of rigidbody associated with an entity and notifying it of movement or collision

dev
Shariq Shah 8 years ago
parent b2874e5786
commit 0547958961
  1. 4
      README.md
  2. 6
      src/common/common.h
  3. 3
      src/game/main.c
  4. 34
      src/game/physics.c
  5. 6
      src/game/physics.h
  6. 31
      src/libsymmetry/entity.c
  7. 3
      src/libsymmetry/entity.h
  8. 30
      src/libsymmetry/game.c

@ -155,7 +155,7 @@
- ## TODO
- Proper physics time-step and speed
- Update physics if entity position/rotation/scale etc are changed
- Fix lights type not being correctly saved/loaded from file
- Physics Trimesh support
- Debug physics mesh drawing
@ -356,3 +356,5 @@
* Implement necessary changes to run Soloud on linux
* Moved third party libs/include directories into root/lib and root/include. Put common includes like header-only libs into root/include/common and others which require platform specific stuff into root/include/linux etc.
* 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 handling of rigidbody associated with an entity and notifying it of movement or collision

@ -20,6 +20,7 @@ struct Sound_Source_Buffer;
//Physics Decls
typedef void* Rigidbody;
typedef void (*RigidbodyMoveCB)(Rigidbody);
typedef void (*RigidbodyColCB)(Rigidbody, Rigidbody);
// Function Pointer decls
typedef void (*Keyboard_Event_Func) (int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt);
@ -64,10 +65,13 @@ struct Physics_Api
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)(Rigidbody body, RigidbodyMoveCB callback);
void (*body_set_moved_callback)(RigidbodyMoveCB callback);
void (*body_set_collision_callback)(RigidbodyColCB callback);
void (*body_kinematic_set)(Rigidbody body);
void (*body_mass_set)(Rigidbody body, float mass);
float (*body_mass_get)(Rigidbody body);
void* (*body_data_get)(Rigidbody body);
void (*body_data_set)(Rigidbody body, void* data);
};
struct Sound_Api

@ -134,7 +134,10 @@ int main(int argc, char** args)
.body_kinematic_set = &physics_body_kinematic_set,
.body_mass_set = &physics_body_mass_set,
.body_mass_get = &physics_body_mass_get,
.body_data_set = &physics_body_data_set,
.body_data_get = &physics_body_data_get,
.body_set_moved_callback = &physics_body_set_moved_callback,
.body_set_collision_callback = &physics_body_set_collision_callback,
.plane_create = &physics_plane_create,
.box_create = &physics_box_create
}

@ -10,6 +10,8 @@ static struct
dSpaceID space;
dJointGroupID contact_group;
double step_size;
RigidbodyColCB on_collision;
RigidbodyMoveCB on_move;
}
Physics;
@ -40,7 +42,6 @@ void physics_init(void)
dWorldSetLinearDamping(Physics.world, 0.00001);
dWorldSetAngularDamping(Physics.world, 0.005);
dWorldSetMaxAngularSpeed(Physics.world, 200);
dWorldSetContactMaxCorrectingVel(Physics.world,0.1);
dWorldSetContactSurfaceLayer(Physics.world,0.001);
}
@ -60,19 +61,11 @@ void physics_cleanup(void)
void physics_step(float delta_time)
{
//if(delta_time <= 0.f) delta_time = Physics.step_size;
//dSpaceCollide(Physics.space, NULL, physics_near_callback);
//dWorldQuickStep(Physics.world, delta_time);
////dWorldStep(Physics.world, Physics.step_size);
//dJointGroupEmpty(Physics.contact_group);
int steps = (int)ceilf(delta_time / Physics.step_size);
//log_message("Num steps : %d", steps);
for(int i = 0; i < steps; i++)
{
dSpaceCollide(Physics.space, NULL, physics_near_callback);
dWorldQuickStep(Physics.world, Physics.step_size);
//dWorldStep(Physics.world, Physics.step_size);
dJointGroupEmpty(Physics.contact_group);
}
}
@ -171,7 +164,7 @@ void physics_near_callback(void* data, dGeomID o1, dGeomID o2)
int n = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(dContact));
if(n > 0)
{
log_message("Collision!");
Physics.on_collision(b1, b2);
for(int i = 0; i < n; i++)
{
//contact[i].surface.slip1 = 0.7;
@ -206,12 +199,19 @@ Rigidbody physics_box_create(float length, float width, float height)
dBodySetAngularVel(body, 0, 0, 0);
dBodySetLinearVel(body, 0, 0, 0);
dBodySetTorque(body, 0, 0, 0);
dBodySetMovedCallback(body, Physics.on_move);
return body;
}
void physics_body_set_moved_callback(Rigidbody body, RigidbodyMoveCB callback)
void physics_body_set_moved_callback(RigidbodyMoveCB callback)
{
Physics.on_move = callback;
}
void physics_body_set_collision_callback(RigidbodyColCB callback)
{
dBodySetMovedCallback(body, callback);
Physics.on_collision = callback;
}
float physics_body_mass_get(Rigidbody body)
@ -226,6 +226,16 @@ void physics_body_mass_set(Rigidbody body, float mass)
dBodySetMass(body, &dmass);*/
}
void physics_body_data_set(Rigidbody body, void * data)
{
dBodySetData(body, data);
}
void * physics_body_data_get(Rigidbody body)
{
return dBodyGetData(body);
}
void physics_body_kinematic_set(Rigidbody body)
{
dBodySetKinematic(body);

@ -18,11 +18,15 @@ void physics_body_rotation_set(Rigidbody body, float x, float y, float z, float
Rigidbody physics_plane_create(float a, float b, float c, float d);
Rigidbody physics_box_create(float length, float width, float height);
void physics_body_set_moved_callback(Rigidbody body, RigidbodyMoveCB callback);
void physics_body_set_moved_callback(RigidbodyMoveCB callback);
void physics_body_set_collision_callback(RigidbodyColCB callback);
float physics_body_mass_get(Rigidbody body);
void physics_body_mass_set(Rigidbody body, float mass);
void physics_body_data_set(Rigidbody body, void* data);
void* physics_body_data_get(Rigidbody body);
void physics_body_kinematic_set(Rigidbody body);
#endif

@ -651,7 +651,36 @@ void entity_apply_sound_params(struct Entity* entity)
}
void entity_on_rigidbody_move(Rigidbody body_A, Rigidbody body_B)
void entity_rigidbody_on_move(Rigidbody body)
{
int id = platform->physics.body_data_get(body);
struct Entity* entity = entity_get(id);
vec3 pos = {0};
quat rot = {0};
platform->physics.body_position_get(body, &pos.x, &pos.y, &pos.z);
platform->physics.body_rotation_get(body, &rot.x, &rot.y, &rot.z, &rot.w);
quat_assign(&entity->transform.rotation, &rot);
transform_set_position(entity, &pos);
}
void entity_rigidbody_on_collision(Rigidbody body_A, Rigidbody body_B)
{
struct Entity* ent_A = NULL;
struct Entity* ent_B = NULL;
if(body_A)
{
int id_A = platform->physics.body_data_get(body_A);
ent_A = entity_get(id_A);
}
if(body_B)
{
int id_B = platform->physics.body_data_get(body_B);
ent_B = entity_get(id_B);
}
if(ent_A && ent_B) log_message("Entity %s collided with Entity %s", ent_A->name, ent_B->name);
}

@ -141,6 +141,7 @@ bool entity_write(struct Entity* entity, struct Parser_Object* object)
struct Entity* entity_read(struct Parser_Object* object);
const char* entity_type_name_get(struct Entity* entity);
void entity_apply_sound_params(struct Entity* entity); // Convenience function to sync the data set in entity's sound_source with the actual sound source's instance
void entity_on_rigidbody_move(Rigidbody body_A, Rigidbody body_B);
void entity_rigidbody_on_move(Rigidbody body);
void entity_rigidbody_on_collision(Rigidbody body_A, Rigidbody body_B);
#endif

@ -103,6 +103,8 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api)
entity_init();
platform->physics.init();
platform->physics.gravity_set(0.f, -9.8f, 0.f);
platform->physics.body_set_moved_callback(entity_rigidbody_on_move);
platform->physics.body_set_collision_callback(entity_rigidbody_on_collision);
scene_init();
/* Debug scene setup */
@ -254,12 +256,15 @@ void scene_setup(void)
Rigidbody box = platform->physics.box_create(2.5, 2.5, 2.5);
platform->physics.body_position_set(box, 0.f, 50.f, 0.f);
platform->physics.body_mass_set(box, 10.f);
platform->physics.body_set_moved_callback(box, on_box_move);
platform->physics.body_data_set(box, (void*)suz_id);
/*Rigidbody plane = platform->physics.plane_create(0, 1, 0, 0);*/
Rigidbody ground_box = platform->physics.box_create(10, 10, 10);
platform->physics.body_position_set(ground_box, 0.f, 0.f, 0.f);
platform->physics.body_kinematic_set(ground_box);
struct Entity* ground = entity_find("Ground");
platform->physics.body_data_set(ground_box, (void*)ground->id);
Rigidbody plane = platform->physics.plane_create(0, 1, 0, 0);
//Rigidbody ground_box = platform->physics.box_create(1000, 1, 1000);
/*platform->physics.body_position_set(ground_box, 0.f, 0.f, 0.f);
platform->physics.body_kinematic_set(ground_box);*/
}
void debug(float dt)
@ -1707,18 +1712,3 @@ struct Game_State* game_state_get(void)
{
return game_state;
}
void on_box_move(Rigidbody body)
{
struct Entity* suz = entity_get(suz_id);
vec3 pos = {0};
quat rot = {0};
platform->physics.body_position_get(body, &pos.x, &pos.y, &pos.z);
platform->physics.body_rotation_get(body, &rot.x, &rot.y, &rot.z, &rot.w);
quat_assign(&suz->transform.rotation, &rot);
transform_set_position(suz, &pos);
//log_message("Pos : %.3f, %.3f, %.3f", pos.x, pos.y, pos.z);
}
Loading…
Cancel
Save