Implemented Debug physics mesh drawing for box and sphere primitives

dev
Shariq Shah 8 years ago
parent 9c2856eb87
commit 8c0433e2be
  1. 6
      README.md
  2. 8
      assets/test_scene.symtres
  3. 15
      src/common/common.h
  4. 3
      src/game/config_vars.c
  5. 5
      src/game/main.c
  6. 78
      src/game/physics.c
  7. 7
      src/game/physics.h
  8. 28
      src/libsymmetry/game.c
  9. 4
      src/libsymmetry/im_render.c
  10. 2
      src/libsymmetry/im_render.h
  11. 47
      src/libsymmetry/renderer.c
  12. 3
      src/libsymmetry/renderer.h

@ -155,17 +155,17 @@
- ## TODO - ## TODO
- Convert IM_Vertex array to only be used as temporary storage for vertices between begin and end calls
- Physics forces/torque etc - Physics forces/torque etc
- Implement physics debug visualizations for other primitives and tri mesh shapes
- Replace all renderer_check_gl calls with GL_CHECK macro - Replace all renderer_check_gl calls with GL_CHECK macro
- 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
- Serializing/Deserializing physics data - Serializing/Deserializing physics data
- Storing entity reference/id in rigidbody - Storing entity reference/id in rigidbody
- Storing rigidbody in entity - Storing rigidbody in entity
- Expose complete physics api with forces/joints etc - Expose complete physics api with forces/joints etc
- Complete ODE integration - Complete ODE integration
- Proper implementation of Scene struct with per-scene settings and configurations that can be loaded/saved to file instead of just dumping entities into a file
- Test physics code on linux - Test physics code on linux
- Pipeline improvements, getting models/materials etc to/from other programs - Pipeline improvements, getting models/materials etc to/from other programs
- Necessary basic editor additions like placing objects, scaling, rotating etc - Necessary basic editor additions like placing objects, scaling, rotating etc
@ -368,3 +368,5 @@
* Update physics if entity position/rotation/scale etc are changed * Update physics if entity position/rotation/scale etc are changed
* Implemented Physics raycasting * Implemented Physics raycasting
* Implemented immediate mode renderer that can draw arbitrary points, lines and triangles * Implemented immediate mode renderer that can draw arbitrary points, lines and triangles
* Converted IM_Vertex array to only be used as temporary storage for vertices between begin and end calls
* Implemented Debug physics mesh drawing for box and sphere primitives

@ -312,11 +312,11 @@ Entity
scale : 1.000 1.000 1.000 scale : 1.000 1.000 1.000
material : Blinn_Phong material : Blinn_Phong
rotation : 0.000 0.000 0.000 1.000 rotation : 0.000 0.000 0.000 1.000
geometry : default.pamesh geometry : sphere.symbres
is_listener : false is_listener : false
position : 3.000 0.000 4.000 position : 3.000 10.000 4.000
parent : Model_Entity parent : ROOT
name : Suzanne name : Sphere_Ent
renderable : true renderable : true
} }

@ -53,6 +53,15 @@ enum Sound_Attenuation_Type
SA_EXPONENTIAL // Exponential distance attenuation model SA_EXPONENTIAL // Exponential distance attenuation model
}; };
enum Collision_Shape_Type
{
CST_BOX = 0,
CST_SPHERE,
CST_CYLINDER,
CST_TRIMESH,
CST_UNKNOWN
};
struct Raycast_Hit struct Raycast_Hit
{ {
int entity_id; int entity_id;
@ -70,6 +79,7 @@ struct Physics_Api
void (*cs_remove)(Collision_Shape shape); void (*cs_remove)(Collision_Shape shape);
void (*cs_data_set)(Collision_Shape shape, void* data); void (*cs_data_set)(Collision_Shape shape, void* data);
void* (*cs_data_get)(Collision_Shape shape); void* (*cs_data_get)(Collision_Shape shape);
int (*cs_type_get)(Collision_Shape shape);
Collision_Shape (*cs_plane_create)(float a, float b, float c, float d); 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_set)(Collision_Shape shape, float a, float b, float c, float d);
@ -93,6 +103,11 @@ struct Physics_Api
float pos_x, float pos_y, float pos_z, float pos_x, float pos_y, float pos_z,
float dir_x, float dir_y, float dir_z); float dir_x, float dir_y, float dir_z);
void (*cs_position_set)(Collision_Shape shape, float x, float y, float z);
void (*cs_position_get)(Collision_Shape shape, float* x, float* y, float* z);
void (*cs_rotation_set)(Collision_Shape shape, float x, float y, float z, float w);
void (*cs_rotation_get)(Collision_Shape shape, float* x, float* y, float* z, float* w);
void (*body_remove)(Rigidbody body); void (*body_remove)(Rigidbody body);
Rigidbody (*body_box_create)(float length, float width, float height); Rigidbody (*body_box_create)(float length, float width, float height);
Rigidbody (*body_sphere_create)(float radius); Rigidbody (*body_sphere_create)(float radius);

@ -28,7 +28,8 @@ void config_vars_init(void)
hashmap_vec3_setf(cvars, "ambient_light", 0.1f, 0.1f, 0.1f); hashmap_vec3_setf(cvars, "ambient_light", 0.1f, 0.1f, 0.1f);
hashmap_bool_set(cvars, "msaa_enabled", 1); hashmap_bool_set(cvars, "msaa_enabled", 1);
hashmap_int_set(cvars, "msaa_levels", 4); hashmap_int_set(cvars, "msaa_levels", 4);
hashmap_bool_set(cvars, "debug_draw_enabled", 1); hashmap_bool_set(cvars, "debug_draw_enabled", true);
hashmap_bool_set(cvars, "debug_draw_physics", true);
hashmap_int_set(cvars, "video_driver_linux", VD_WAYLAND); hashmap_int_set(cvars, "video_driver_linux", VD_WAYLAND);
hashmap_int_set(cvars, "debug_draw_mode", 0); hashmap_int_set(cvars, "debug_draw_mode", 0);
hashmap_vec4_setf(cvars, "debug_draw_color", 1.f, 0.f, 0.f, 1.f); hashmap_vec4_setf(cvars, "debug_draw_color", 1.f, 0.f, 0.f, 1.f);

@ -152,6 +152,11 @@ int main(int argc, char** args)
.cs_sphere_create = &physics_cs_sphere_create, .cs_sphere_create = &physics_cs_sphere_create,
.cs_capsule_create = &physics_cs_capsule_create, .cs_capsule_create = &physics_cs_capsule_create,
.cs_remove = &physics_cs_remove, .cs_remove = &physics_cs_remove,
.cs_position_set = &physics_cs_position_set,
.cs_position_get = &physics_cs_position_get,
.cs_rotation_set = &physics_cs_rotation_set,
.cs_rotation_get = &physics_cs_rotation_get,
.cs_type_get = &physics_cs_type_get,
.cs_data_set = &physics_cs_data_set, .cs_data_set = &physics_cs_data_set,
.cs_data_get = &physics_cs_data_get, .cs_data_get = &physics_cs_data_get,
.cs_plane_params_get = &physics_cs_plane_params_get, .cs_plane_params_get = &physics_cs_plane_params_get,

@ -113,7 +113,7 @@ void physics_body_rotation_get(Rigidbody body, float * x, float * y, float * z,
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)
{ {
dReal rotation[4] = { 0 }; dReal rotation[4] = { 0.f };
rotation[1] = x; rotation[1] = x;
rotation[2] = y; rotation[2] = y;
rotation[3] = z; rotation[3] = z;
@ -229,12 +229,25 @@ Collision_Shape physics_cs_box_create(float x, float y, float z)
} }
int physics_cs_type_get(Collision_Shape shape)
{
int geom_class = dGeomGetClass(shape);
switch(geom_class)
{
case dBoxClass: return CST_BOX;
case dSphereClass: return CST_SPHERE;
case dCylinderClass: return CST_CYLINDER;
case dTriMeshClass: return CST_TRIMESH;
default: return CST_UNKNOWN;
}
}
void physics_cs_box_params_get(Collision_Shape shape, float* x, float* y, float* z) void physics_cs_box_params_get(Collision_Shape shape, float* x, float* y, float* z)
{ {
assert(x && y && z); assert(x && y && z);
*x = *y = *z = 0.f; *x = *y = *z = 0.f;
float lengths[3] = { 0.f }; dReal lengths[3] = { 0 };
dGeomBoxGetLengths(shape, lengths); dGeomBoxGetLengths(shape, &lengths[0]);
*x = lengths[0]; *x = lengths[0];
*y = lengths[1]; *y = lengths[1];
*z = lengths[2]; *z = lengths[2];
@ -432,6 +445,65 @@ bool physics_cs_ray_cast(Collision_Shape ray,
return out_rayhit->entity_id == -1 ? false : true; return out_rayhit->entity_id == -1 ? false : true;
} }
void physics_cs_position_get(Collision_Shape shape, float * x, float * y, float * z)
{
assert(x && y && z);
if(dGeomGetClass(shape) == dPlaneClass)
{
*x = 0.f;
*y = 0.f;
*z = 0.f;
return;
}
const dReal* pos = dGeomGetPosition(shape);
*x = pos[0];
*y = pos[1];
*z = pos[2];
}
void physics_cs_position_set(Collision_Shape shape, float x, float y, float z)
{
if(dGeomGetClass(shape) == dPlaneClass)
return;
dGeomSetPosition(shape, x, y, z);
}
void physics_cs_rotation_get(Collision_Shape shape, float* x, float* y, float* z, float* w)
{
assert(x && y && z && w);
if(dGeomGetClass(shape) == dPlaneClass)
{
*x = 0.f;
*y = 0.f;
*z = 0.f;
*w = 1.f;
return;
}
dReal rotation[4] = { 1, 0, 0, 0 };
dGeomGetQuaternion(shape, &rotation[0]);
*x = rotation[1];
*y = rotation[2];
*z = rotation[3];
*w = rotation[0];
}
void physics_cs_rotation_set(Collision_Shape shape, float x, float y, float z, float w)
{
if(dGeomGetClass(shape) == dPlaneClass)
return;
dReal rotation[4] = { 0.f };
rotation[1] = x;
rotation[2] = y;
rotation[3] = z;
rotation[0] = w;
dGeomSetQuaternion(shape, &rotation[0]);
}
Collision_Shape physics_cs_ray_create(float length, bool first_contact, bool backface_cull) Collision_Shape physics_cs_ray_create(float length, bool first_contact, bool backface_cull)
{ {
dGeomID ray = dCreateRay(Physics.space, length); dGeomID ray = dCreateRay(Physics.space, length);

@ -19,6 +19,7 @@ Collision_Shape physics_body_cs_get(Rigidbody body);
void physics_body_cs_set(Rigidbody body, Collision_Shape shape); void physics_body_cs_set(Rigidbody body, Collision_Shape shape);
void physics_cs_remove(Collision_Shape shape); void physics_cs_remove(Collision_Shape shape);
int physics_cs_type_get(Collision_Shape shape);
Collision_Shape physics_cs_plane_create(float a, float b, float c, float d); 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_set(Collision_Shape shape, float a, float b, float c, float d);
@ -45,6 +46,12 @@ bool physics_cs_ray_cast(Collision_Shape ray,
float pos_x, float pos_y, float pos_z, float pos_x, float pos_y, float pos_z,
float dir_x, float dir_y, float dir_z); float dir_x, float dir_y, float dir_z);
void physics_cs_position_get(Collision_Shape shape, float* x, float* y, float* z);
void physics_cs_position_set(Collision_Shape shape, float x, float y, float z);
void physics_cs_rotation_get(Collision_Shape shape, float* x, float* y, float* z, float* w);
void physics_cs_rotation_set(Collision_Shape shape, float x, float y, float z, float w);
Rigidbody physics_body_box_create(float x, float y, float z); Rigidbody physics_body_box_create(float x, float y, float z);
Rigidbody physics_body_sphere_create(float radius); Rigidbody physics_body_sphere_create(float radius);
Rigidbody physics_body_capsule_create(float radius, float height); Rigidbody physics_body_capsule_create(float radius, float height);

@ -255,7 +255,8 @@ void scene_setup(void)
} }
platform->physics.cs_plane_create(0, 1, 0, 0); platform->physics.cs_plane_create(0, 1, 0, 0);
Rigidbody box = platform->physics.body_box_create(2.5, 2.5, 2.5); //Rigidbody box = platform->physics.body_box_create(2.5, 2.5, 2.5);
Rigidbody box = platform->physics.body_sphere_create(3.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);*/
@ -264,15 +265,17 @@ void scene_setup(void)
entity_rigidbody_set(suz, box); entity_rigidbody_set(suz, box);
suz->collision.on_collision = &on_collision_test; suz->collision.on_collision = &on_collision_test;
Collision_Shape plane = platform->physics.cs_plane_create(0, 1, 0, 0); Rigidbody sphere = platform->physics.body_sphere_create(3.5f);
//Rigidbody ground_box = platform->physics.body_box_create(10, 10, 10); struct Entity* sphere_ent = entity_find("Sphere_Ent");
/*platform->physics.body_position_set(ground_box, 0.f, 0.f, 0.f); entity_rigidbody_set(sphere_ent, sphere);
platform->physics.body_kinematic_set(ground_box);*/
struct Entity* ground = entity_find("Ground");
entity_collision_shape_set(ground, plane);
//entity_rigidbody_set(ground, ground_box);
/*platform->physics.body_data_set(ground_box, (void*)ground->id);*/
//Collision_Shape plane = platform->physics.cs_plane_create(0, 1, 0, 0);
Rigidbody ground_box = platform->physics.body_box_create(10, 5, 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");
//entity_collision_shape_set(ground, plane);
entity_rigidbody_set(ground, ground_box);
} }
void debug(float dt) void debug(float dt)
@ -525,9 +528,14 @@ void debug(float dt)
im_end(); im_end();
vec4 prim_color = {1.f, 1.f, 0.f, 1.f}; vec4 prim_color = {1.f, 1.f, 0.f, 1.f};
im_cube(5.f, im_position, im_rot, prim_color, GDM_TRIANGLES); im_box(5.f, 2.f, 10.f, im_position, im_rot, prim_color, GDM_TRIANGLES);
for(int i = 0; i < 10; i++)
{
im_position.x += i * 2.f;
im_sphere(2.f, im_position, im_rot, prim_color, GDM_TRIANGLES); im_sphere(2.f, im_position, im_rot, prim_color, GDM_TRIANGLES);
} }
}
bool run(void) bool run(void)
{ {

@ -100,7 +100,7 @@ void im_pos(float x, float y, float z)
active_vertex_index++; active_vertex_index++;
} }
void im_cube(float length, vec3 position, quat rotation, vec4 color, int draw_mode) void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode)
{ {
if(active_geom) if(active_geom)
{ {
@ -113,7 +113,7 @@ void im_cube(float length, vec3 position, quat rotation, vec4 color, int draw_mo
active_geom->draw_mode = draw_mode; active_geom->draw_mode = draw_mode;
active_geom->prim_geom_index = geom_create_from_file("cube.symbres"); active_geom->prim_geom_index = geom_create_from_file("cube.symbres");
vec3_assign(&active_geom->position, &position); vec3_assign(&active_geom->position, &position);
vec3 scale = { length, length, length }; vec3 scale = { x, y, z};
vec3_assign(&active_geom->scale, &scale); vec3_assign(&active_geom->scale, &scale);
vec4_assign(&active_geom->color, &color); vec4_assign(&active_geom->color, &color);
quat_assign(&active_geom->rotation, &rotation); quat_assign(&active_geom->rotation, &rotation);

@ -40,7 +40,7 @@ void im_init(void);
void im_cleanup(void); void im_cleanup(void);
void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode); void im_begin(vec3 position, quat rotation, vec3 scale, vec4 color, int draw_mode);
void im_pos(float x, float y, float z); void im_pos(float x, float y, float z);
void im_cube(float length, vec3 position, quat rotation, vec4 color, int draw_mode); void im_box(float x, float y, float z, vec3 position, quat rotation, vec4 color, int draw_mode);
void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_mode); void im_sphere(float radius, vec3 position, quat rotation, vec4 color, int draw_mode);
void im_end(void); void im_end(void);
void im_render(struct Entity* active_viewer); void im_render(struct Entity* active_viewer);

@ -408,6 +408,51 @@ void renderer_draw(struct Entity* active_viewer)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
} }
// Debug Physics render
if(hashmap_bool_get(cvars, "debug_draw_physics"))
{
static vec4 physics_draw_color = { 0.f, 0.f, 1.f, 1.f };
struct Entity* entity_list = entity_get_all();
for(int i = 0; i < array_len(entity_list); i++)
{
if(!entity_list[i].has_collision) continue;
struct Entity* entity = &entity_list[i];
//Get collision mesh and it's props then render it
vec3 pos = {0.f};
quat rot = {0.f, 0.f, 0.f, 1.f };
if(entity->collision.rigidbody)
{
platform->physics.body_position_get(entity->collision.rigidbody, &pos.x, &pos.y, &pos.z);
platform->physics.body_rotation_get(entity->collision.rigidbody, &rot.x, &rot.y, &rot.z, &rot.w);
}
else
{
platform->physics.cs_position_get(entity->collision.collision_shape, &pos.x, &pos.y, &pos.z);
platform->physics.cs_rotation_get(entity->collision.collision_shape, &rot.x, &rot.y, &rot.z, &rot.w);
}
int collision_shape_type = platform->physics.cs_type_get(entity->collision.collision_shape);
switch(collision_shape_type)
{
case CST_SPHERE:
{
float radius = platform->physics.cs_sphere_radius_get(entity->collision.collision_shape);
im_sphere(radius, pos, rot, physics_draw_color, GDM_TRIANGLES);
}
break;
case CST_BOX:
{
float x = 0.f, y = 0.f, z = 0.f;
platform->physics.cs_box_params_get(entity->collision.collision_shape, &x, &y, &z);
im_box(x, y, z, pos, rot, physics_draw_color, GDM_TRIANGLES);
};
break;
default: break;
}
}
}
//Immediate mode geometry render //Immediate mode geometry render
im_render(active_viewer); im_render(active_viewer);
@ -508,6 +553,7 @@ void renderer_settings_get(struct Render_Settings* settings)
settings->fog.max_dist = hashmap_float_get(cvars, "fog_max_dist"); settings->fog.max_dist = hashmap_float_get(cvars, "fog_max_dist");
settings->fog.color = hashmap_vec3_get(cvars, "fog_color"); settings->fog.color = hashmap_vec3_get(cvars, "fog_color");
settings->debug_draw_enabled = hashmap_bool_get(cvars, "debug_draw_enabled"); settings->debug_draw_enabled = hashmap_bool_get(cvars, "debug_draw_enabled");
settings->debug_draw_physics = hashmap_bool_get(cvars, "debug_draw_physics");
settings->debug_draw_mode = hashmap_int_get(cvars, "debug_draw_mode"); settings->debug_draw_mode = hashmap_int_get(cvars, "debug_draw_mode");
settings->debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); settings->debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color");
settings->ambient_light = hashmap_vec3_get(cvars, "ambient_light"); settings->ambient_light = hashmap_vec3_get(cvars, "ambient_light");
@ -522,6 +568,7 @@ void renderer_settings_set(const struct Render_Settings* settings)
hashmap_float_set(cvars, "fog_max_dist", settings->fog.max_dist); hashmap_float_set(cvars, "fog_max_dist", settings->fog.max_dist);
hashmap_vec3_set(cvars, "fog_color", &settings->fog.color); hashmap_vec3_set(cvars, "fog_color", &settings->fog.color);
hashmap_bool_set(cvars, "debug_draw_enabled", settings->debug_draw_enabled); hashmap_bool_set(cvars, "debug_draw_enabled", settings->debug_draw_enabled);
hashmap_bool_set(cvars, "debug_draw_physics", settings->debug_draw_physics);
hashmap_int_set(cvars, "debug_draw_mode", settings->debug_draw_mode); hashmap_int_set(cvars, "debug_draw_mode", settings->debug_draw_mode);
hashmap_vec4_set(cvars, "debug_draw_color", &settings->debug_draw_color); hashmap_vec4_set(cvars, "debug_draw_color", &settings->debug_draw_color);
hashmap_vec3_set(cvars, "ambient_light", &settings->ambient_light); hashmap_vec3_set(cvars, "ambient_light", &settings->ambient_light);

@ -26,9 +26,10 @@ struct Render_Settings
{ {
struct Fog fog; struct Fog fog;
vec3 ambient_light; vec3 ambient_light;
int debug_draw_enabled; bool debug_draw_enabled;
vec4 debug_draw_color; vec4 debug_draw_color;
int debug_draw_mode; int debug_draw_mode;
bool debug_draw_physics;
}; };
struct Entity; struct Entity;

Loading…
Cancel
Save