diff --git a/data/hashmap_scene.json b/data/hashmap_scene.json index 931931e..1493eec 100644 --- a/data/hashmap_scene.json +++ b/data/hashmap_scene.json @@ -38,7 +38,7 @@ "model_file" : "block2.dae", "rotation" : {"x":0,"y":0,"z":0,"w":0}, "scale" : {"x":5,"y":5,"z":5}, - "grid_pos": {"q":-2,"r":-2,"s":-4}, + "grid_pos": {"q":-2,"r":-2,"s":4}, "use_grid": true }, { @@ -47,7 +47,6 @@ "position" : {"x":0,"y":0,"z":-1}, "rotation" : {"x":0,"y":0,"z":0,"w":0}, "scale" : {"x":300,"y":300,"z":300}, - "grid_pos": {"q":0,"r":0,"s":0}, "use_grid": false } ], diff --git a/src/entity.cpp b/src/entity.cpp index 43650a5..6e6f26c 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -4,67 +4,45 @@ #include "entity.h" +void initEntityRG(Entity& e, rg_shader_program& shader, bool use_normals); +bool initEntityROs(Entity& e); bool convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals, bool use_texture); - bool -entInit(Entity& e, const char* data_dir, rg_shader_program& shader, v3f world_pos) +entInit(Entity& e, const char* data_dir, rg_shader_program& shader, hexgrid& hg) { + e.world_transform = glm::mat4(1.0); + entScale(e, e.scale); uint max_len = 256; // TODO: define max_len for property strings char full_path[max_len]; if (utilConcatPath(full_path, data_dir, e.model_filename, max_len)) { if (meLoadFromFile(e.mesh_group, data_dir, full_path)) { - // initialize the entity's render group - render_group* rg = UTIL_ALLOC(1, render_group); - e.ren_group = rg; - e.ren_group->shader = shader; - rg->draw_indexed = true; - rg->draw_mode = GL_TRIANGLES; - rg->use_normals = e.mesh_group.use_normals; - uint num_meshes = rg->num_objects = e.mesh_group.num_meshes; - rg->render_objects = UTIL_ALLOC(num_meshes, render_object*); - - // apply translation/rotation/scaling - glm::vec3 v3_world(world_pos.x, world_pos.y, world_pos.z); - e.world_transform = glm::mat4(1.0); - entTranslate(e, v3_world); - entScale(e, e.scale); - - for (uint i = 0; i < num_meshes; i++) - { - meMeshInfo* mesh = e.mesh_group.meshes[i]; - uint buffer_len = mesh->num_vertices * 3; - uint index_len = mesh->num_indices; - - render_object* ro = rgAllocateRenderObject(buffer_len, index_len); - rg->render_objects[i] = ro; - - if (ro == nullptr) - return false; - - if (!convertMeshInfo(mesh, ro, rg->use_normals, mesh->use_texture)) { - rgFree(rg); - return false; - } + initEntityRG(e, shader, e.mesh_group.use_normals); - if (mesh->use_texture) { - ro->use_texture = true; - if (!rgInitGLTexture(ro->tex_id, mesh->diffuse_texture)) { - LOG(ERROR) << "Error initializing GL texture\n"; - return false; - } + if (e.use_grid) { + if (!entPositionToGrid(e, hg, e.grid_pos.q, e.grid_pos.r, e.grid_pos.s)) { + LOG(ERROR) << "tried to place entity at invalid grid coord\n"; + goto cleanup; } + } else { + entSetWorldPosition(e, e.translation.x, e.translation.y, e.translation.z); } + + if (!initEntityROs(e)) + goto cleanup; } else { - meFreeMeshGroup(e.mesh_group); - return false; + goto cleanup; } } else { LOG(ERROR) << data_dir << " + " << e.model_filename << " is too long\n"; - return false; + goto cleanup; } return true; + +cleanup: + entFree(e); + return false; } void @@ -74,6 +52,84 @@ entFree(Entity& e) rgFree(e.ren_group); } +bool +entPositionToGrid(Entity& e, hexgrid& hg, int q, int r, int s) +{ + if (e.container_hex) { + e.container_hex->contained_entity = nullptr; + e.container_hex = nullptr; + } + + hex_info* hxi = hgGetSingleHex(hg, q, r, s); + + if (hxi != nullptr) { + e.container_hex = hxi; + hxi->contained_entity = &e; + + v3f pos = hgGetWorldPostion(hg, hxi->hex.q, hxi->hex.r, hxi->hex.s); + entSetWorldPosition(e, pos.x, pos.y, pos.z); + + return true; + } + + return false; +} + +void +entSetWorldPosition(Entity& e, float x, float y, float z) +{ + e.world_transform[3][0] = e.translation.x = x; + e.world_transform[3][1] = e.translation.y = y; + e.world_transform[3][2] = e.translation.z = z; +} + +void +initEntityRG(Entity& e, rg_shader_program& shader, bool use_normals) +{ + render_group* rg = UTIL_ALLOC(1, render_group); + e.ren_group = rg; + e.ren_group->shader = shader; + rg->draw_indexed = true; + rg->draw_mode = GL_TRIANGLES; + rg->use_normals = use_normals; + uint num_meshes = rg->num_objects = e.mesh_group.num_meshes; + rg->render_objects = UTIL_ALLOC(num_meshes, render_object*); +} + +bool +initEntityROs(Entity& e) +{ + render_group* rg = e.ren_group; + + for (uint i = 0; i < e.mesh_group.num_meshes; i++) + { + meMeshInfo* mesh = e.mesh_group.meshes[i]; + uint buffer_len = mesh->num_vertices * 3; + uint index_len = mesh->num_indices; + + render_object* ro = rgAllocateRenderObject(buffer_len, index_len); + rg->render_objects[i] = ro; + + if (ro == nullptr) + return false; + + if (!convertMeshInfo(mesh, ro, rg->use_normals, mesh->use_texture)) { + rgFree(rg); + return false; + } + + if (mesh->use_texture) { + ro->use_texture = true; + if (!rgInitGLTexture(ro->tex_id, mesh->diffuse_texture)) { + LOG(ERROR) << "Error initializing GL texture\n"; + return false; + } + } + } + + return true; +} + bool convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals, bool use_texture) { diff --git a/src/entity.h b/src/entity.h index d9ef74d..a134580 100644 --- a/src/entity.h +++ b/src/entity.h @@ -4,6 +4,7 @@ #include #include +#include "hexgrid.h" #include "mesh.h" #include "render_group.h" @@ -21,18 +22,15 @@ struct Entity glm::vec3 translation; glm::vec4 rotation; - bool use_grid; // NOTE: determines if entity is position with grid_pos or translation - ent_grid_position grid_pos; - meMeshGroup mesh_group; render_group* ren_group; char model_filename[256]; -}; -bool entInit(Entity& e, const char* data_dir, rg_shader_program& shader, v3f world_pos); - -void entFree(Entity& e); + bool use_grid; // NOTE: determines if entity is position with grid_pos or translation + ent_grid_position grid_pos; + hex_info* container_hex; +}; inline void entTranslate(Entity& e, glm::vec3 v) @@ -45,3 +43,11 @@ entScale(Entity& e, glm::vec3 v) { e.world_transform = glm::scale(e.world_transform, v); } + +bool entInit(Entity& e, const char* data_dir, rg_shader_program& shader, hexgrid& hg); + +void entFree(Entity& e); + +bool entPositionToGrid(Entity& e, hexgrid& hg, int q, int r, int s); + +void entSetWorldPosition(Entity& e, float x, float y, float z); diff --git a/src/hexgame.cpp b/src/hexgame.cpp index eb13b8e..5425f54 100644 --- a/src/hexgame.cpp +++ b/src/hexgame.cpp @@ -71,16 +71,11 @@ loadSceneFromJson(game_state* s, render_state* rs) ret = false; } + // NOTE: hexgrid must be initialized before entities to be able to use grid coordinates + // for entity positions if (slParseEntities(sd, gs->entities, gs->entity_count, MAX_ENTITIES)) { for (uint i = 0; i < gs->entity_count; i++) { - Entity& e = gs->entities[i]; - v3f world_pos; - if (e.use_grid) - world_pos = hgGetWorldPostion(gs->grid, e.grid_pos.q, e.grid_pos.r, e.grid_pos.s); - else - world_pos = v3f(e.translation.x, e.translation.y, e.translation.z); - - if (!entInit(e, DATA_DIR, rs->default_shader, world_pos)) { + if (!entInit(gs->entities[i], DATA_DIR, rs->default_shader, gs->grid)) { LOG(ERROR) << "Error initilaizing entity\n"; return false; } diff --git a/src/hexgrid.cpp b/src/hexgrid.cpp index ff002ea..d1a48e8 100644 --- a/src/hexgrid.cpp +++ b/src/hexgrid.cpp @@ -216,6 +216,17 @@ hgGetSingleHex(hexgrid& hg, real32 x, real32 y) return nullptr; } +hex_info* +hgGetSingleHex(hexgrid& hg, int q, int r, int s) +{ + auto it = hg.hex_map.find(Hex(q, r, s)); + + if (it != hg.hex_map.end()) + return &it->second; + + return nullptr; +} + v3f hgGetWorldPostion(hexgrid& hg, int q, int r, int s) { diff --git a/src/hexgrid.h b/src/hexgrid.h index 3c25300..b82d7ca 100644 --- a/src/hexgrid.h +++ b/src/hexgrid.h @@ -44,6 +44,8 @@ struct hex_info real64 YPos; bool selected; std::vector vertices; + + void* contained_entity; }; struct hex_hashfunc @@ -97,6 +99,8 @@ void hgUpdateUVBuffer(hexgrid& hg, render_group* rg); hex_info* hgGetSingleHex(hexgrid& hg, real32 x, real32 y); +hex_info* hgGetSingleHex(hexgrid& hg, int q, int r, int s); + v3f hgGetWorldPostion(hexgrid& hg, int q, int r, int s); void hgResetHexes(hexgrid& hg); diff --git a/src/renderer.cpp b/src/renderer.cpp index 78a0a61..1b43594 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -21,9 +21,9 @@ #define MAX_LIGHTS 10 // NOTE: needs to match the fragment shader source #define DEFAULT_PALETTE_DIR "../data" #define DEFAULT_PALETTE_FILE "palette.png" -#define CLEAR_COL_R 75.f / 255.f -#define CLEAR_COL_G 135.f / 255.f -#define CLEAR_COL_B 135.f / 255.f +#define CLEAR_COL_R 55.f / 255.f +#define CLEAR_COL_G 55.f / 255.f +#define CLEAR_COL_B 55.f / 255.f #define CLEAR_COL_A 1.f #define USE_SECOND_MONITOR 1 diff --git a/src/scene_loader.h b/src/scene_loader.h index 5ff6ce9..9749426 100644 --- a/src/scene_loader.h +++ b/src/scene_loader.h @@ -3,13 +3,11 @@ #include "camera.h" #include "hexgrid.h" -#include "renderer.h" #include "render_group.h" #include "util.h" struct slSceneDoc; -struct render_state; slSceneDoc* slLoadFile(const char* data_dir, const char* scene_file, const char* schema_file);