diff --git a/src/common/linmath.h b/src/common/linmath.h index 90e31f9..47403c4 100755 --- a/src/common/linmath.h +++ b/src/common/linmath.h @@ -14,7 +14,7 @@ i'll make my own additions like SIMD etc later on. #define M_PI 3.14159265358979323846f #endif #define EPSILON 0.000001 -#define TO_RADIANS(degrees) ((degrees * M_PI) / 180.0) +#define TO_RADIANS(degrees) ((degrees * M_PI) / 180.f) #define TO_DEGREES(radians) ((radians * 180.0) / M_PI) typedef struct vec2_t diff --git a/src/common/num_types.h b/src/common/num_types.h index a3d1ac8..ca0aa21 100755 --- a/src/common/num_types.h +++ b/src/common/num_types.h @@ -4,12 +4,13 @@ #include #include -typedef int8_t int8; -typedef int32_t int32; -typedef int64_t int64; -typedef unsigned int uint; -typedef uint32_t uint32; -typedef uint64_t uint64; -typedef uint8_t uint8; +typedef int8_t int8; +typedef int32_t int32; +typedef int64_t int64; +typedef unsigned int uint; +typedef uint32_t uint32; +typedef uint64_t uint64; +typedef uint8_t uint8; +typedef unsigned char uchar; #endif diff --git a/src/common/parser.c b/src/common/parser.c index c9126de..207e0de 100755 --- a/src/common/parser.c +++ b/src/common/parser.c @@ -245,6 +245,7 @@ int parser_object_type_from_str(const char* str) else if(strncmp(str, "Key", HASH_MAX_KEY_LEN) == 0) object_type = PO_KEY; else if(strncmp(str, "Scene_Entity_Entry", HASH_MAX_KEY_LEN) == 0) object_type = PO_SCENE_ENTITY_ENTRY; else if(strncmp(str, "Scene_Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_SCENE_CONFIG; + else if(strncmp(str, "Player", HASH_MAX_KEY_LEN) == 0) object_type = PO_PLAYER; return object_type; } @@ -261,6 +262,7 @@ const char* parser_object_type_to_str(int type) case PO_UNKNOWN: return "Unknown"; case PO_SCENE_CONFIG: return "Scene_Config"; case PO_SCENE_ENTITY_ENTRY: return "Scene_Entity_Entry"; + case PO_PLAYER: return "Player"; default: return "Unknown"; } } diff --git a/src/common/parser.h b/src/common/parser.h index 9d5849b..1a8a0c8 100755 --- a/src/common/parser.h +++ b/src/common/parser.h @@ -13,6 +13,7 @@ enum Parser_Object_Type PO_MATERIAL, PO_MODEL, PO_KEY, + PO_PLAYER, PO_UNKNOWN }; diff --git a/src/game/editor.c b/src/game/editor.c index a567b89..e087ba1 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -164,7 +164,7 @@ void editor_init_camera(struct Editor* editor, struct Hashmap* cvars) { struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; entity_rename(editor_camera, "Editor_Camera"); - editor_camera->base.active = true; + editor_camera->base.flags |= EF_ACTIVE; editor_camera->clear_color.x = 0.3f; editor_camera->clear_color.y = 0.6f; editor_camera->clear_color.z = 0.9f; @@ -1170,7 +1170,7 @@ void editor_on_key_release(const struct Event* event) if(event->key.key == KEY_DELETE && editor->selected_entity) { - editor->selected_entity->marked_for_deletion = true; + editor->selected_entity->flags |= EF_MARKED_FOR_DELETION; editor_entity_select(editor, NULL); } } @@ -1193,15 +1193,16 @@ void editor_entity_select(struct Editor* editor, struct Entity* entity) { if(!entity && editor->selected_entity) // Deselect { - editor->selected_entity->selected_in_editor = false; + editor->selected_entity->flags &= ~EF_SELECTED_IN_EDITOR; editor->selected_entity = NULL; editor_tool_reset(editor); } else if(entity) // Select { + // Deselect already selected entity if(editor->selected_entity && editor->selected_entity != entity) { - editor->selected_entity->selected_in_editor = false; + editor->selected_entity->flags &= ~EF_SELECTED_IN_EDITOR; editor->selected_entity = NULL; } @@ -1211,7 +1212,7 @@ void editor_entity_select(struct Editor* editor, struct Entity* entity) editor_axis_set(editor, EDITOR_AXIS_XZ); editor->draw_cursor_entity = true; } - entity->selected_in_editor = true; + entity->flags |= EF_SELECTED_IN_EDITOR; editor->selected_entity = entity; transform_copy(editor->cursor_entity, editor->selected_entity, false); } @@ -1508,17 +1509,23 @@ bool editor_widget_v3(struct nk_context* context, vec3* value, const char* name_ void editor_show_entity_in_list(struct Editor* editor, struct nk_context* context, struct Scene* scene, struct Entity* entity) { - if(!entity->active) return; + if(!(entity->flags & EF_ACTIVE)) return; nk_layout_row_dynamic(context, 20, 1); - if(nk_selectable_label(context, entity->name, NK_TEXT_ALIGN_LEFT, &entity->selected_in_editor)) + int selected = entity->flags & EF_SELECTED_IN_EDITOR; + if(nk_selectable_label(context, entity->name, NK_TEXT_ALIGN_LEFT, &selected)) { + if(selected) + entity->flags |= EF_SELECTED_IN_EDITOR; + else + entity->flags &= ~EF_SELECTED_IN_EDITOR; + if(editor->selected_entity && editor->selected_entity != entity) editor_entity_select(editor, entity); - else if(editor->selected_entity && editor->selected_entity == entity && !entity->selected_in_editor) + else if(editor->selected_entity && editor->selected_entity == entity && !(entity->flags & EF_SELECTED_IN_EDITOR)) editor_entity_select(editor, NULL); - if(entity->selected_in_editor) + if(entity->flags & EF_SELECTED_IN_EDITOR) { editor->selected_entity = entity; if(!editor->window_property_inspector) editor->window_property_inspector = true; @@ -1594,7 +1601,7 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor* struct Entity* parent_ent = entity->transform.parent; nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Name", NK_TEXT_ALIGN_LEFT); nk_label(context, entity->name, NK_TEXT_ALIGN_RIGHT); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "ID", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%d", entity->id); - nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Selected", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity->selected_in_editor ? "True" : "False"); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Selected", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", (entity->flags & EF_SELECTED_IN_EDITOR) ? "True" : "False"); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Entity Type", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity_type_name_get(entity)); nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Parent Name", NK_TEXT_ALIGN_LEFT); nk_label(context, parent_ent ? parent_ent->name : "NONE", NK_TEXT_ALIGN_RIGHT); diff --git a/src/game/entity.c b/src/game/entity.c index b4951b7..4d92b9c 100755 --- a/src/game/entity.c +++ b/src/game/entity.c @@ -37,9 +37,7 @@ void entity_init(struct Entity* entity, const char* name, struct Entity* parent) entity->name[MAX_ENTITY_NAME_LEN - 1] = '\0'; entity->type = ET_DEFAULT; entity->archetype_index = -1; - entity->active = true; - entity->marked_for_deletion = false; - entity->selected_in_editor = false; + entity->flags = EF_ACTIVE; transform_init(entity, parent); } @@ -49,9 +47,7 @@ void entity_reset(struct Entity * entity, int id) entity->id = id; entity->type = ET_DEFAULT; entity->archetype_index = -1; - entity->active = false; - entity->marked_for_deletion = false; - entity->selected_in_editor = false; + entity->flags = EF_NONE; memset(entity->name, '\0', MAX_ENTITY_NAME_LEN); } @@ -68,7 +64,7 @@ bool entity_write(struct Entity* entity, struct Parser_Object* object, bool writ hashmap_str_set(entity_data, "name", entity->name); hashmap_int_set(entity_data, "type", entity->type); - hashmap_bool_set(entity_data, "active", entity->active); + hashmap_bool_set(entity_data, "active", entity->flags & EF_ACTIVE ? true : false); //if(entity->has_collision) //{ diff --git a/src/game/entity.h b/src/game/entity.h index e17e0de..e09a99e 100755 --- a/src/game/entity.h +++ b/src/game/entity.h @@ -45,6 +45,16 @@ enum Camera_Type CAM_MAX }; +enum Entity_Flags +{ + EF_NONE = 0, + EF_ACTIVE = 1 << 0, + EF_SELECTED_IN_EDITOR = 1 << 1, + EF_MARKED_FOR_DELETION = 1 << 2, + EF_SERIALIZE_IN_SCENE = 1 << 3, + EF_SHOW_IN_EDITOR_SCENE_HIERARCHY = 1 << 4 +}; + struct Transform { vec3 position; @@ -62,10 +72,8 @@ struct Entity int id; int type; int archetype_index; + uchar flags; char name[MAX_ENTITY_NAME_LEN]; - bool marked_for_deletion; - bool active; - bool selected_in_editor; struct Transform transform; }; diff --git a/src/game/player.c b/src/game/player.c index d421600..17e7586 100755 --- a/src/game/player.c +++ b/src/game/player.c @@ -16,9 +16,9 @@ void player_init(struct Player* player, struct Scene* scene) { struct Game_State* game_state = game_state_get(); entity_init(player, "Player", &scene->root_entity); - player->base.active = true; - player->base.id = 1; - player->base.type = ET_PLAYER; + player->base.flags |= EF_ACTIVE; + player->base.id = 1; + player->base.type = ET_PLAYER; struct Hashmap* config = game_state->cvars; player->move_speed = hashmap_int_get(config, "player_move_speed"); @@ -29,7 +29,7 @@ void player_init(struct Player* player, struct Scene* scene) struct Camera* player_camera = &scene->cameras[CAM_GAME]; entity_rename(player_camera, "Player_Camera"); - player_camera->base.active = true; + player_camera->base.flags |= EF_ACTIVE; player_camera->clear_color.x = 0.6f; player_camera->clear_color.y = 0.6f; player_camera->clear_color.z = 0.9f; @@ -54,7 +54,7 @@ void player_init(struct Player* player, struct Scene* scene) void player_destroy(struct Player* player) { entity_reset(player, player->base.id); - player->base.active = false; + player->base.flags = EF_NONE; } void player_update(struct Player* player, struct Scene* scene, float dt) diff --git a/src/game/renderer.c b/src/game/renderer.c index bd9ee35..49a1e3e 100755 --- a/src/game/renderer.c +++ b/src/game/renderer.c @@ -176,7 +176,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene) for(int j = 0; j < MAX_LIGHTS; j++) { struct Light* light = &scene->lights[j]; /* TODO: Cull lights according to camera frustum */ - if(!light->base.active || !light->valid) continue; + if(!(light->base.flags & EF_ACTIVE) || !light->valid) continue; light_count++; vec3 light_pos = { 0, 0, 0 }; @@ -346,7 +346,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene) for(int i = 0; i < MAX_STATIC_MESHES; i++) { struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!mesh->base.active) continue; + if(!(mesh->base.flags & EF_ACTIVE)) continue; struct Model* model = &mesh->model; struct Transform* transform = &mesh->base.transform; int geometry = model->geometry_index; @@ -367,7 +367,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene) for(int i = 0; i < MAX_STATIC_MESHES; i++) { struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!mesh->base.active || (!mesh->collision.collision_shape && !mesh->collision.rigidbody)) continue; + if(!(mesh->base.flags & EF_ACTIVE) || (!mesh->collision.collision_shape && !mesh->collision.rigidbody)) continue; //Get collision mesh and it's props then render it vec3 pos = {0.f}; diff --git a/src/game/scene.c b/src/game/scene.c index 777a378..deb32ac 100755 --- a/src/game/scene.c +++ b/src/game/scene.c @@ -32,7 +32,7 @@ void scene_init(struct Scene* scene) //Initialize the root entity entity_init(&scene->root_entity, "ROOT_ENTITY", NULL); - scene->root_entity.active = true; + scene->root_entity.flags |= EF_ACTIVE; scene->root_entity.id = 0; scene->root_entity.type = ET_ROOT; @@ -62,7 +62,7 @@ void scene_init(struct Scene* scene) { entity_init(&scene->cameras[i], NULL, &scene->root_entity); camera_init(&scene->cameras[i], width, height); - scene->cameras[i].base.active = false; + scene->cameras[i].base.flags &= ~EF_ACTIVE; scene->cameras[i].base.id = i; } @@ -182,7 +182,7 @@ bool scene_save(struct Scene* scene, const char* filename, int directory_type) struct Parser* parser = parser_new(); - //Start by saving the scene configuration information + // Scene configuration struct Parser_Object* scene_config_object = parser_object_new(parser, PO_SCENE_CONFIG); struct Render_Settings* render_settings = &game_state_get()->renderer->settings; struct Hashmap* scene_data = scene_config_object->data; @@ -197,6 +197,10 @@ bool scene_save(struct Scene* scene, const char* filename, int directory_type) hashmap_int_set(scene_data, "debug_draw_mode", render_settings->debug_draw_mode); hashmap_bool_set(scene_data, "debug_draw_physics", render_settings->debug_draw_physics); + // Player + struct Parser_Object* player_object = parser_object_new(parser, PO_PLAYER); + entity_write(&scene->player, player_object, true); + scene_write_entity_list(scene, ET_DEFAULT, parser); scene_write_entity_list(scene, ET_LIGHT, parser); scene_write_entity_list(scene, ET_STATIC_MESH, parser); @@ -253,7 +257,7 @@ void scene_write_entity_list(struct Scene* scene, int entity_type, struct Parser //((char*)entity) += stride * count; ((char*)entity) += stride; - if(entity->active) + if(entity->flags & EF_ACTIVE) { if(entity->archetype_index != -1) { @@ -294,7 +298,7 @@ void scene_destroy(struct Scene* scene) for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++) memset(&scene->entity_archetypes[i][0], '\0', MAX_FILENAME_LEN); player_destroy(&scene->player); entity_reset(&scene->root_entity, 0); - scene->root_entity.active = false; + scene->root_entity.flags &= ~EF_ACTIVE; } void scene_update(struct Scene* scene, float dt) @@ -310,9 +314,9 @@ void scene_post_update(struct Scene* scene) for(int i = 0; i < MAX_ENTITIES; i++) { struct Entity* entity = &scene->entities[i]; - if(!entity->active) continue; + if(!(entity->flags & EF_ACTIVE)) continue; - if(entity->marked_for_deletion) + if(entity->flags & EF_MARKED_FOR_DELETION) { scene_entity_base_remove(scene, entity); continue; @@ -324,9 +328,9 @@ void scene_post_update(struct Scene* scene) for(int i = 0; i < MAX_CAMERAS; i++) { struct Camera* camera = &scene->cameras[i]; - if(!camera->base.active) continue; + if(!(camera->base.flags & EF_ACTIVE)) continue; - if(camera->base.marked_for_deletion) + if(camera->base.flags & EF_MARKED_FOR_DELETION) { scene_camera_remove(scene, camera); continue; @@ -342,9 +346,9 @@ void scene_post_update(struct Scene* scene) for(int i = 0; i < MAX_SOUND_SOURCES; i++) { struct Sound_Source* sound_source = &scene->sound_sources[i]; - if(!sound_source->base.active) continue; + if(!(sound_source->base.flags & EF_ACTIVE)) continue; - if(sound_source->base.marked_for_deletion) + if(sound_source->base.flags & EF_MARKED_FOR_DELETION) { scene_sound_source_remove(scene, sound_source); continue; @@ -362,9 +366,9 @@ void scene_post_update(struct Scene* scene) for(int i = 0; i < MAX_STATIC_MESHES; i++) { struct Static_Mesh* static_mesh = &scene->static_meshes[i]; - if(!static_mesh->base.active) continue; + if(!(static_mesh->base.flags & EF_ACTIVE)) continue; - if(static_mesh->base.marked_for_deletion) + if(static_mesh->base.flags & EF_MARKED_FOR_DELETION) { scene_static_mesh_remove(scene, static_mesh); continue; @@ -389,9 +393,9 @@ void scene_post_update(struct Scene* scene) for(int i = 0; i < MAX_LIGHTS; i++) { struct Light* light = &scene->lights[i]; - if(!light->base.active) continue; + if(!(light->base.flags & EF_ACTIVE)) continue; - if(light->base.marked_for_deletion) + if(light->base.flags & EF_MARKED_FOR_DELETION) { scene_light_remove(scene, light); continue; @@ -403,7 +407,7 @@ void scene_post_update(struct Scene* scene) for(int i = 0; i < MAX_ENTITIES; i++) { struct Entity* entity = &scene->entities[i]; - if(!entity->active) continue; + if(!(entity->flags & EF_ACTIVE)) continue; } if(scene->player.base.transform.is_modified) @@ -420,7 +424,7 @@ struct Entity* scene_entity_create(struct Scene* scene, const char* name, struct for(int i = 0; i < MAX_ENTITIES; i++) { struct Entity* entity = &scene->entities[i]; - if(!entity->active) + if(!(entity->flags & EF_ACTIVE)) { new_entity = entity; break; @@ -448,7 +452,7 @@ struct Light* scene_light_create(struct Scene* scene, const char* name, struct E for(int i = 0; i < MAX_LIGHTS; i++) { struct Light* light = &scene->lights[i]; - if(!light->base.active) + if(!(light->base.flags & EF_ACTIVE)) { new_light = light; break; @@ -476,7 +480,7 @@ struct Camera* scene_camera_create(struct Scene* scene, const char* name, struct for(int i = 0; i < MAX_CAMERAS; i++) { struct Camera* camera = &scene->cameras[i]; - if(!camera->base.active) + if(!(camera->base.flags & EF_ACTIVE)) { new_camera = camera; break; @@ -504,7 +508,7 @@ struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* na for(int i = 0; i < MAX_STATIC_MESHES; i++) { struct Static_Mesh* static_mesh = &scene->static_meshes[i]; - if(!static_mesh->base.active) + if(!(static_mesh->base.flags & EF_ACTIVE)) { new_static_mesh = static_mesh; break; @@ -534,7 +538,7 @@ struct Sound_Source* scene_sound_source_create(struct Scene* scene, const char* for(int i = 0; i < MAX_SOUND_SOURCES; i++) { struct Sound_Source* sound_source = &scene->sound_sources[i]; - if(!sound_source->base.active) + if(!(sound_source->base.flags & EF_ACTIVE)) { new_sound_source = sound_source; break; @@ -589,12 +593,10 @@ void scene_entity_base_remove(struct Scene* scene, struct Entity* entity) { assert(scene && entity && entity->id >= 0); - if(!entity->active) return; + if(!(entity->flags & EF_ACTIVE)) return; transform_destroy(entity); - entity->active = false; - entity->selected_in_editor = false; - entity->marked_for_deletion = false; + entity->flags = EF_NONE; memset(entity->name, '\0', MAX_ENTITY_NAME_LEN); } @@ -781,7 +783,7 @@ void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Re for(int i = 0; i < MAX_STATIC_MESHES; i++) { struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!mesh->base.active) continue; + if(!(mesh->base.flags & EF_ACTIVE)) continue; vec3 abs_pos = { 0.f }; transform_get_absolute_position(mesh, &abs_pos); diff --git a/src/game/transform.c b/src/game/transform.c index fad3982..b6f8951 100755 --- a/src/game/transform.c +++ b/src/game/transform.c @@ -246,7 +246,7 @@ void transform_destroy(struct Entity* entity) for(int i = 0; i < children; i++) { struct Entity* child = transform->children[i]; - child->marked_for_deletion = true; + child->flags |= EF_MARKED_FOR_DELETION; } } diff --git a/todo.txt b/todo.txt index f166640..0d9d6af 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,4 @@ Todo: - - Implement flags that specify whether an entity should be written to file or not for example to avoid writing cameras and player to file - Implment/Test reading/writing scene that has a mixture of default entites and entity archetypes - Serialize player, camera properties to file - Implement behaviour that avoids writing normal entities that do not have children or parent to file to avoid inconsistencies when loading them @@ -332,3 +331,4 @@ Done: * Scene read/write to file with scene file only containing names of entity archetypes * Console command to read/write scene to/from file + * Implemented flags that specify whether an entity should be written to file or not for example to avoid writing cameras and player to file