Fixed several bugs and implementing loading saving entity archetypes when loading and saving scenes

dev
Shariq Shah 6 years ago
parent 239d44ac6e
commit 4f3632bb3e
  1. 7
      assets/entities/Suzanne.symtres
  2. 14
      assets/entities/default.symtres
  3. 2
      src/common/array.h
  4. 13
      src/game/console.c
  5. 27
      src/game/editor.c
  6. 7
      src/game/entity.c
  7. 1
      src/game/framebuffer.c
  8. 13
      src/game/game.c
  9. 11
      src/game/player.c
  10. 7
      src/game/renderer.c
  11. 36
      src/game/scene.c
  12. 1
      src/game/scene.h
  13. 10
      todo.txt

@ -2,8 +2,13 @@ Entity
{
type : 6
material : 0
diffuse_color : 1.000 0.000 1.000 1.000
geometry : suzanne.symbres
specular : 1.0000
active : true
name : Suzanne_0
diffuse_texture : white.tga
diffuse : 0.5000
specular_strength : 1.0000
name : Suzanne_Saved
}

@ -0,0 +1,14 @@
Entity
{
type : 6
material : 0
diffuse_color : 1.000 0.000 1.000 1.000
geometry : suzanne.symbres
specular : 1.0000
active : true
diffuse_texture : default.tga
diffuse : 1.0000
specular_strength : 1.0000
name : Suzanne_Default
}

@ -20,7 +20,7 @@ int array_copy_(void* arr_src, void** arr_dest);
#define array_grow(array, type) (type*) array_grow_((void**)&array)
#define array_push(array, value, type) {type* new_val = array_grow(array, type); \
*new_val = value;}
#define array_get_last(array, type) (type*) (&array[array_len(array)])
#define array_get_last(array, type) (type*) (&array[array_len(array) - 1])
#define array_set_last(array, val, type) {type* last = array_get_last(array, type); \
*last = val}
#define array_pop(array) array_pop_((void**)&array)

@ -15,6 +15,7 @@ static struct nk_color console_message_color[CMT_MAX];
static int console_filter(const struct nk_text_edit *box, nk_rune unicode);
static void console_command_scene_empty(struct Console* console, const char* command);
static void console_command_scene_save(struct Console* console, const char* command);
static void console_command_scene_load(struct Console* console, const char* command);
static void console_command_entity_save(struct Console* console, const char* command);
@ -45,6 +46,7 @@ void console_init(struct Console* console)
}
console->console_commands = hashmap_new();
hashmap_ptr_set(console->console_commands, "scene_empty", &console_command_scene_empty);
hashmap_ptr_set(console->console_commands, "scene_save", &console_command_scene_save);
hashmap_ptr_set(console->console_commands, "scene_load", &console_command_scene_load);
hashmap_ptr_set(console->console_commands, "entity_save", &console_command_entity_save);
@ -266,3 +268,14 @@ void console_command_scene_load(struct Console* console, const char* command)
if(!scene_load(game_state_get()->scene, full_filename, DIRT_INSTALL))
log_error("scene_load", "Command failed");
}
void console_command_scene_empty(struct Console* console, const char* command)
{
char filename[MAX_FILENAME_LEN];
memset(filename, '\0', MAX_FILENAME_LEN);
struct Scene* scene = game_state_get()->scene;
scene_destroy(scene);
scene_post_update(scene);
scene_init(scene);
}

@ -174,9 +174,12 @@ void editor_init_camera(struct Editor* editor, struct Hashmap* cvars)
editor_camera->clear_color.z = 0.9f;
editor_camera->clear_color.w = 1.f;
int render_width = hashmap_int_get(cvars, "render_width");
int render_height = hashmap_int_get(cvars, "render_height");
camera_attach_fbo(editor_camera, render_width, render_height, true, true, true);
if(editor_camera->fbo == -1)
{
int render_width = hashmap_int_get(cvars, "render_width");
int render_height = hashmap_int_get(cvars, "render_height");
camera_attach_fbo(editor_camera, render_width, render_height, true, true, true);
}
vec3 cam_pos = {5.f, 20.f, 50.f};
transform_translate(editor_camera, &cam_pos, TS_WORLD);
@ -1328,10 +1331,10 @@ void editor_camera_update(struct Editor* editor, float dt)
{
struct Game_State* game_state = game_state_get();
struct Gui* gui = game_state->gui;
if(game_state->console->visible)
if(game_state->console->visible || nk_item_is_any_active(&gui->context))
return;
struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR];
struct Camera* editor_camera = &game_state->scene->cameras[CAM_EDITOR];
static float total_up_down_rot = 0.f;
float move_speed = editor->camera_move_speed, turn_speed = editor->camera_turn_speed;
float turn_up_down = 0.f;
@ -1347,7 +1350,7 @@ void editor_camera_update(struct Editor* editor, float dt)
if(input_map_state_get("Turn_Right", KS_PRESSED)) turn_left_right += turn_speed;
if(input_map_state_get("Turn_Left", KS_PRESSED)) turn_left_right -= turn_speed;
if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED) && !nk_item_is_any_active(&game_state_get()->gui->context))
if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED) && !nk_item_is_any_active(&gui->context))
{
const float scale = 0.5f;
int cursor_lr, cursor_ud;
@ -1488,10 +1491,16 @@ void editor_widget_color_combov4(struct nk_context* context, vec4* color, int wi
void editor_cleanup(struct Editor* editor)
{
event_manager_unsubscribe(game_state_get()->event_manager, EVT_MOUSEBUTTON_PRESSED, &editor_on_mousebutton_press);
event_manager_unsubscribe(game_state_get()->event_manager, EVT_MOUSEBUTTON_RELEASED, &editor_on_mousebutton_release);
struct Event_Manager* event_manager = game_state_get()->event_manager;
event_manager_unsubscribe(event_manager, EVT_MOUSEBUTTON_PRESSED, &editor_on_mousebutton_press);
event_manager_unsubscribe(event_manager, EVT_MOUSEBUTTON_RELEASED, &editor_on_mousebutton_release);
event_manager_unsubscribe(event_manager, EVT_MOUSEMOTION, &editor_on_mousemotion);
event_manager_unsubscribe(event_manager, EVT_KEY_PRESSED, &editor_on_key_press);
event_manager_unsubscribe(event_manager, EVT_KEY_RELEASED, &editor_on_key_release);
for(int i = 0; i < array_len(debug_vars_list); i++)
editor_debugvar_slot_remove(i);
editor_debugvar_slot_remove(i);
array_free(debug_vars_list);
array_free(empty_indices);
}

@ -506,7 +506,14 @@ struct Entity* entity_load(const char* filename, int directory_type)
if(new_entity)
{
if(i == 0)
{
new_entity->archetype_index = scene_entity_archetype_add(game_state_get()->scene, filename);
parent_entity = new_entity;
}
// We don't want this entity to be saved when we're saving the scene because
// this entity and its parent will be loaded from this same file next time the scene is loaded
if(i != 0)
new_entity->flags |= EF_TRANSIENT;
num_entites_loaded++;
log_message("Entity %s loaded from %s", new_entity->name, filename);
}

@ -95,6 +95,7 @@ int framebuffer_create(int width, int height, bool has_depth, bool has_color, bo
{
index = *array_get_last(empty_indices, int);
array_pop(empty_indices);
framebuffer = &fbo_list[index];
}
framebuffer->handle = fbo;

@ -102,10 +102,10 @@ bool game_init(struct Window* window, struct Hashmap* cvars)
gui_init(game_state->gui);
console_init(game_state->console);
geom_init();
physics_init();
physics_gravity_set(0.f, -9.8f, 0.f);
physics_body_set_moved_callback(entity_rigidbody_on_move);
physics_body_set_collision_callback(entity_rigidbody_on_collision);
//physics_init();
//physics_gravity_set(0.f, -9.8f, 0.f);
//physics_body_set_moved_callback(entity_rigidbody_on_move);
//physics_body_set_collision_callback(entity_rigidbody_on_collision);
sound_init(game_state->sound);
renderer_init(game_state->renderer);
@ -115,6 +115,7 @@ bool game_init(struct Window* window, struct Hashmap* cvars)
/* Debug scene setup */
//game_scene_setup();
scene_load(game_state->scene, "scenes/default.symtres", DIRT_INSTALL);
game_state->is_initialized = true;
return game_state->is_initialized;
}
@ -557,7 +558,7 @@ void game_update(float dt, bool* window_should_close)
scene_update(game_state->scene, dt);
if(game_state->game_mode == GAME_MODE_GAME)
{
physics_step(dt);
//physics_step(dt);
}
else if(game_state->game_mode == GAME_MODE_EDITOR)
{
@ -1912,7 +1913,7 @@ void game_cleanup(void)
texture_cleanup();
shader_cleanup();
sound_cleanup(game_state->sound);
physics_cleanup();
//physics_cleanup();
event_manager_cleanup(game_state->event_manager);
free(game_state->editor);

@ -40,9 +40,13 @@ void player_init(struct Player* player, struct Scene* scene)
player->camera_node->base.flags |= EF_TRANSIENT;
player->mesh->base.flags |= EF_TRANSIENT;
int render_width = hashmap_int_get(config, "render_width");
int render_height = hashmap_int_get(config, "render_height");
camera_attach_fbo(player_camera, render_width, render_height, true, true, true);
if(player_camera->fbo == -1)
{
int render_width = hashmap_int_get(config, "render_width");
int render_height = hashmap_int_get(config, "render_height");
camera_attach_fbo(player_camera, render_width, render_height, true, true, true);
}
transform_parent_set(player_camera, player, true);
vec3 cam_translation = {0.f, 20.f, 2.f};
@ -58,6 +62,7 @@ void player_init(struct Player* player, struct Scene* scene)
void player_destroy(struct Player* player)
{
entity_reset(player, player->base.id);
scene_entity_base_remove(game_state_get()->scene, &player->base);
player->base.flags = EF_NONE;
}

@ -459,8 +459,11 @@ void renderer_on_framebuffer_size_changed(const struct Event* event)
for(int i = 0; i < MAX_CAMERAS; i++)
{
struct Camera* viewer = &scene->cameras[i];
viewer->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f;
camera_update_proj(viewer);
if(viewer->resizeable)
{
viewer->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f;
camera_update_proj(viewer);
}
}
framebuffer_resize_all(width, height);

@ -279,7 +279,6 @@ void scene_write_entity_list(struct Scene* scene, int entity_type, struct Parser
while(count < max_length)
{
//((char*)entity) += stride * count;
((char*)entity) += stride;
if(!(entity->flags & EF_TRANSIENT) && (entity->flags & EF_ACTIVE))
{
@ -295,6 +294,7 @@ void scene_write_entity_list(struct Scene* scene, int entity_type, struct Parser
}
}
count++;
((char*)entity) += stride;
}
}
@ -634,6 +634,7 @@ void scene_light_remove(struct Scene* scene, struct Light* light)
void scene_camera_remove(struct Scene* scene, struct Camera* camera)
{
assert(scene && camera);
camera_reset(camera);
scene_entity_base_remove(scene, &camera->base);
}
@ -926,3 +927,36 @@ bool scene_save_(const char* filename, int directory_type)
return success;
}
int scene_entity_archetype_add(struct Scene* scene, const char* filename)
{
// check if we have already added this archetype, if we have, return that index
// otherwise add it and return the index
int index = -1;
for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++)
{
if(strncmp(filename, &scene->entity_archetypes[i][0], MAX_FILENAME_LEN) == 0)
{
index = i;
break;
}
}
if(index == -1)
{
for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++)
{
if(scene->entity_archetypes[i][0] == '\0')
{
strncpy(&scene->entity_archetypes[i][0], filename, MAX_FILENAME_LEN);
index = i;
break;
}
}
}
if(index == -1)
log_warning("Out of archetype indices!");
return index;
}

@ -56,6 +56,7 @@ struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type
void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct Entity* parent);
void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity); // Sets root entity as parent
int scene_entity_archetype_add(struct Scene* scene, const char* filename);
void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Result* out_results);

@ -1,5 +1,7 @@
Todo:
- Save default entity archetype to be loaded when there is not other archetype or in case of an error as fallback
- Fix cameras not resizing to current resolution when scene is loaded/reloaded
- Allow renaming scene objects in editor
- Add parameter to entity_load command that renames the newly loaded object to whatever the second specified parameter is
- Bring back debug variable display in editor and allow showing colours, textures etc
- Implment/Test reading/writing scene that has a mixture of default entites and entity archetypes
- Serialize player, camera properties to file
@ -18,6 +20,7 @@ Todo:
- Better, more accurate picking
- Editor related messages/notifications in the bottom status bar
? Disable entity picking when tool is in use or only allow picking when pressing ALT
? Maybe remove physics engine and ode all together if we're not using it or investigate the memory leaks that it causes if we're going to keep it?
- Disable editor event recievers on game mode change
- Editor Undo
- Duplicate with Ctrl-D
@ -123,6 +126,7 @@ Bugs:
- Fix shader preprocessor failing when the file in //include directive is empty
- Fix bug with blinn shader reaching maximum uniform number on mac
- Fix delete in editor not working when the cursor is hovering over scene heirarchy window
- Investigate memory leaks caused by nuklear or opengl related operations in gui_update
Done:
* Input
@ -337,4 +341,6 @@ Done:
* Implemented flags that specify whether an entity should be written to file or not for example to avoid writing cameras and player to file
* In editor, only show entities with specific flags
* Fixed bugs with meshes being registered to uninitialized materials and not rendering
* Added EF_SKIP_RENDER flag to allow entites to skip rendering
* Added EF_SKIP_RENDER flag to allow entites to skip rendering
* Save default entity archetype to be loaded when there is not other archetype or in case of an error as fallback
* Ensure cameras are not initialized multiple times
Loading…
Cancel
Save