|
|
|
|
@ -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) |
|
|
|
|
{ |
|
|
|
|
|