Physics is now updated when entity's position/rotation is changed

dev
Shariq Shah 8 years ago
parent 0af53d7456
commit b3cecf3221
  1. 4
      README.md
  2. 2
      src/game/physics.c
  3. 85
      src/libsymmetry/entity.c
  4. 12
      src/libsymmetry/entity.h
  5. 31
      src/libsymmetry/game.c
  6. 1
      src/libsymmetry/transform.c

@ -155,7 +155,6 @@
- ## TODO
- 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
@ -167,6 +166,8 @@
- Expose complete physics api with forces/joints etc
- Complete ODE integration
- Test physics code on linux
- Pipeline improvements, getting models/materials etc to/from other programs
- Necessary basic editor additions like placing objects, scaling, rotating etc
- Terrain rendering using heightfields
- Re-order lib folder for linux by putting all libraries in one folder
- Figure out a better way for handling libs on linux, current method DOES NOT work on other computers
@ -363,3 +364,4 @@
* Added physics spheres and other primitive shapes
* Separated collision shape and rigidbody
* Implemented Getting/Modifying primitive physics shapes' values like length, radius etc
* Update physics if entity position/rotation/scale etc are changed

@ -97,6 +97,7 @@ void physics_body_position_get(Rigidbody body, float * x, float * y, float * z)
void physics_body_position_set(Rigidbody body, float x, float y, float z)
{
dBodySetPosition(body, x, y, z);
dBodyEnable(body);
}
void physics_body_rotation_get(Rigidbody body, float * x, float * y, float * z, float * w)
@ -117,6 +118,7 @@ void physics_body_rotation_set(Rigidbody body, float x, float y, float z, float
rotation[3] = z;
rotation[0] = w;
dBodySetQuaternion(body, &rotation[0]);
dBodyEnable(body);
}

@ -58,14 +58,29 @@ void entity_remove(int index)
case ET_STATIC_MESH: model_destroy(entity); break;
case ET_SOUND_SOURCE:
{
platform->sound.source_instance_destroy(entity->sound_source.source_instance);
entity->sound_source.source_instance = 0;
}
break;
case ET_ROOT: break;
default: log_error("entity:remove", "Invalid entity type"); break;
};
entity->id = -1;
if(entity->has_collision)
{
platform->physics.body_remove(entity->collision.rigidbody);
entity->has_collision = false;
entity->collision.rigidbody = NULL;
entity->collision.on_collision = NULL;
}
if(entity->is_listener)
{
platform->sound.listener_update(0.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 1.f, 0.f);
entity->is_listener = false;
}
entity->id = -1;
entity->marked_for_deletion = false;
entity->editor_selected = 0;
entity->renderable = false;
@ -97,6 +112,9 @@ struct Entity* entity_create(const char* name, const int type, int parent_id)
new_entity->type = type;
new_entity->marked_for_deletion = false;
new_entity->renderable = false;
new_entity->has_collision = false;
new_entity->collision.on_collision = NULL;
new_entity->collision.rigidbody = NULL;
new_entity->editor_selected = 0;
transform_create(new_entity, parent_id);
return new_entity;
@ -153,7 +171,7 @@ void entity_post_update(void)
{
camera_update_view(entity);
}
else if(entity->type == ET_SOUND_SOURCE)
else
{
vec3 abs_pos = {0.f, 0.f, 0.f};
vec3 abs_fwd = {0.f, 0.f, -1.f};
@ -162,22 +180,27 @@ void entity_post_update(void)
transform_get_absolute_forward(entity, &abs_fwd);
transform_get_absolute_up(entity, &abs_up);
if(entity->type == ET_SOUND_SOURCE)
platform->sound.source_instance_update_position(entity->sound_source.source_instance, abs_pos.x, abs_pos.y, abs_pos.z);
}
if(entity->is_listener)
{
vec3 abs_pos = {0.f, 0.f, 0.f};
vec3 abs_fwd = {0.f, 0.f, -1.f};
vec3 abs_up = {0.f, 1.f, 0.f};
transform_get_absolute_pos(entity, &abs_pos);
transform_get_absolute_forward(entity, &abs_fwd);
transform_get_absolute_up(entity, &abs_up);
platform->sound.listener_update(abs_pos.x, abs_pos.y, abs_pos.z,
abs_fwd.x, abs_fwd.y, abs_fwd.z,
abs_up.x, abs_up.y, abs_up.z);
}
if(entity->has_collision && entity->transform.sync_physics)
{
assert(entity->collision.rigidbody);
quat abs_rot = { 0.f, 0.f, 0.f, 1.f };
transform_get_absolute_rot(entity, &abs_rot);
platform->physics.body_rotation_set(entity->collision.rigidbody, abs_rot.x, abs_rot.y, abs_rot.z, abs_rot.w);
platform->physics.body_position_set(entity->collision.rigidbody, abs_pos.x, abs_pos.y, abs_pos.z);
entity->transform.sync_physics = false;
}
}
}
}
}
@ -663,6 +686,7 @@ void entity_rigidbody_on_move(Rigidbody body)
quat_assign(&entity->transform.rotation, &rot);
transform_set_position(entity, &pos);
entity->transform.sync_physics = false;
}
void entity_rigidbody_on_collision(Rigidbody body_A, Rigidbody body_B)
@ -682,5 +706,42 @@ void entity_rigidbody_on_collision(Rigidbody body_A, Rigidbody 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);
if(ent_A && ent_A->collision.on_collision)
{
ent_A->collision.on_collision(ent_A, ent_B ? ent_B : NULL, body_A, body_B ? body_B : NULL);
}
if(ent_B && ent_B->collision.on_collision)
{
ent_B->collision.on_collision(ent_B, ent_A ? ent_A : NULL, body_B, body_A ? body_A : NULL);
}
if(ent_A && ent_B)
{
log_message("Entity %s collided with Entity %s", ent_A->name, ent_B->name);
}
}
void entity_rigidbody_set(struct Entity * entity, Rigidbody body)
{
assert(entity && body);
//Remove previous rigidbody if there is any
if(entity->has_collision && entity->collision.rigidbody)
{
platform->physics.body_remove(entity->collision.rigidbody);
entity->collision.rigidbody = NULL;
}
entity->has_collision = true;
entity->collision.rigidbody = body;
vec3 abs_pos = {0.f, 0.f, 0.f};
quat abs_rot = {0.f, 0.f, 0.f, 1.f};
transform_get_absolute_pos(entity, &abs_pos);
transform_get_absolute_rot(entity, &abs_rot);
platform->physics.body_rotation_set(body, abs_rot.x, abs_rot.y, abs_rot.z, abs_rot.w);
platform->physics.body_position_set(body, abs_pos.x, abs_pos.y, abs_pos.z);
platform->physics.body_data_set(body, (void*)entity->id);
}

@ -11,6 +11,8 @@
struct Material_Param;
struct Parser_Object;
typedef void (*Collision_CB)(struct Entity* this_entity, struct Entity* other_entity, Rigidbody, Rigidbody);
enum Entity_Type
{
ET_NONE,
@ -41,6 +43,7 @@ struct Transform
int parent;
int* children;
bool is_modified;
bool sync_physics;
};
struct Model
@ -100,6 +103,12 @@ struct Light
float depth_bias;
};
struct Collision
{
Rigidbody rigidbody;
Collision_CB on_collision;
};
struct Entity
{
int id;
@ -108,8 +117,10 @@ struct Entity
bool is_listener; /* TODO: Replace all booleans with flags */
bool marked_for_deletion;
bool renderable;
bool has_collision;
int editor_selected;
struct Transform transform;
struct Collision collision;
union
{
@ -143,5 +154,6 @@ 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_rigidbody_on_move(Rigidbody body);
void entity_rigidbody_on_collision(Rigidbody body_A, Rigidbody body_B);
void entity_rigidbody_set(struct Entity* entity, Rigidbody body);
#endif

@ -48,6 +48,7 @@ static void debug(float dt);
static void debug_gui(float dt);
static void scene_setup(void);
static void on_box_move(Rigidbody body);
static void on_collision_test(struct Entity* this_ent, struct Entity* other_ent, Rigidbody body, Rigidbody body2);
static struct Game_State* game_state = NULL;
struct Platform_Api* platform = NULL;
@ -151,7 +152,7 @@ void scene_setup(void)
// /* platform->sound.source_play(sound_source->source_handle); */
// int parent_node = new_ent->id;
// int num_suz = 10;
// int num_suz = 50;
// srand(time(NULL));
// for(int i = 0; i < num_suz; i++)
// {
@ -254,17 +255,21 @@ void scene_setup(void)
platform->physics.cs_plane_create(0, 1, 0, 0);
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_mass_set(box, 10.f);
platform->physics.body_data_set(box, (void*)suz_id);
platform->physics.body_force_add(box, -100.f, 0.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_data_set(box, (void*)suz_id);*/
//platform->physics.body_force_add(box, -100.f, 0.f, 0.f);
struct Entity* suz = entity_find("Model_Entity");
entity_rigidbody_set(suz, box);
suz->collision.on_collision = &on_collision_test;
/*Rigidbody plane = platform->physics.plane_create(0, 1, 0, 0);*/
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_kinematic_set(ground_box);
struct Entity* ground = entity_find("Ground");
platform->physics.body_data_set(ground_box, (void*)ground->id);
entity_rigidbody_set(ground, ground_box);
/*platform->physics.body_data_set(ground_box, (void*)ground->id);*/
}
@ -390,7 +395,7 @@ void debug(float dt)
/*struct Entity* model = scene_find("Model_Entity");
vec3 x_axis = {0, 1, 0};
transform_rotate(model, &x_axis, 25.f * dt, TS_WORLD);
transform_rotate(model, &x_axis, 50.f * dt, TS_WORLD);
vec3 amount = {0, 0, -5 * dt};
transform_translate(model, &amount, TS_LOCAL);*/
@ -1713,3 +1718,15 @@ struct Game_State* game_state_get(void)
{
return game_state;
}
void on_collision_test(struct Entity* this_ent, struct Entity* other_ent, Rigidbody body, Rigidbody body2)
{
float y = this_ent->transform.position.y;
if(y < 10.f)
{
vec3 translation = {0.f, 50.f, 0.f};
transform_translate(this_ent, &translation, TS_WORLD);
//platform->physics.body_force_add(body, 0.f, -100.f, 0.f);
}
//platform->physics.body_force_add(body, 0.f, 500.f, 0.f);
}

@ -207,6 +207,7 @@ void transform_update_transmat(struct Entity* entity)
}
}
transform->is_modified = true;
if(entity->has_collision) entity->transform.sync_physics = true;
}
void transform_destroy(struct Entity* entity)

Loading…
Cancel
Save