diff options
Diffstat (limited to 'Source/Graphics/model.cpp')
-rw-r--r-- | Source/Graphics/model.cpp | 2193 |
1 files changed, 1068 insertions, 1125 deletions
diff --git a/Source/Graphics/model.cpp b/Source/Graphics/model.cpp index ca4b61a0..dd93eba1 100644 --- a/Source/Graphics/model.cpp +++ b/Source/Graphics/model.cpp @@ -53,84 +53,81 @@ #include <Timing/intel_gl_perf.h> #include <cmath> -#include <set> +#include <set> //----------------------------------------------------------------------------- -//Functions +// Functions //----------------------------------------------------------------------------- namespace { - void RearrangeVertices(Model& model, const std::vector<int> &new_order){ - std::vector<float> old_vertices = model.vertices; - std::vector<float> old_normals = model.normals; - std::vector<float> old_tex_coords = model.tex_coords; - std::vector<float> old_tex_coords2 = model.tex_coords2; - std::vector<float> old_tangents = model.tangents; - std::vector<float> old_bitangents = model.bitangents; - std::vector<float> old_aux = model.aux; - std::vector<vec4> old_bone_weights = model.bone_weights; - std::vector<vec4> old_bone_ids = model.bone_ids; - - for(unsigned i=0; i<new_order.size(); ++i){ - model.vertices[i*3+0] = old_vertices[new_order[i]*3+0]; - model.vertices[i*3+1] = old_vertices[new_order[i]*3+1]; - model.vertices[i*3+2] = old_vertices[new_order[i]*3+2]; - if(!model.normals.empty()){ - model.normals[i*3+0] = old_normals[new_order[i]*3+0]; - model.normals[i*3+1] = old_normals[new_order[i]*3+1]; - model.normals[i*3+2] = old_normals[new_order[i]*3+2]; - } - if(!model.tex_coords.empty()){ - model.tex_coords[i*2+0] = old_tex_coords[new_order[i]*2+0]; - model.tex_coords[i*2+1] = old_tex_coords[new_order[i]*2+1]; - } - if(!model.tex_coords2.empty()){ - model.tex_coords2[i*2+0] = old_tex_coords2[new_order[i]*2+0]; - model.tex_coords2[i*2+1] = old_tex_coords2[new_order[i]*2+1]; - } - if(!model.tangents.empty()){ - model.tangents[i*3+0] = old_tangents[new_order[i]*3+0]; - model.tangents[i*3+1] = old_tangents[new_order[i]*3+1]; - model.tangents[i*3+2] = old_tangents[new_order[i]*3+2]; - } - if(!model.bitangents.empty()){ - model.bitangents[i*3+0] = old_bitangents[new_order[i]*3+0]; - model.bitangents[i*3+1] = old_bitangents[new_order[i]*3+1]; - model.bitangents[i*3+2] = old_bitangents[new_order[i]*3+2]; - } - if(!model.aux.empty()){ - model.aux[i*3+0] = old_aux[new_order[i]*3+0]; - model.aux[i*3+1] = old_aux[new_order[i]*3+1]; - model.aux[i*3+2] = old_aux[new_order[i]*3+2]; - } - if(!model.bone_weights.empty()){ - model.bone_weights[i] = old_bone_weights[new_order[i]]; - } - if(!model.bone_ids.empty()){ - model.bone_ids[i] = old_bone_ids[new_order[i]]; - } - } - model.ResizeVertices(new_order.size()); - } -} //namespace "" +void RearrangeVertices(Model &model, const std::vector<int> &new_order) { + std::vector<float> old_vertices = model.vertices; + std::vector<float> old_normals = model.normals; + std::vector<float> old_tex_coords = model.tex_coords; + std::vector<float> old_tex_coords2 = model.tex_coords2; + std::vector<float> old_tangents = model.tangents; + std::vector<float> old_bitangents = model.bitangents; + std::vector<float> old_aux = model.aux; + std::vector<vec4> old_bone_weights = model.bone_weights; + std::vector<vec4> old_bone_ids = model.bone_ids; + + for (unsigned i = 0; i < new_order.size(); ++i) { + model.vertices[i * 3 + 0] = old_vertices[new_order[i] * 3 + 0]; + model.vertices[i * 3 + 1] = old_vertices[new_order[i] * 3 + 1]; + model.vertices[i * 3 + 2] = old_vertices[new_order[i] * 3 + 2]; + if (!model.normals.empty()) { + model.normals[i * 3 + 0] = old_normals[new_order[i] * 3 + 0]; + model.normals[i * 3 + 1] = old_normals[new_order[i] * 3 + 1]; + model.normals[i * 3 + 2] = old_normals[new_order[i] * 3 + 2]; + } + if (!model.tex_coords.empty()) { + model.tex_coords[i * 2 + 0] = old_tex_coords[new_order[i] * 2 + 0]; + model.tex_coords[i * 2 + 1] = old_tex_coords[new_order[i] * 2 + 1]; + } + if (!model.tex_coords2.empty()) { + model.tex_coords2[i * 2 + 0] = old_tex_coords2[new_order[i] * 2 + 0]; + model.tex_coords2[i * 2 + 1] = old_tex_coords2[new_order[i] * 2 + 1]; + } + if (!model.tangents.empty()) { + model.tangents[i * 3 + 0] = old_tangents[new_order[i] * 3 + 0]; + model.tangents[i * 3 + 1] = old_tangents[new_order[i] * 3 + 1]; + model.tangents[i * 3 + 2] = old_tangents[new_order[i] * 3 + 2]; + } + if (!model.bitangents.empty()) { + model.bitangents[i * 3 + 0] = old_bitangents[new_order[i] * 3 + 0]; + model.bitangents[i * 3 + 1] = old_bitangents[new_order[i] * 3 + 1]; + model.bitangents[i * 3 + 2] = old_bitangents[new_order[i] * 3 + 2]; + } + if (!model.aux.empty()) { + model.aux[i * 3 + 0] = old_aux[new_order[i] * 3 + 0]; + model.aux[i * 3 + 1] = old_aux[new_order[i] * 3 + 1]; + model.aux[i * 3 + 2] = old_aux[new_order[i] * 3 + 2]; + } + if (!model.bone_weights.empty()) { + model.bone_weights[i] = old_bone_weights[new_order[i]]; + } + if (!model.bone_ids.empty()) { + model.bone_ids[i] = old_bone_ids[new_order[i]]; + } + } + model.ResizeVertices(new_order.size()); +} +} // namespace -//Initialize model +// Initialize model Model::Model() -:vbo_loaded(false), - vbo_enabled(false), - texel_density(1.0f), - average_triangle_edge_length(1.0f), - path("DEFAULT") -{ + : vbo_loaded(false), + vbo_enabled(false), + texel_density(1.0f), + average_triangle_edge_length(1.0f), + path("DEFAULT") { } -Model::Model( const Model © ) -{ - (*this)=copy; +Model::Model(const Model ©) { + (*this) = copy; } -Model& Model::operator=( const Model © ) -{ +Model &Model::operator=(const Model ©) { vbo_loaded = false; vbo_enabled = false; @@ -165,20 +162,19 @@ Model& Model::operator=( const Model © ) return (*this); } - void Model::WriteToFile(FILE *file) { int count; - count = vertices.size()/3; + count = vertices.size() / 3; fwrite(&count, sizeof(int), 1, file); - fwrite(&vertices.front(), sizeof(GLfloat), count*3, file); - fwrite(&normals.front(), sizeof(GLfloat), count*3, file); - fwrite(&tangents.front(), sizeof(GLfloat), count*3, file); - fwrite(&bitangents.front(), sizeof(GLfloat), count*3, file); - fwrite(&tex_coords.front(), sizeof(GLfloat), count*2, file); + fwrite(&vertices.front(), sizeof(GLfloat), count * 3, file); + fwrite(&normals.front(), sizeof(GLfloat), count * 3, file); + fwrite(&tangents.front(), sizeof(GLfloat), count * 3, file); + fwrite(&bitangents.front(), sizeof(GLfloat), count * 3, file); + fwrite(&tex_coords.front(), sizeof(GLfloat), count * 2, file); - count = faces.size()/3; + count = faces.size() / 3; fwrite(&count, sizeof(int), 1, file); - fwrite(&faces.front(), sizeof(GLfloat), count*3, file); + fwrite(&faces.front(), sizeof(GLfloat), count * 3, file); fwrite(&face_normals.front(), sizeof(vec3), count, file); fwrite(&precollapse_num_vertices, sizeof(int), 1, file); @@ -189,12 +185,12 @@ void Model::WriteToFile(FILE *file) { fwrite(&count, sizeof(int), 1, file); fwrite(&optimize_vert_reorder.front(), sizeof(int), count, file); - count = tex_coords2.size()/2; + count = tex_coords2.size() / 2; fwrite(&count, sizeof(int), 1, file); - if (count>0) { - fwrite(&tex_coords2.front(), sizeof(GLfloat), count*2, file); + if (count > 0) { + fwrite(&tex_coords2.front(), sizeof(GLfloat), count * 2, file); } - + fwrite(&min_coords, sizeof(vec3), 1, file); fwrite(&max_coords, sizeof(vec3), 1, file); fwrite(¢er_coords, sizeof(vec3), 1, file); @@ -206,19 +202,18 @@ void Model::WriteToFile(FILE *file) { fwrite(&average_triangle_edge_length, sizeof(float), 1, file); } -void Model::ReadFromFile(FILE *file) -{ +void Model::ReadFromFile(FILE *file) { int count; fread(&count, sizeof(int), 1, file); ResizeVertices(count); - fread(&vertices.front(), sizeof(GLfloat), count*3, file); - fread(&normals.front(), sizeof(GLfloat), count*3, file); - fread(&tangents.front(), sizeof(GLfloat), count*3, file); - fread(&bitangents.front(), sizeof(GLfloat), count*3, file); - fread(&tex_coords.front(), sizeof(GLfloat), count*2, file); + fread(&vertices.front(), sizeof(GLfloat), count * 3, file); + fread(&normals.front(), sizeof(GLfloat), count * 3, file); + fread(&tangents.front(), sizeof(GLfloat), count * 3, file); + fread(&bitangents.front(), sizeof(GLfloat), count * 3, file); + fread(&tex_coords.front(), sizeof(GLfloat), count * 2, file); fread(&count, sizeof(int), 1, file); ResizeFaces(count); - fread(&faces.front(), sizeof(GLfloat), count*3, file); + fread(&faces.front(), sizeof(GLfloat), count * 3, file); fread(&face_normals.front(), sizeof(vec3), count, file); fread(&precollapse_num_vertices, sizeof(int), 1, file); @@ -232,10 +227,10 @@ void Model::ReadFromFile(FILE *file) fread(&count, sizeof(int), 1, file); if (count > 0) { - tex_coords2.resize(count*2); - fread(&tex_coords2.front(), sizeof(GLfloat), count*2, file); + tex_coords2.resize(count * 2); + fread(&tex_coords2.front(), sizeof(GLfloat), count * 2, file); } - + fread(&min_coords, sizeof(vec3), 1, file); fread(&max_coords, sizeof(vec3), 1, file); fread(¢er_coords, sizeof(vec3), 1, file); @@ -269,8 +264,7 @@ void Model::Dispose() { optimize_vert_reorder.clear(); precollapse_vert_reorder.clear(); - if(vbo_enabled&&vbo_loaded) - { + if (vbo_enabled && vbo_loaded) { VBO_vertices.Dispose(); VBO_tex_coords.Dispose(); VBO_normals.Dispose(); @@ -283,32 +277,32 @@ void Model::Dispose() { vbo_loaded = false; } -//Dispose of model -Model::~Model() { +// Dispose of model +Model::~Model() { Dispose(); } -float StaticCalcTexelDensity(const std::vector<float> &vertices, const std::vector<float> &tex_coords, const std::vector<unsigned> &faces){ +float StaticCalcTexelDensity(const std::vector<float> &vertices, const std::vector<float> &tex_coords, const std::vector<unsigned> &faces) { float total_tex = 0.0f; float total_vert = 0.0f; int next; - for (int i=0, len=faces.size()/3; i<len; i++) { + for (int i = 0, len = faces.size() / 3; i < len; i++) { int face_vertex_index[3]; const float *vert[3]; const float *tc[3]; - for(int j=0; j<3; ++j) { - face_vertex_index[j] = faces[i*3+j]; - vert[j] = &vertices[face_vertex_index[j]*3]; - tc[j] = &tex_coords[face_vertex_index[j]*2]; - } - for(int j=0; j<3; j++) { - next = (j+1)%3; - float tex_distance = sqrtf( square(tc[j][0] - tc[next][0]) + - square(tc[j][1] - tc[next][1])); - float vert_distance = sqrtf( square(vert[j][0] - vert[next][0]) + - square(vert[j][1] - vert[next][1]) + - square(vert[j][2] - vert[next][2])); - if(vert_distance != 0.0f){ + for (int j = 0; j < 3; ++j) { + face_vertex_index[j] = faces[i * 3 + j]; + vert[j] = &vertices[face_vertex_index[j] * 3]; + tc[j] = &tex_coords[face_vertex_index[j] * 2]; + } + for (int j = 0; j < 3; j++) { + next = (j + 1) % 3; + float tex_distance = sqrtf(square(tc[j][0] - tc[next][0]) + + square(tc[j][1] - tc[next][1])); + float vert_distance = sqrtf(square(vert[j][0] - vert[next][0]) + + square(vert[j][1] - vert[next][1]) + + square(vert[j][2] - vert[next][2])); + if (vert_distance != 0.0f) { total_tex += tex_distance; total_vert += vert_distance; } @@ -326,7 +320,7 @@ struct ObjFileStats { int num_tex; int num_vert; int num_face; - int objects; //Number of objects specified in the file, for this game this should only be 1 + int objects; // Number of objects specified in the file, for this game this should only be 1 }; bool GetObjFileStats(std::string rel_path, ObjFileStats &stats, bool file_necessary) { @@ -337,11 +331,11 @@ bool GetObjFileStats(std::string rel_path, ObjFileStats &stats, bool file_necess stats.objects = 0; char abs_path[kPathSize]; - FindFilePath(rel_path.c_str(), abs_path, kPathSize, kAnyPath, file_necessary); - FILE *fp = my_fopen(abs_path,"r"); + FindFilePath(rel_path.c_str(), abs_path, kPathSize, kAnyPath, file_necessary); + FILE *fp = my_fopen(abs_path, "r"); - if(!fp){ - if(file_necessary) { + if (!fp) { + if (file_necessary) { FatalError("Error", "Could not open file fs \"%s\"", rel_path.c_str()); } else { return false; @@ -349,25 +343,24 @@ bool GetObjFileStats(std::string rel_path, ObjFileStats &stats, bool file_necess } char buffer[256]; - while(!feof(fp)) - { - memset(buffer,0,200); - fgets(buffer,256,fp); + while (!feof(fp)) { + memset(buffer, 0, 200); + fgets(buffer, 256, fp); - if( strncmp("vn ",buffer,3) == 0 ) + if (strncmp("vn ", buffer, 3) == 0) ++stats.num_normal; - else if( strncmp("vt ",buffer,3) == 0 ) + else if (strncmp("vt ", buffer, 3) == 0) ++stats.num_tex; - else if( strncmp("v ",buffer,2) == 0 ) + else if (strncmp("v ", buffer, 2) == 0) ++stats.num_vert; - else if( strncmp("f ",buffer,2) == 0 ) + else if (strncmp("f ", buffer, 2) == 0) ++stats.num_face; - else if( strncmp("o ",buffer,2) == 0 ) + else if (strncmp("o ", buffer, 2) == 0) ++stats.objects; } - //There is always at least one object in a file. - if( stats.objects == 0 ) + // There is always at least one object in a file. + if (stats.objects == 0) stats.objects = 1; fclose(fp); @@ -386,23 +379,23 @@ struct TempModel { std::vector<GLuint> tex_indices; std::vector<GLuint> tex_indices2; std::vector<GLuint> norm_indices; - unsigned int vc,nc,tc,fc; + unsigned int vc, nc, tc, fc; }; void LoadTempModel(std::string rel_path, TempModel &temp, const ObjFileStats &obj_stats) { - temp.vertices.resize(obj_stats.num_vert*3); - temp.normals.resize(obj_stats.num_normal*3); - temp.tangents.resize(obj_stats.num_tex*3); - temp.bitangents.resize(obj_stats.num_tex*3); - temp.tex_coords.resize(obj_stats.num_tex*2); + temp.vertices.resize(obj_stats.num_vert * 3); + temp.normals.resize(obj_stats.num_normal * 3); + temp.tangents.resize(obj_stats.num_tex * 3); + temp.bitangents.resize(obj_stats.num_tex * 3); + temp.tex_coords.resize(obj_stats.num_tex * 2); temp.tex_coords2.resize(0); - temp.vert_indices.resize(obj_stats.num_face*6); - temp.tex_indices.resize(obj_stats.num_face*6); - temp.norm_indices.resize(obj_stats.num_face*6); + temp.vert_indices.resize(obj_stats.num_face * 6); + temp.tex_indices.resize(obj_stats.num_face * 6); + temp.norm_indices.resize(obj_stats.num_face * 6); char abs_path[kPathSize]; - FindFilePath(rel_path.c_str(), abs_path, kPathSize, kAnyPath); - FILE *fp = my_fopen(abs_path,"r"); + FindFilePath(rel_path.c_str(), abs_path, kPathSize, kAnyPath); + FILE *fp = my_fopen(abs_path, "r"); int num_read; @@ -412,120 +405,112 @@ void LoadTempModel(std::string rel_path, TempModel &temp, const ObjFileStats &ob temp.vc = 0; char buffer[256]; - while(!feof(fp)) - { - memset(buffer,0,255); - fgets(buffer,256,fp); - - if( strncmp("vn ",buffer,3) == 0 ) - { - sscanf((buffer+2),"%f%f%f", - &temp.normals[temp.nc*3+0], - &temp.normals[temp.nc*3+1], - &temp.normals[temp.nc*3+2]); + while (!feof(fp)) { + memset(buffer, 0, 255); + fgets(buffer, 256, fp); + + if (strncmp("vn ", buffer, 3) == 0) { + sscanf((buffer + 2), "%f%f%f", + &temp.normals[temp.nc * 3 + 0], + &temp.normals[temp.nc * 3 + 1], + &temp.normals[temp.nc * 3 + 2]); ++temp.nc; - } - else if( strncmp("vt ",buffer,3) == 0 ) - { - sscanf((buffer+2),"%f%f", - &temp.tex_coords[temp.tc*2+0], - &temp.tex_coords[temp.tc*2+1]); + } else if (strncmp("vt ", buffer, 3) == 0) { + sscanf((buffer + 2), "%f%f", + &temp.tex_coords[temp.tc * 2 + 0], + &temp.tex_coords[temp.tc * 2 + 1]); ++temp.tc; - } - else if( strncmp("v ",buffer,2) == 0 ) - { - sscanf((buffer+1),"%f%f%f", - &temp.vertices[temp.vc*3+0], - &temp.vertices[temp.vc*3+1], - &temp.vertices[temp.vc*3+2]); + } else if (strncmp("v ", buffer, 2) == 0) { + sscanf((buffer + 1), "%f%f%f", + &temp.vertices[temp.vc * 3 + 0], + &temp.vertices[temp.vc * 3 + 1], + &temp.vertices[temp.vc * 3 + 2]); ++temp.vc; - } - else if( strncmp("f ",buffer,2) == 0 ) - { - if(obj_stats.num_tex&&obj_stats.num_normal) { - num_read = sscanf(buffer+1,"%u/%u/%u %u/%u/%u %u/%u/%u %u/%u/%u", - &temp.vert_indices[temp.fc*3+0], - &temp.tex_indices[temp.fc*3+0], - &temp.norm_indices[temp.fc*3+0], - - &temp.vert_indices[temp.fc*3+1], - &temp.tex_indices[temp.fc*3+1], - &temp.norm_indices[temp.fc*3+1], - - &temp.vert_indices[temp.fc*3+2], - &temp.tex_indices[temp.fc*3+2], - &temp.norm_indices[temp.fc*3+2], - - &temp.vert_indices[temp.fc*3+3], - &temp.tex_indices[temp.fc*3+3], - &temp.norm_indices[temp.fc*3+3]); - if(num_read == 12) { - temp.vert_indices[temp.fc*3+4] = temp.vert_indices[temp.fc*3+0]; - temp.tex_indices[temp.fc*3+4] = temp.tex_indices[temp.fc*3+0]; - temp.norm_indices[temp.fc*3+4] = temp.norm_indices[temp.fc*3+0]; - - temp.vert_indices[temp.fc*3+5] = temp.vert_indices[temp.fc*3+2]; - temp.tex_indices[temp.fc*3+5] = temp.tex_indices[temp.fc*3+2]; - temp.norm_indices[temp.fc*3+5] = temp.norm_indices[temp.fc*3+2]; + } else if (strncmp("f ", buffer, 2) == 0) { + if (obj_stats.num_tex && obj_stats.num_normal) { + num_read = sscanf(buffer + 1, "%u/%u/%u %u/%u/%u %u/%u/%u %u/%u/%u", + &temp.vert_indices[temp.fc * 3 + 0], + &temp.tex_indices[temp.fc * 3 + 0], + &temp.norm_indices[temp.fc * 3 + 0], + + &temp.vert_indices[temp.fc * 3 + 1], + &temp.tex_indices[temp.fc * 3 + 1], + &temp.norm_indices[temp.fc * 3 + 1], + + &temp.vert_indices[temp.fc * 3 + 2], + &temp.tex_indices[temp.fc * 3 + 2], + &temp.norm_indices[temp.fc * 3 + 2], + + &temp.vert_indices[temp.fc * 3 + 3], + &temp.tex_indices[temp.fc * 3 + 3], + &temp.norm_indices[temp.fc * 3 + 3]); + if (num_read == 12) { + temp.vert_indices[temp.fc * 3 + 4] = temp.vert_indices[temp.fc * 3 + 0]; + temp.tex_indices[temp.fc * 3 + 4] = temp.tex_indices[temp.fc * 3 + 0]; + temp.norm_indices[temp.fc * 3 + 4] = temp.norm_indices[temp.fc * 3 + 0]; + + temp.vert_indices[temp.fc * 3 + 5] = temp.vert_indices[temp.fc * 3 + 2]; + temp.tex_indices[temp.fc * 3 + 5] = temp.tex_indices[temp.fc * 3 + 2]; + temp.norm_indices[temp.fc * 3 + 5] = temp.norm_indices[temp.fc * 3 + 2]; temp.fc++; } } else if (obj_stats.num_normal) { - num_read = sscanf(buffer+1,"%u//%u %u//%u %u//%u %u//%u", - &temp.vert_indices[temp.fc*3+0], - &temp.norm_indices[temp.fc*3+0], + num_read = sscanf(buffer + 1, "%u//%u %u//%u %u//%u %u//%u", + &temp.vert_indices[temp.fc * 3 + 0], + &temp.norm_indices[temp.fc * 3 + 0], - &temp.vert_indices[temp.fc*3+1], - &temp.norm_indices[temp.fc*3+1], + &temp.vert_indices[temp.fc * 3 + 1], + &temp.norm_indices[temp.fc * 3 + 1], - &temp.vert_indices[temp.fc*3+2], - &temp.norm_indices[temp.fc*3+2], + &temp.vert_indices[temp.fc * 3 + 2], + &temp.norm_indices[temp.fc * 3 + 2], - &temp.vert_indices[temp.fc*3+3], - &temp.norm_indices[temp.fc*3+3]); + &temp.vert_indices[temp.fc * 3 + 3], + &temp.norm_indices[temp.fc * 3 + 3]); - if(num_read == 8) { - temp.vert_indices[temp.fc*3+4] = temp.vert_indices[temp.fc*3+0]; - temp.norm_indices[temp.fc*3+4] = temp.norm_indices[temp.fc*3+0]; + if (num_read == 8) { + temp.vert_indices[temp.fc * 3 + 4] = temp.vert_indices[temp.fc * 3 + 0]; + temp.norm_indices[temp.fc * 3 + 4] = temp.norm_indices[temp.fc * 3 + 0]; - temp.vert_indices[temp.fc*3+5] = temp.vert_indices[temp.fc*3+2]; - temp.norm_indices[temp.fc*3+5] = temp.norm_indices[temp.fc*3+2]; + temp.vert_indices[temp.fc * 3 + 5] = temp.vert_indices[temp.fc * 3 + 2]; + temp.norm_indices[temp.fc * 3 + 5] = temp.norm_indices[temp.fc * 3 + 2]; temp.fc++; } } else if (obj_stats.num_tex) { - num_read = sscanf(buffer+1,"%u/%u %u/%u %u/%u %u/%u", - &temp.vert_indices[temp.fc*3+0], - &temp.tex_indices[temp.fc*3+0], + num_read = sscanf(buffer + 1, "%u/%u %u/%u %u/%u %u/%u", + &temp.vert_indices[temp.fc * 3 + 0], + &temp.tex_indices[temp.fc * 3 + 0], - &temp.vert_indices[temp.fc*3+1], - &temp.tex_indices[temp.fc*3+1], + &temp.vert_indices[temp.fc * 3 + 1], + &temp.tex_indices[temp.fc * 3 + 1], - &temp.vert_indices[temp.fc*3+2], - &temp.tex_indices[temp.fc*3+2], + &temp.vert_indices[temp.fc * 3 + 2], + &temp.tex_indices[temp.fc * 3 + 2], - &temp.vert_indices[temp.fc*3+3], - &temp.tex_indices[temp.fc*3+3]); + &temp.vert_indices[temp.fc * 3 + 3], + &temp.tex_indices[temp.fc * 3 + 3]); - if(num_read == 8) { - temp.vert_indices[temp.fc*3+4] = temp.vert_indices[temp.fc*3+0]; - temp.tex_indices[temp.fc*3+4] = temp.tex_indices[temp.fc*3+0]; + if (num_read == 8) { + temp.vert_indices[temp.fc * 3 + 4] = temp.vert_indices[temp.fc * 3 + 0]; + temp.tex_indices[temp.fc * 3 + 4] = temp.tex_indices[temp.fc * 3 + 0]; - temp.vert_indices[temp.fc*3+5] = temp.vert_indices[temp.fc*3+2]; - temp.tex_indices[temp.fc*3+5] = temp.tex_indices[temp.fc*3+2]; + temp.vert_indices[temp.fc * 3 + 5] = temp.vert_indices[temp.fc * 3 + 2]; + temp.tex_indices[temp.fc * 3 + 5] = temp.tex_indices[temp.fc * 3 + 2]; temp.fc++; } } else { - num_read = sscanf(buffer+1,"%u %u %u %u", - &temp.vert_indices[temp.fc*3+0], - &temp.vert_indices[temp.fc*3+1], - &temp.vert_indices[temp.fc*3+2], - &temp.vert_indices[temp.fc*3+3]); - - if(num_read == 4) { - temp.vert_indices[temp.fc*3+4] = temp.vert_indices[temp.fc*3+0]; - temp.vert_indices[temp.fc*3+5] = temp.vert_indices[temp.fc*3+2]; + num_read = sscanf(buffer + 1, "%u %u %u %u", + &temp.vert_indices[temp.fc * 3 + 0], + &temp.vert_indices[temp.fc * 3 + 1], + &temp.vert_indices[temp.fc * 3 + 2], + &temp.vert_indices[temp.fc * 3 + 3]); + + if (num_read == 4) { + temp.vert_indices[temp.fc * 3 + 4] = temp.vert_indices[temp.fc * 3 + 0]; + temp.vert_indices[temp.fc * 3 + 5] = temp.vert_indices[temp.fc * 3 + 2]; temp.fc++; } } @@ -536,62 +521,54 @@ void LoadTempModel(std::string rel_path, TempModel &temp, const ObjFileStats &ob bool vert_index_error = false; bool tex_index_error = false; - bool norm_index_error = false; + bool norm_index_error = false; - for (unsigned j = 0;j<temp.fc*3;j++){ - - if( temp.vert_indices[j] > 0 ) + for (unsigned j = 0; j < temp.fc * 3; j++) { + if (temp.vert_indices[j] > 0) temp.vert_indices[j]--; - if( temp.tex_indices[j] > 0 ) + if (temp.tex_indices[j] > 0) temp.tex_indices[j]--; - if( temp.norm_indices[j] > 0 ) + if (temp.norm_indices[j] > 0) temp.norm_indices[j]--; - - if( temp.vert_indices[j] > temp.vertices.size()/3 && temp.vert_indices[j] != 0) - { - temp.vert_indices[j] = 0; //This is better than NaN data or a segfault. + if (temp.vert_indices[j] > temp.vertices.size() / 3 && temp.vert_indices[j] != 0) { + temp.vert_indices[j] = 0; // This is better than NaN data or a segfault. vert_index_error = true; } - if( temp.tex_indices[j] > temp.tex_coords.size()/2 && temp.tex_indices[j] != 0) - { + if (temp.tex_indices[j] > temp.tex_coords.size() / 2 && temp.tex_indices[j] != 0) { temp.tex_indices[j] = 0; tex_index_error = true; } - if( temp.norm_indices[j] > temp.normals.size()/3 && temp.norm_indices[j] != 0 ) - { + if (temp.norm_indices[j] > temp.normals.size() / 3 && temp.norm_indices[j] != 0) { temp.norm_indices[j] = 0; norm_index_error = true; } } - if( vert_index_error ) - { + if (vert_index_error) { LOGE << "Error when loading: " << rel_path << " face (v) indices are higher than parsed data, file is probably corrupt." << std::endl; } - if( tex_index_error ) - { + if (tex_index_error) { LOGE << "Error when loading: " << rel_path << " face (vt) indices are higher than parsed data, file is probably corrupt." << std::endl; } - if( norm_index_error ) - { + if (norm_index_error) { LOGE << "Error when loading: " << rel_path << " face (vn) indices are higher than parsed data, file is probably corrupt." << std::endl; } } void LoadSecondUVs(std::string name, TempModel &temp, const ObjFileStats &obj_stats) { - temp.tex_coords2.resize(obj_stats.num_tex*2); - temp.tex_indices2.resize(obj_stats.num_face*6); - + temp.tex_coords2.resize(obj_stats.num_tex * 2); + temp.tex_indices2.resize(obj_stats.num_face * 6); + char abs_path[kPathSize]; - FindFilePath(name.c_str(), abs_path, kPathSize, kDataPaths|kModPaths); - FILE *fp = my_fopen(abs_path,"r"); + FindFilePath(name.c_str(), abs_path, kPathSize, kDataPaths | kModPaths); + FILE *fp = my_fopen(abs_path, "r"); int tc2 = 0; int fc2 = 0; @@ -599,59 +576,58 @@ void LoadSecondUVs(std::string name, TempModel &temp, const ObjFileStats &obj_st int num_read; char buffer[256]; - while(!feof(fp)) - { - memset(buffer,0,255); - fgets(buffer,256,fp); - - if( strncmp("vt ",buffer,3) == 0 ) { - sscanf((buffer+2),"%f%f", - &temp.tex_coords2[tc2*2+0], - &temp.tex_coords2[tc2*2+1]); + while (!feof(fp)) { + memset(buffer, 0, 255); + fgets(buffer, 256, fp); + + if (strncmp("vt ", buffer, 3) == 0) { + sscanf((buffer + 2), "%f%f", + &temp.tex_coords2[tc2 * 2 + 0], + &temp.tex_coords2[tc2 * 2 + 1]); ++tc2; - } else if( strncmp("f ",buffer,2) == 0 ) { - if(obj_stats.num_tex&&obj_stats.num_normal) { - num_read = sscanf(buffer+1,"%u/%u/%u %u/%u/%u %u/%u/%u %u/%u/%u", - &trash, - &temp.tex_indices2[fc2*3+0], - &trash, - - &trash, - &temp.tex_indices2[fc2*3+1], - &trash, - - &trash, - &temp.tex_indices2[fc2*3+2], - &trash, - - &trash, - &temp.tex_indices2[fc2*3+3], - &trash); - if(num_read == 12) { - temp.tex_indices2[fc2*3+4] = temp.tex_indices2[fc2*3+0]; - - temp.tex_indices2[fc2*3+5] = temp.tex_indices2[fc2*3+2]; - + } else if (strncmp("f ", buffer, 2) == 0) { + if (obj_stats.num_tex && obj_stats.num_normal) { + num_read = sscanf(buffer + 1, "%u/%u/%u %u/%u/%u %u/%u/%u %u/%u/%u", + &trash, + &temp.tex_indices2[fc2 * 3 + 0], + &trash, + + &trash, + &temp.tex_indices2[fc2 * 3 + 1], + &trash, + + &trash, + &temp.tex_indices2[fc2 * 3 + 2], + &trash, + + &trash, + &temp.tex_indices2[fc2 * 3 + 3], + &trash); + if (num_read == 12) { + temp.tex_indices2[fc2 * 3 + 4] = temp.tex_indices2[fc2 * 3 + 0]; + + temp.tex_indices2[fc2 * 3 + 5] = temp.tex_indices2[fc2 * 3 + 2]; + ++fc2; } } else if (obj_stats.num_tex) { - num_read = sscanf(buffer+1,"%u/%u %u/%u %u/%u %u/%u", - &trash, - &temp.tex_indices2[fc2*3+0], + num_read = sscanf(buffer + 1, "%u/%u %u/%u %u/%u %u/%u", + &trash, + &temp.tex_indices2[fc2 * 3 + 0], - &trash, - &temp.tex_indices2[fc2*3+1], + &trash, + &temp.tex_indices2[fc2 * 3 + 1], - &trash, - &temp.tex_indices2[fc2*3+2], + &trash, + &temp.tex_indices2[fc2 * 3 + 2], - &trash, - &temp.tex_indices2[fc2*3+3]); + &trash, + &temp.tex_indices2[fc2 * 3 + 3]); - if(num_read == 8) { - temp.tex_indices2[fc2*3+4] = temp.tex_indices2[fc2*3+0]; + if (num_read == 8) { + temp.tex_indices2[fc2 * 3 + 4] = temp.tex_indices2[fc2 * 3 + 0]; - temp.tex_indices2[fc2*3+5] = temp.tex_indices2[fc2*3+2]; + temp.tex_indices2[fc2 * 3 + 5] = temp.tex_indices2[fc2 * 3 + 2]; ++fc2; } @@ -660,7 +636,7 @@ void LoadSecondUVs(std::string name, TempModel &temp, const ObjFileStats &obj_st } } - for (int j = 0;j<fc2*3;j++){ + for (int j = 0; j < fc2 * 3; j++) { temp.tex_indices2[j]--; } @@ -674,25 +650,25 @@ void Model::SaveObj(std::string name) { my_ofstream_open(file, abs_path); unsigned index = 0; - for(int i=0, len=vertices.size()/3; i<len; ++i){ + for (int i = 0, len = vertices.size() / 3; i < len; ++i) { file << "v "; file << vertices[index++] << " "; file << vertices[index++] << " "; file << vertices[index++] << "\n"; } - if(!tex_coords.empty()){ + if (!tex_coords.empty()) { index = 0; - for(int i=0, len=vertices.size()/3; i<len; ++i){ + for (int i = 0, len = vertices.size() / 3; i < len; ++i) { file << "vt "; file << tex_coords[index++] << " "; file << tex_coords[index++] << "\n"; } } - if(!normals.empty()){ + if (!normals.empty()) { index = 0; - for(int i=0, len=vertices.size()/3; i<len; ++i){ + for (int i = 0, len = vertices.size() / 3; i < len; ++i) { file << "vn "; file << normals[index++] << " "; file << normals[index++] << " "; @@ -702,31 +678,31 @@ void Model::SaveObj(std::string name) { index = 0; - if(tex_coords.empty() && normals.empty()){ - for(int i=0, len=faces.size()/3; i<len; ++i){ + if (tex_coords.empty() && normals.empty()) { + for (int i = 0, len = faces.size() / 3; i < len; ++i) { file << "f "; - file << faces[index++]+1 << " "; - file << faces[index++]+1 << " "; - file << faces[index++]+1 << "\n"; + file << faces[index++] + 1 << " "; + file << faces[index++] + 1 << " "; + file << faces[index++] + 1 << "\n"; } - } else if(tex_coords.empty() || normals.empty()){ - for(int i=0, len=faces.size()/3; i<len; ++i){ + } else if (tex_coords.empty() || normals.empty()) { + for (int i = 0, len = faces.size() / 3; i < len; ++i) { file << "f "; - file << faces[index]+1 << "/" << faces[index]+1 << " "; + file << faces[index] + 1 << "/" << faces[index] + 1 << " "; index++; - file << faces[index]+1 << "/" << faces[index]+1 << " "; + file << faces[index] + 1 << "/" << faces[index] + 1 << " "; index++; - file << faces[index]+1 << "/" << faces[index]+1 << "\n"; + file << faces[index] + 1 << "/" << faces[index] + 1 << "\n"; index++; } } else { - for(int i=0, len=faces.size()/3; i<len; ++i){ + for (int i = 0, len = faces.size() / 3; i < len; ++i) { file << "f "; - file << faces[index]+1 << "/" << faces[index]+1 << "/" << faces[index]+1 << " "; + file << faces[index] + 1 << "/" << faces[index] + 1 << "/" << faces[index] + 1 << " "; index++; - file << faces[index]+1 << "/" << faces[index]+1 << "/" << faces[index]+1 << " "; + file << faces[index] + 1 << "/" << faces[index] + 1 << "/" << faces[index] + 1 << " "; index++; - file << faces[index]+1 << "/" << faces[index]+1 << "/" << faces[index]+1 << "\n"; + file << faces[index] + 1 << "/" << faces[index] + 1 << "/" << faces[index] + 1 << "\n"; index++; } } @@ -743,69 +719,64 @@ int Model::SimpleLoadTriangleCutObj(const std::string &name_to_load) { TempModel temp; LoadTempModel(name_to_load, temp, obj_stats); - //Check if the obj file has more than one model object packed into it. - if( obj_stats.objects == 1 ) - { + // Check if the obj file has more than one model object packed into it. + if (obj_stats.objects == 1) { int num_faces = temp.fc; - int num_vertices = num_faces*3; + int num_vertices = num_faces * 3; - vertices.resize(num_vertices*3); - if(obj_stats.num_normal){ - normals.resize(num_vertices*3); + vertices.resize(num_vertices * 3); + if (obj_stats.num_normal) { + normals.resize(num_vertices * 3); } else { normals.clear(); } - tangents.resize(num_vertices*3,0.0f); - bitangents.resize(num_vertices*3,0.0f); - tex_coords.resize(num_vertices*2); - faces.resize(num_faces*3); + tangents.resize(num_vertices * 3, 0.0f); + bitangents.resize(num_vertices * 3, 0.0f); + tex_coords.resize(num_vertices * 2); + faces.resize(num_faces * 3); face_normals.resize(num_faces); - for (int i=0, len=faces.size(); i<len; i++){ + for (int i = 0, len = faces.size(); i < len; i++) { faces[i] = i; - vertices[i*3+0] = temp.vertices[temp.vert_indices[i]*3+0]; - vertices[i*3+1] = temp.vertices[temp.vert_indices[i]*3+1]; - vertices[i*3+2] = temp.vertices[temp.vert_indices[i]*3+2]; + vertices[i * 3 + 0] = temp.vertices[temp.vert_indices[i] * 3 + 0]; + vertices[i * 3 + 1] = temp.vertices[temp.vert_indices[i] * 3 + 1]; + vertices[i * 3 + 2] = temp.vertices[temp.vert_indices[i] * 3 + 2]; - if(obj_stats.num_normal){ - normals[i*3+0] = temp.normals[temp.norm_indices[i]*3+0]; - normals[i*3+1] = temp.normals[temp.norm_indices[i]*3+1]; - normals[i*3+2] = temp.normals[temp.norm_indices[i]*3+2]; + if (obj_stats.num_normal) { + normals[i * 3 + 0] = temp.normals[temp.norm_indices[i] * 3 + 0]; + normals[i * 3 + 1] = temp.normals[temp.norm_indices[i] * 3 + 1]; + normals[i * 3 + 2] = temp.normals[temp.norm_indices[i] * 3 + 2]; } - if(obj_stats.num_tex){ - tangents[i*3+0] = temp.tangents[temp.tex_indices[i]*3+0]; - tangents[i*3+1] = temp.tangents[temp.tex_indices[i]*3+1]; - tangents[i*3+2] = temp.tangents[temp.tex_indices[i]*3+2]; + if (obj_stats.num_tex) { + tangents[i * 3 + 0] = temp.tangents[temp.tex_indices[i] * 3 + 0]; + tangents[i * 3 + 1] = temp.tangents[temp.tex_indices[i] * 3 + 1]; + tangents[i * 3 + 2] = temp.tangents[temp.tex_indices[i] * 3 + 2]; - bitangents[i*3+0] = temp.bitangents[temp.tex_indices[i]*3+0]; - bitangents[i*3+1] = temp.bitangents[temp.tex_indices[i]*3+1]; - bitangents[i*3+2] = temp.bitangents[temp.tex_indices[i]*3+2]; + bitangents[i * 3 + 0] = temp.bitangents[temp.tex_indices[i] * 3 + 0]; + bitangents[i * 3 + 1] = temp.bitangents[temp.tex_indices[i] * 3 + 1]; + bitangents[i * 3 + 2] = temp.bitangents[temp.tex_indices[i] * 3 + 2]; - tex_coords[i*2+0] = temp.tex_coords[temp.tex_indices[i]*2+0]; - tex_coords[i*2+1] = temp.tex_coords[temp.tex_indices[i]*2+1]; + tex_coords[i * 2 + 0] = temp.tex_coords[temp.tex_indices[i] * 2 + 0]; + tex_coords[i * 2 + 1] = temp.tex_coords[temp.tex_indices[i] * 2 + 1]; } } - tex_coords2.resize(num_vertices*2); - for (int i = 0;i<num_vertices;i++){ - tex_coords2[i*2+0] = tex_coords[i*2+0]; - tex_coords2[i*2+1] = tex_coords[i*2+1]; + tex_coords2.resize(num_vertices * 2); + for (int i = 0; i < num_vertices; i++) { + tex_coords2[i * 2 + 0] = tex_coords[i * 2 + 0]; + tex_coords2[i * 2 + 1] = tex_coords[i * 2 + 1]; } - } - else - { + } else { return ERROR_MORE_THAN_ONE_OBJECT; } return 0; } - -const char* Model::GetLoadErrorString(int err) -{ - switch( err ) - { + +const char *Model::GetLoadErrorString(int err) { + switch (err) { case 0: return "No error"; case ERROR_MORE_THAN_ONE_OBJECT: @@ -815,28 +786,29 @@ const char* Model::GetLoadErrorString(int err) } } -void CopyTexCoords2( Model &a, const Model& b ) { - a.tex_coords2.resize(a.vertices.size()/3*2); - std::map<float,std::map<float,std::map<float, - std::map<float,std::map<float,std::map<float, - std::vector<int> > > > > > > dup_map; +void CopyTexCoords2(Model &a, const Model &b) { + a.tex_coords2.resize(a.vertices.size() / 3 * 2); + std::map<float, std::map<float, std::map<float, + std::map<float, std::map<float, std::map<float, + std::vector<int> > > > > > > + dup_map; unsigned vert_index = 0; unsigned normal_index = 0; vec3 n_i; - for(int i=0, len=a.vertices.size()/3; i<len; ++i){ - a.tex_coords2[i*2+0] = 0.0f; - a.tex_coords2[i*2+1] = 0.0f; - if(!a.normals.empty() && !b.normals.empty()){ - n_i = vec3(a.normals[normal_index+0], - a.normals[normal_index+1], - a.normals[normal_index+2]); - } - std::vector<int> &indices = dup_map[floorf(a.vertices[vert_index+0]*100.0f)] - [floorf(a.vertices[vert_index+1]*100.0f)] - [floorf(a.vertices[vert_index+2]*100.0f)] - [floorf(n_i[0]*100.0f)] - [floorf(n_i[1]*100.0f)] - [floorf(n_i[2]*100.0f)]; + for (int i = 0, len = a.vertices.size() / 3; i < len; ++i) { + a.tex_coords2[i * 2 + 0] = 0.0f; + a.tex_coords2[i * 2 + 1] = 0.0f; + if (!a.normals.empty() && !b.normals.empty()) { + n_i = vec3(a.normals[normal_index + 0], + a.normals[normal_index + 1], + a.normals[normal_index + 2]); + } + std::vector<int> &indices = dup_map[floorf(a.vertices[vert_index + 0] * 100.0f)] + [floorf(a.vertices[vert_index + 1] * 100.0f)] + [floorf(a.vertices[vert_index + 2] * 100.0f)] + [floorf(n_i[0] * 100.0f)] + [floorf(n_i[1] * 100.0f)] + [floorf(n_i[2] * 100.0f)]; normal_index += 3; vert_index += 3; indices.push_back(i); @@ -844,41 +816,41 @@ void CopyTexCoords2( Model &a, const Model& b ) { vert_index = 0; normal_index = 0; - for(int i=0, len=b.vertices.size()/3; i<len; ++i){ - if(!a.normals.empty() && !b.normals.empty()){ - n_i = vec3(b.normals[normal_index+0], - b.normals[normal_index+1], - b.normals[normal_index+2]); - } - std::vector<int> &indices = dup_map[floorf(b.vertices[vert_index+0]*100.0f)] - [floorf(b.vertices[vert_index+1]*100.0f)] - [floorf(b.vertices[vert_index+2]*100.0f)] - [floorf(n_i[0]*100.0f)] - [floorf(n_i[1]*100.0f)] - [floorf(n_i[2]*100.0f)]; + for (int i = 0, len = b.vertices.size() / 3; i < len; ++i) { + if (!a.normals.empty() && !b.normals.empty()) { + n_i = vec3(b.normals[normal_index + 0], + b.normals[normal_index + 1], + b.normals[normal_index + 2]); + } + std::vector<int> &indices = dup_map[floorf(b.vertices[vert_index + 0] * 100.0f)] + [floorf(b.vertices[vert_index + 1] * 100.0f)] + [floorf(b.vertices[vert_index + 2] * 100.0f)] + [floorf(n_i[0] * 100.0f)] + [floorf(n_i[1] * 100.0f)] + [floorf(n_i[2] * 100.0f)]; normal_index += 3; vert_index += 3; - for(int index : indices){ - a.tex_coords2[index*2+0] = b.tex_coords[i*2+0]; - a.tex_coords2[index*2+1] = b.tex_coords[i*2+1]; + for (int index : indices) { + a.tex_coords2[index * 2 + 0] = b.tex_coords[i * 2 + 0]; + a.tex_coords2[index * 2 + 1] = b.tex_coords[i * 2 + 1]; } } dup_map.clear(); vert_index = 0; normal_index = 0; - for(int i=0, len=a.vertices.size()/3; i<len; ++i){ - if(!a.normals.empty() && !b.normals.empty()){ - n_i = vec3(a.normals[normal_index+0], - a.normals[normal_index+1], - a.normals[normal_index+2]); - } - std::vector<int> &indices = dup_map[floorf(a.vertices[vert_index+0]*10.0f+0.5f)] - [floorf(a.vertices[vert_index+1]*10.0f+0.5f)] - [floorf(a.vertices[vert_index+2]*10.0f+0.5f)] - [floorf(n_i[0]*10.0f+0.5f)] - [floorf(n_i[1]*10.0f+0.5f)] - [floorf(n_i[2]*10.0f+0.5f)]; + for (int i = 0, len = a.vertices.size() / 3; i < len; ++i) { + if (!a.normals.empty() && !b.normals.empty()) { + n_i = vec3(a.normals[normal_index + 0], + a.normals[normal_index + 1], + a.normals[normal_index + 2]); + } + std::vector<int> &indices = dup_map[floorf(a.vertices[vert_index + 0] * 10.0f + 0.5f)] + [floorf(a.vertices[vert_index + 1] * 10.0f + 0.5f)] + [floorf(a.vertices[vert_index + 2] * 10.0f + 0.5f)] + [floorf(n_i[0] * 10.0f + 0.5f)] + [floorf(n_i[1] * 10.0f + 0.5f)] + [floorf(n_i[2] * 10.0f + 0.5f)]; normal_index += 3; vert_index += 3; indices.push_back(i); @@ -886,26 +858,25 @@ void CopyTexCoords2( Model &a, const Model& b ) { vert_index = 0; normal_index = 0; - for(int i=0, len=b.vertices.size()/3; i<len; ++i){ - if(!a.normals.empty() && !b.normals.empty()){ - n_i = vec3(b.normals[normal_index+0], - b.normals[normal_index+1], - b.normals[normal_index+2]); - } - std::vector<int> &indices = dup_map[floorf(b.vertices[vert_index+0]*10.0f+0.5f)] - [floorf(b.vertices[vert_index+1]*10.0f+0.5f)] - [floorf(b.vertices[vert_index+2]*10.0f+0.5f)] - [floorf(n_i[0]*10.0f+0.5f)] - [floorf(n_i[1]*10.0f+0.5f)] - [floorf(n_i[2]*10.0f+0.5f)]; + for (int i = 0, len = b.vertices.size() / 3; i < len; ++i) { + if (!a.normals.empty() && !b.normals.empty()) { + n_i = vec3(b.normals[normal_index + 0], + b.normals[normal_index + 1], + b.normals[normal_index + 2]); + } + std::vector<int> &indices = dup_map[floorf(b.vertices[vert_index + 0] * 10.0f + 0.5f)] + [floorf(b.vertices[vert_index + 1] * 10.0f + 0.5f)] + [floorf(b.vertices[vert_index + 2] * 10.0f + 0.5f)] + [floorf(n_i[0] * 10.0f + 0.5f)] + [floorf(n_i[1] * 10.0f + 0.5f)] + [floorf(n_i[2] * 10.0f + 0.5f)]; normal_index += 3; vert_index += 3; - for(int index : indices){ - if(a.tex_coords2[index*2+0] == 0.0f && - a.tex_coords2[index*2+1] == 0.0f) - { - a.tex_coords2[index*2+0] = b.tex_coords[i*2+0]; - a.tex_coords2[index*2+1] = b.tex_coords[i*2+1]; + for (int index : indices) { + if (a.tex_coords2[index * 2 + 0] == 0.0f && + a.tex_coords2[index * 2 + 1] == 0.0f) { + a.tex_coords2[index * 2 + 0] = b.tex_coords[i * 2 + 0]; + a.tex_coords2[index * 2 + 1] = b.tex_coords[i * 2 + 1]; } } } @@ -913,18 +884,18 @@ void CopyTexCoords2( Model &a, const Model& b ) { dup_map.clear(); vert_index = 0; normal_index = 0; - for(int i=0, len=a.vertices.size()/3; i<len; ++i){ - if(!a.normals.empty() && !b.normals.empty()){ - n_i = vec3(a.normals[normal_index+0], - a.normals[normal_index+1], - a.normals[normal_index+2]); - } - std::vector<int> &indices = dup_map[floorf(a.vertices[vert_index+0]*1.0f+0.5f)] - [floorf(a.vertices[vert_index+1]*1.0f+0.5f)] - [floorf(a.vertices[vert_index+2]*1.0f+0.5f)] - [floorf(n_i[0]*1.0f+0.5f)] - [floorf(n_i[1]*1.0f+0.5f)] - [floorf(n_i[2]*1.0f+0.5f)]; + for (int i = 0, len = a.vertices.size() / 3; i < len; ++i) { + if (!a.normals.empty() && !b.normals.empty()) { + n_i = vec3(a.normals[normal_index + 0], + a.normals[normal_index + 1], + a.normals[normal_index + 2]); + } + std::vector<int> &indices = dup_map[floorf(a.vertices[vert_index + 0] * 1.0f + 0.5f)] + [floorf(a.vertices[vert_index + 1] * 1.0f + 0.5f)] + [floorf(a.vertices[vert_index + 2] * 1.0f + 0.5f)] + [floorf(n_i[0] * 1.0f + 0.5f)] + [floorf(n_i[1] * 1.0f + 0.5f)] + [floorf(n_i[2] * 1.0f + 0.5f)]; normal_index += 3; vert_index += 3; indices.push_back(i); @@ -932,40 +903,37 @@ void CopyTexCoords2( Model &a, const Model& b ) { vert_index = 0; normal_index = 0; - for(int i=0, len=b.vertices.size()/3; i<len; ++i){ - if(!a.normals.empty() && !b.normals.empty()){ - n_i = vec3(b.normals[normal_index+0], - b.normals[normal_index+1], - b.normals[normal_index+2]); - } - std::vector<int> &indices = dup_map[floorf(b.vertices[vert_index+0]*1.0f+0.5f)] - [floorf(b.vertices[vert_index+1]*1.0f+0.5f)] - [floorf(b.vertices[vert_index+2]*1.0f+0.5f)] - [floorf(n_i[0]*1.0f+0.5f)] - [floorf(n_i[1]*1.0f+0.5f)] - [floorf(n_i[2]*1.0f+0.5f)]; + for (int i = 0, len = b.vertices.size() / 3; i < len; ++i) { + if (!a.normals.empty() && !b.normals.empty()) { + n_i = vec3(b.normals[normal_index + 0], + b.normals[normal_index + 1], + b.normals[normal_index + 2]); + } + std::vector<int> &indices = dup_map[floorf(b.vertices[vert_index + 0] * 1.0f + 0.5f)] + [floorf(b.vertices[vert_index + 1] * 1.0f + 0.5f)] + [floorf(b.vertices[vert_index + 2] * 1.0f + 0.5f)] + [floorf(n_i[0] * 1.0f + 0.5f)] + [floorf(n_i[1] * 1.0f + 0.5f)] + [floorf(n_i[2] * 1.0f + 0.5f)]; normal_index += 3; vert_index += 3; - for(int index : indices){ - if(a.tex_coords2[index*2+0] == 0.0f && - a.tex_coords2[index*2+1] == 0.0f) - { - a.tex_coords2[index*2+0] = b.tex_coords[i*2+0]; - a.tex_coords2[index*2+1] = b.tex_coords[i*2+1]; + for (int index : indices) { + if (a.tex_coords2[index * 2 + 0] == 0.0f && + a.tex_coords2[index * 2 + 1] == 0.0f) { + a.tex_coords2[index * 2 + 0] = b.tex_coords[i * 2 + 0]; + a.tex_coords2[index * 2 + 1] = b.tex_coords[i * 2 + 1]; } } } } - void Model::LoadObj(const std::string &rel_path, char flags, const std::string &alt_name, const PathFlags searchPaths) { + // LOGI << "Loading model: " << rel_path << std::endl; + const char *fail_whale = "./Data/Models/Default/default_model_2.obj"; - //LOGI << "Loading model: " << rel_path << std::endl; - const char* fail_whale = "./Data/Models/Default/default_model_2.obj"; - - bool center = (flags & _MDL_CENTER)!=0; - bool simple = (flags & _MDL_SIMPLE)!=0; - use_tangent = (flags & _MDL_USE_TANGENT)!=0; + bool center = (flags & _MDL_CENTER) != 0; + bool simple = (flags & _MDL_SIMPLE) != 0; + use_tangent = (flags & _MDL_USE_TANGENT) != 0; bool load_model = true; @@ -974,31 +942,31 @@ void Model::LoadObj(const std::string &rel_path, char flags, const std::string & path = rel_path; std::string name_to_load = rel_path; - const std::string &cache_name_to_load = SanitizePath(alt_name.empty()?rel_path:alt_name); + const std::string &cache_name_to_load = SanitizePath(alt_name.empty() ? rel_path : alt_name); char abs_path[kPathSize], abs_cache_path[kPathSize]; ModID modsource, cache_modsource; bool found_model = (FindFilePath(name_to_load.c_str(), abs_path, kPathSize, searchPaths, false, NULL, &modsource) != -1); - bool found_cache = (FindFilePath((cache_name_to_load+".cache").c_str(), abs_cache_path, kPathSize, searchPaths, false, NULL, &cache_modsource) != -1); + bool found_cache = (FindFilePath((cache_name_to_load + ".cache").c_str(), abs_cache_path, kPathSize, searchPaths, false, NULL, &cache_modsource) != -1); - if (!found_model && !found_cache) { // To do: fix bug when only cache exists + if (!found_model && !found_cache) { // To do: fix bug when only cache exists std::string error_msg = "Whale fail :(\nModel file \"" + std::string(rel_path) + "\" not found. Loading the fail whale instead."; DisplayError("Error", error_msg.c_str(), _ok, false); name_to_load = fail_whale; } - if(found_model){ + if (found_model) { checksum = Checksum(abs_path); } - - if(found_cache){ + + if (found_cache) { FILE *cache_file = my_fopen(abs_cache_path, "rb"); - if(cache_file){ + if (cache_file) { unsigned short file_checksum = 0; fread(&file_checksum, sizeof(unsigned short), 1, cache_file); unsigned short version; fread(&version, sizeof(unsigned short), 1, cache_file); - if(checksum == file_checksum && version == _model_cache_version){ + if (checksum == file_checksum && version == _model_cache_version) { ReadFromFile(cache_file); load_model = false; modsource_ = cache_modsource; @@ -1010,71 +978,66 @@ void Model::LoadObj(const std::string &rel_path, char flags, const std::string & if (load_model) { int modelLoadError = SimpleLoadTriangleCutObj(name_to_load); - if( 0 == modelLoadError ) - { - precollapse_num_vertices = vertices.size()/3; + if (0 == modelLoadError) { + precollapse_num_vertices = vertices.size() / 3; ObjFileStats obj_stats2; - bool uv2_file = GetObjFileStats(name_to_load+"_UV2", obj_stats2, false); + bool uv2_file = GetObjFileStats(name_to_load + "_UV2", obj_stats2, false); if (uv2_file) { Model temp2; - int uv2_err = temp2.SimpleLoadTriangleCutObj(name_to_load+"_UV2"); - - if( uv2_err == 0 ) - { - //CopyTexCoords2((*this), temp2); - if(temp2.vertices.size() != vertices.size()){ - DisplayError("Error", ("Mismatched number of vertices in: "+ - (name_to_load+"_UV2") + ". Will not use data.").c_str() ); - } - else - { - for(int i=0, len=vertices.size()/3*2; i<len; ++i){ + int uv2_err = temp2.SimpleLoadTriangleCutObj(name_to_load + "_UV2"); + + if (uv2_err == 0) { + // CopyTexCoords2((*this), temp2); + if (temp2.vertices.size() != vertices.size()) { + DisplayError("Error", ("Mismatched number of vertices in: " + + (name_to_load + "_UV2") + ". Will not use data.") + .c_str()); + } else { + for (int i = 0, len = vertices.size() / 3 * 2; i < len; ++i) { tex_coords2[i] = temp2.tex_coords[i]; } } - } - else - { - DisplayError("Error", ("Malformed data in: "+ - (name_to_load+"_UV2" + ", reason: " + GetLoadErrorString(uv2_err) + " Will not use data.")).c_str() ); + } else { + DisplayError("Error", ("Malformed data in: " + + (name_to_load + "_UV2" + ", reason: " + GetLoadErrorString(uv2_err) + " Will not use data.")) + .c_str()); } } - - if(flags & _MDL_FLIP_FACES){ - for(unsigned i=0; i<faces.size(); i+=3){ - std::swap(faces[i+0], faces[i+2]); + if (flags & _MDL_FLIP_FACES) { + for (unsigned i = 0; i < faces.size(); i += 3) { + std::swap(faces[i + 0], faces[i + 2]); } } - if(!simple){ - if(normals.empty()) { + if (!simple) { + if (normals.empty()) { calcNormals(); } else { calcFaceNormals(); - for(int i=0, len=normals.size(); i<len; i+=3){ - float length = sqrtf(square(normals[i]) + square(normals[i+1]) + square(normals[i+2])); - if(length != 0.0f){ - normals[i+0] /= length; - normals[i+1] /= length; - normals[i+2] /= length; + for (int i = 0, len = normals.size(); i < len; i += 3) { + float length = sqrtf(square(normals[i]) + square(normals[i + 1]) + square(normals[i + 2])); + if (length != 0.0f) { + normals[i + 0] /= length; + normals[i + 1] /= length; + normals[i + 2] /= length; } } } calcTangents(); } else { tex_coords.clear(); - tex_coords.resize(vertices.size()/3*2, 0.0f); + tex_coords.resize(vertices.size() / 3 * 2, 0.0f); normals.resize(vertices.size(), 0.0f); } calcBoundingBox(); old_center = center_coords; - if(center) { + if (center) { CenterModel(); } calcBoundingSphere(); - + CalcTexelDensity(); CalcAverageTriangleEdge(); @@ -1084,61 +1047,56 @@ void Model::LoadObj(const std::string &rel_path, char flags, const std::string & OptimizeVertexOrder(); FILE *cache_file = my_fopen((GetWritePath(modsource) + cache_name_to_load + ".cache").c_str(), "wb"); - if(cache_file){ + if (cache_file) { fwrite(&checksum, sizeof(unsigned short), 1, cache_file); fwrite(&_model_cache_version, sizeof(unsigned short), 1, cache_file); WriteToFile(cache_file); fclose(cache_file); } modsource_ = modsource; - } - else - { - if( fail_whale == rel_path ) - { - FatalError( "Error", "Unable to load fail whale, this is bad."); - } - else - { - std::string error_msg = "Whale fail :(\nModel file \"" + std::string(rel_path) + "\" is corrupt because: "+ GetLoadErrorString(modelLoadError) + ". Loading the fail whale instead."; + } else { + if (fail_whale == rel_path) { + FatalError("Error", "Unable to load fail whale, this is bad."); + } else { + std::string error_msg = "Whale fail :(\nModel file \"" + std::string(rel_path) + "\" is corrupt because: " + GetLoadErrorString(modelLoadError) + ". Loading the fail whale instead."; DisplayError("Error", error_msg.c_str(), _ok, false); LoadObj(fail_whale, flags, fail_whale); - return; //Quick out. + return; // Quick out. } } } vbo_enabled = true; - //PrintACMR(); + // PrintACMR(); } -void DrawModelVerts(Model& model, const char* vert_attrib_str, Shaders* shaders, Graphics* graphics, int shader) { - if(!model.vbo_loaded){ +void DrawModelVerts(Model &model, const char *vert_attrib_str, Shaders *shaders, Graphics *graphics, int shader) { + if (!model.vbo_loaded) { model.createVBO(); - } + } model.VBO_vertices.Bind(); model.VBO_faces.Bind(); int vert_attrib_id = shaders->returnShaderAttrib(vert_attrib_str, shader); graphics->EnableVertexAttribArray(vert_attrib_id); - glVertexAttribPointer(vert_attrib_id, 3, GL_FLOAT, false, 3*sizeof(GLfloat), 0); + glVertexAttribPointer(vert_attrib_id, 3, GL_FLOAT, false, 3 * sizeof(GLfloat), 0); graphics->DrawElements(GL_TRIANGLES, model.faces.size(), GL_UNSIGNED_INT, 0); graphics->ResetVertexAttribArrays(); graphics->BindArrayVBO(0); graphics->BindElementVBO(0); } -//Draw model +// Draw model void Model::Draw() { PROFILER_GPU_ZONE(g_profiler_ctx, "Model::Draw"); Graphics *graphics = Graphics::Instance(); CHECK_GL_ERROR(); - if(vbo_enabled){ - if(!vbo_loaded){ + if (vbo_enabled) { + if (!vbo_loaded) { createVBO(); - } - CHECK_GL_ERROR(); + } + CHECK_GL_ERROR(); int flags = F_VERTEX_ARRAY | F_NORMAL_ARRAY | F_TEXTURE_COORD_ARRAY0; - if(!tangents.empty()){ + if (!tangents.empty()) { flags |= F_TEXTURE_COORD_ARRAY1 | F_TEXTURE_COORD_ARRAY2; } if (!tex_coords2.empty()) { @@ -1146,67 +1104,66 @@ void Model::Draw() { } if (!aux.empty()) { flags |= F_COLOR_ARRAY; - } - CHECK_GL_ERROR(); - graphics->SetClientStates(flags); - CHECK_GL_ERROR(); - VBO_vertices.Bind(); - CHECK_GL_ERROR(); - glVertexPointer(3, GL_FLOAT, 0, 0); - CHECK_GL_ERROR(); - VBO_normals.Bind(); - CHECK_GL_ERROR(); - glNormalPointer(GL_FLOAT, 0, 0); - CHECK_GL_ERROR(); - graphics->SetClientActiveTexture(0); - CHECK_GL_ERROR(); - VBO_tex_coords.Bind(); - glTexCoordPointer(2, GL_FLOAT, 0, 0); - CHECK_GL_ERROR(); - if(!tangents.empty()){ - graphics->SetClientActiveTexture(1); - CHECK_GL_ERROR(); - VBO_tangents.Bind(); + } + CHECK_GL_ERROR(); + graphics->SetClientStates(flags); + CHECK_GL_ERROR(); + VBO_vertices.Bind(); + CHECK_GL_ERROR(); + glVertexPointer(3, GL_FLOAT, 0, 0); + CHECK_GL_ERROR(); + VBO_normals.Bind(); + CHECK_GL_ERROR(); + glNormalPointer(GL_FLOAT, 0, 0); + CHECK_GL_ERROR(); + graphics->SetClientActiveTexture(0); + CHECK_GL_ERROR(); + VBO_tex_coords.Bind(); + glTexCoordPointer(2, GL_FLOAT, 0, 0); + CHECK_GL_ERROR(); + if (!tangents.empty()) { + graphics->SetClientActiveTexture(1); + CHECK_GL_ERROR(); + VBO_tangents.Bind(); + glTexCoordPointer(3, GL_FLOAT, 0, 0); + graphics->SetClientActiveTexture(2); + CHECK_GL_ERROR(); + VBO_bitangents.Bind(); glTexCoordPointer(3, GL_FLOAT, 0, 0); - graphics->SetClientActiveTexture(2); - CHECK_GL_ERROR(); - VBO_bitangents.Bind(); - glTexCoordPointer(3, GL_FLOAT, 0, 0); - CHECK_GL_ERROR(); + CHECK_GL_ERROR(); } if (!tex_coords2.empty()) { - graphics->SetClientActiveTexture(3); - CHECK_GL_ERROR(); - VBO_tex_coords2.Bind(); - glTexCoordPointer(2, GL_FLOAT, 0, 0); - CHECK_GL_ERROR(); + graphics->SetClientActiveTexture(3); + CHECK_GL_ERROR(); + VBO_tex_coords2.Bind(); + glTexCoordPointer(2, GL_FLOAT, 0, 0); + CHECK_GL_ERROR(); } if (!aux.empty()) { - VBO_aux.Bind(); - glColorPointer(3, GL_FLOAT, 0, 0); - CHECK_GL_ERROR(); + VBO_aux.Bind(); + glColorPointer(3, GL_FLOAT, 0, 0); + CHECK_GL_ERROR(); } - VBO_faces.Bind(); - graphics->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, 0); - CHECK_GL_ERROR(); + VBO_faces.Bind(); + graphics->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, 0); + CHECK_GL_ERROR(); if (!tex_coords2.empty()) { - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY3,false); - } - if(!tangents.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2,false); - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1,false); - } - CHECK_GL_ERROR(); - Graphics::Instance()->SetClientActiveTexture(0); - CHECK_GL_ERROR(); - graphics->BindArrayVBO(0); - CHECK_GL_ERROR(); - graphics->BindElementVBO(0); - CHECK_GL_ERROR(); - } - else if (transform_vec.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY3, false); + } + if (!tangents.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2, false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1, false); + } + CHECK_GL_ERROR(); + Graphics::Instance()->SetClientActiveTexture(0); + CHECK_GL_ERROR(); + graphics->BindArrayVBO(0); + CHECK_GL_ERROR(); + graphics->BindElementVBO(0); + CHECK_GL_ERROR(); + } else if (transform_vec.empty()) { int flags = F_VERTEX_ARRAY | F_NORMAL_ARRAY | F_TEXTURE_COORD_ARRAY0; - if(!tangents.empty()){ + if (!tangents.empty()) { flags |= F_TEXTURE_COORD_ARRAY1 | F_TEXTURE_COORD_ARRAY2; } if (!tex_coords2.empty()) { @@ -1215,56 +1172,56 @@ void Model::Draw() { if (!aux.empty()) { flags |= F_COLOR_ARRAY; } - if(!bone_weights.empty()){ + if (!bone_weights.empty()) { flags |= F_TEXTURE_COORD_ARRAY5; } - if(!bone_ids.empty()){ + if (!bone_ids.empty()) { flags |= F_TEXTURE_COORD_ARRAY6; } - graphics->SetClientStates(flags); + graphics->SetClientStates(flags); graphics->SetClientActiveTexture(0); glTexCoordPointer(2, GL_FLOAT, 0, &tex_coords[0]); glNormalPointer(GL_FLOAT, 0, &normals[0]); glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); - if(!tangents.empty()){ + if (!tangents.empty()) { graphics->SetClientActiveTexture(1); glTexCoordPointer(3, GL_FLOAT, 0, &tangents[0]); graphics->SetClientActiveTexture(2); glTexCoordPointer(3, GL_FLOAT, 0, &bitangents[0]); } - if(!tex_coords2.empty()){ + if (!tex_coords2.empty()) { graphics->SetClientActiveTexture(3); glTexCoordPointer(2, GL_FLOAT, 0, &tex_coords2[0]); } - if(!aux.empty()){ + if (!aux.empty()) { glColorPointer(3, GL_FLOAT, 0, &aux[0]); } - if(!bone_weights.empty()){ + if (!bone_weights.empty()) { graphics->SetClientActiveTexture(5); glTexCoordPointer(4, GL_FLOAT, 0, &bone_weights[0]); } - if(!bone_ids.empty()){ + if (!bone_ids.empty()) { graphics->SetClientActiveTexture(6); glTexCoordPointer(4, GL_FLOAT, 0, &bone_ids[0]); } graphics->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, &faces[0]); - if(!tex_coords2.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY3,false); + if (!tex_coords2.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY3, false); } - if(!bone_weights.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY5,false); + if (!bone_weights.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY5, false); } - if(!bone_ids.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY6,false); + if (!bone_ids.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY6, false); } - if(!tangents.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2,false); - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1,false); + if (!tangents.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2, false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1, false); } Graphics::Instance()->SetClientActiveTexture(0); } else { int flags = F_VERTEX_ARRAY | F_NORMAL_ARRAY | F_TEXTURE_COORD_ARRAY0 | F_TEXTURE_COORD_ARRAY1 | F_TEXTURE_COORD_ARRAY2 | F_TEXTURE_COORD_ARRAY4 | F_TEXTURE_COORD_ARRAY5; - if(!tangents.empty()){ + if (!tangents.empty()) { flags |= F_TEXTURE_COORD_ARRAY3; } if (!tex_coords2.empty()) { @@ -1273,22 +1230,22 @@ void Model::Draw() { if (!aux.empty()) { flags |= F_COLOR_ARRAY; } - if(!bone_weights.empty()){ + if (!bone_weights.empty()) { flags |= F_TEXTURE_COORD_ARRAY5; } - if(!bone_ids.empty()){ + if (!bone_ids.empty()) { flags |= F_TEXTURE_COORD_ARRAY6; } - graphics->SetClientStates(flags); + graphics->SetClientStates(flags); glNormalPointer(GL_FLOAT, 0, &normals[0]); glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); graphics->SetClientActiveTexture(0); - glTexCoordPointer(2, GL_FLOAT, 0, &tex_coords[0]); + glTexCoordPointer(2, GL_FLOAT, 0, &tex_coords[0]); graphics->SetClientActiveTexture(1); glTexCoordPointer(4, GL_FLOAT, 0, &transform_vec[0][0]); graphics->SetClientActiveTexture(2); glTexCoordPointer(4, GL_FLOAT, 0, &transform_vec[1][0]); - if(!tangents.empty()){ + if (!tangents.empty()) { graphics->SetClientActiveTexture(3); glTexCoordPointer(3, GL_FLOAT, 0, &tangents[0]); } @@ -1297,13 +1254,13 @@ void Model::Draw() { graphics->SetClientActiveTexture(5); glTexCoordPointer(4, GL_FLOAT, 0, &transform_vec[3][0]); graphics->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, &faces[0]); - if(!tangents.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY3,false); - } - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY4,false); - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY5,false); - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2,false); - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1,false); + if (!tangents.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY3, false); + } + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY4, false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY5, false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2, false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1, false); Graphics::Instance()->SetClientActiveTexture(0); } @@ -1312,12 +1269,12 @@ void Model::Draw() { void Model::StartPreset() { Graphics *graphics = Graphics::Instance(); - if(vbo_enabled){ - if(!vbo_loaded){ + if (vbo_enabled) { + if (!vbo_loaded) { createVBO(); - } + } int flags = F_VERTEX_ARRAY | F_NORMAL_ARRAY | F_TEXTURE_COORD_ARRAY0; - if(!tangents.empty()){ + if (!tangents.empty()) { flags |= F_TEXTURE_COORD_ARRAY1 | F_TEXTURE_COORD_ARRAY2; } if (!tex_coords2.empty()) { @@ -1327,48 +1284,48 @@ void Model::StartPreset() { flags |= F_COLOR_ARRAY; } graphics->SetClientStates(flags); - VBO_vertices.Bind(); + VBO_vertices.Bind(); glVertexPointer(3, GL_FLOAT, 0, 0); - VBO_normals.Bind(); + VBO_normals.Bind(); glNormalPointer(GL_FLOAT, 0, 0); graphics->SetClientActiveTexture(0); - VBO_tex_coords.Bind(); + VBO_tex_coords.Bind(); glTexCoordPointer(2, GL_FLOAT, 0, 0); - if(!tangents.empty()){ + if (!tangents.empty()) { graphics->SetClientActiveTexture(1); - VBO_tangents.Bind(); + VBO_tangents.Bind(); glTexCoordPointer(3, GL_FLOAT, 0, 0); graphics->SetClientActiveTexture(2); - VBO_bitangents.Bind(); + VBO_bitangents.Bind(); glTexCoordPointer(3, GL_FLOAT, 0, 0); } if (!tex_coords2.empty()) { graphics->SetClientActiveTexture(3); - VBO_tex_coords2.Bind(); + VBO_tex_coords2.Bind(); glTexCoordPointer(2, GL_FLOAT, 0, 0); } if (!aux.empty()) { - VBO_aux.Bind(); + VBO_aux.Bind(); glColorPointer(3, GL_FLOAT, 0, 0); - } - VBO_faces.Bind(); + } + VBO_faces.Bind(); } } void Model::EndPreset() { - if(vbo_enabled){ + if (vbo_enabled) { if (!aux.empty()) { - //glClientActiveTexture(GL_TEXTURE4); - //glDisableClientState(GL_TEXTURE_COORD_ARRAY); + // glClientActiveTexture(GL_TEXTURE4); + // glDisableClientState(GL_TEXTURE_COORD_ARRAY); } - + if (!tex_coords2.empty()) { - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY3,false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY3, false); } - - if(!tangents.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2,false); - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1,false); + + if (!tangents.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2, false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1, false); } Graphics::Instance()->SetClientActiveTexture(0); Graphics::Instance()->BindArrayVBO(0); @@ -1376,9 +1333,8 @@ void Model::EndPreset() { } } -void Model::DrawPreset() -{ - if(vbo_enabled){ +void Model::DrawPreset() { + if (vbo_enabled) { Graphics::Instance()->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, 0); } } @@ -1388,29 +1344,29 @@ struct AuxVertData { vec3 total_aux; }; -bool Model::LoadAuxFromImage(const std::string &image_path) { +bool Model::LoadAuxFromImage(const std::string &image_path) { bool ret = true; - if(aux.empty()) { + if (aux.empty()) { ImageSamplerRef image = Engine::Instance()->GetAssetManager()->LoadSync<ImageSampler>(image_path); - - if(image.valid()) { + + if (image.valid()) { image_samplers.insert(image); aux.resize(vertices.size()); - for(int i=0, len=vertices.size()/3; i<len; i++) { - vec4 color = image->GetInterpolatedColorUV(tex_coords[i*2+0], tex_coords[i*2+1]); - aux[i*3+0] = color.r(); - aux[i*3+1] = color.g(); - aux[i*3+2] = color.b(); + for (int i = 0, len = vertices.size() / 3; i < len; i++) { + vec4 color = image->GetInterpolatedColorUV(tex_coords[i * 2 + 0], tex_coords[i * 2 + 1]); + aux[i * 3 + 0] = color.r(); + aux[i * 3 + 1] = color.g(); + aux[i * 3 + 2] = color.b(); } // Duplicate map keeps a list of all vertices that share the same position std::map<vec3, AuxVertData> dup_map; unsigned vert_index = 0; - for(int i=0, len=vertices.size()/3; i<len; i++) { - vec3 index(vertices[vert_index+0], - vertices[vert_index+1], - vertices[vert_index+2]); + for (int i = 0, len = vertices.size() / 3; i < len; i++) { + vec3 index(vertices[vert_index + 0], + vertices[vert_index + 1], + vertices[vert_index + 2]); AuxVertData &avd = dup_map[index]; avd.verts.push_back(i); avd.total_aux[0] += aux[vert_index + 0]; @@ -1419,12 +1375,12 @@ bool Model::LoadAuxFromImage(const std::string &image_path) { vert_index += 3; } std::map<vec3, AuxVertData>::iterator iter; - for(iter = dup_map.begin(); iter != dup_map.end(); ++iter){ + for (iter = dup_map.begin(); iter != dup_map.end(); ++iter) { AuxVertData &avd = iter->second; - if(avd.verts.size() > 1){ + if (avd.verts.size() > 1) { avd.total_aux /= (float)avd.verts.size(); - for(unsigned i=0; i<avd.verts.size(); ++i){ - int index = avd.verts[i]*3; + for (unsigned i = 0; i < avd.verts.size(); ++i) { + int index = avd.verts[i] * 3; aux[index + 0] = avd.total_aux[0]; aux[index + 1] = avd.total_aux[2]; aux[index + 2] = avd.total_aux[1]; @@ -1436,80 +1392,77 @@ bool Model::LoadAuxFromImage(const std::string &image_path) { ret = false; } } else { - //Nop instruction, this state is ok. + // Nop instruction, this state is ok. } return ret; } -void Model::DrawAltTexCoords() -{ +void Model::DrawAltTexCoords() { PROFILER_GPU_ZONE(g_profiler_ctx, "Model::DrawAltTexCoords"); CHECK_GL_ERROR(); - + Graphics *graphics = Graphics::Instance(); int flags = F_VERTEX_ARRAY | F_NORMAL_ARRAY | F_TEXTURE_COORD_ARRAY0; - if(!tangents.empty()){ + if (!tangents.empty()) { flags |= F_TEXTURE_COORD_ARRAY1 | F_TEXTURE_COORD_ARRAY2; } - graphics->SetClientStates(flags); + graphics->SetClientStates(flags); - if(vbo_enabled){ - if(!vbo_loaded){ + if (vbo_enabled) { + if (!vbo_loaded) { createVBO(); } - VBO_vertices.Bind(); + VBO_vertices.Bind(); glVertexPointer(3, GL_FLOAT, 0, 0); - VBO_normals.Bind(); + VBO_normals.Bind(); glNormalPointer(GL_FLOAT, 0, 0); graphics->SetClientActiveTexture(0); - VBO_tex_coords.Bind(); + VBO_tex_coords.Bind(); glTexCoordPointer(2, GL_FLOAT, 0, 0); if (!tex_coords2.empty()) { - VBO_tex_coords2.Bind(); + VBO_tex_coords2.Bind(); glTexCoordPointer(2, GL_FLOAT, 0, 0); } - if(!tangents.empty()){ + if (!tangents.empty()) { graphics->SetClientActiveTexture(1); - VBO_tangents.Bind(); + VBO_tangents.Bind(); glTexCoordPointer(3, GL_FLOAT, 0, 0); graphics->SetClientActiveTexture(2); - VBO_bitangents.Bind(); + VBO_bitangents.Bind(); glTexCoordPointer(3, GL_FLOAT, 0, 0); } - + VBO_faces.Bind(); graphics->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, 0); - if(!tangents.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2,false); - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1,false); + if (!tangents.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2, false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1, false); } Graphics::Instance()->SetClientActiveTexture(0); Graphics::Instance()->BindArrayVBO(0); Graphics::Instance()->BindElementVBO(0); - } - else - { + } else { graphics->SetClientActiveTexture(0); glTexCoordPointer(2, GL_FLOAT, 0, &tex_coords[0]); glNormalPointer(GL_FLOAT, 0, &normals[0]); glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); - - if(!tex_coords2.empty()){ + + if (!tex_coords2.empty()) { glTexCoordPointer(2, GL_FLOAT, 0, &tex_coords2[0]); } - if(!tangents.empty()){ + if (!tangents.empty()) { graphics->SetClientActiveTexture(1); glTexCoordPointer(3, GL_FLOAT, 0, &tangents[0]); graphics->SetClientActiveTexture(2); glTexCoordPointer(3, GL_FLOAT, 0, &bitangents[0]); } - + graphics->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, &faces[0]); - - if(!tangents.empty()){ - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2,false); - Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1,false); + + if (!tangents.empty()) { + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY2, false); + Graphics::Instance()->SetClientStateEnabled(CS_TEXTURE_COORD_ARRAY1, false); } Graphics::Instance()->SetClientActiveTexture(0); } @@ -1517,66 +1470,65 @@ void Model::DrawAltTexCoords() CHECK_GL_ERROR(); } -void Model::DrawToTextureCoords() -{ +void Model::DrawToTextureCoords() { PROFILER_GPU_ZONE(g_profiler_ctx, "Model::DrawToTextureCoords"); CHECK_GL_ERROR(); - + Graphics *graphics = Graphics::Instance(); int flags = F_VERTEX_ARRAY | F_NORMAL_ARRAY | F_TEXTURE_COORD_ARRAY0; - if(!tangents.empty()){ + if (!tangents.empty()) { flags |= F_TEXTURE_COORD_ARRAY1 | F_TEXTURE_COORD_ARRAY2; } if (!tex_coords2.empty()) { flags |= F_TEXTURE_COORD_ARRAY3; } CHECK_GL_ERROR(); - graphics->SetClientStates(flags); + graphics->SetClientStates(flags); CHECK_GL_ERROR(); - if(vbo_enabled){ - if(!vbo_loaded){ + if (vbo_enabled) { + if (!vbo_loaded) { createVBO(); } - VBO_tex_coords.Bind(); + VBO_tex_coords.Bind(); glVertexPointer(2, GL_FLOAT, 0, 0); - VBO_normals.Bind(); + VBO_normals.Bind(); glNormalPointer(GL_FLOAT, 0, 0); - graphics->SetClientActiveTexture(0); - VBO_tex_coords.Bind(); + graphics->SetClientActiveTexture(0); + VBO_tex_coords.Bind(); glTexCoordPointer(2, GL_FLOAT, 0, 0); - if(!tangents.empty()){ - graphics->SetClientActiveTexture(1); - VBO_tangents.Bind(); + if (!tangents.empty()) { + graphics->SetClientActiveTexture(1); + VBO_tangents.Bind(); glTexCoordPointer(3, GL_FLOAT, 0, 0); - graphics->SetClientActiveTexture(2); - VBO_bitangents.Bind(); + graphics->SetClientActiveTexture(2); + VBO_bitangents.Bind(); glTexCoordPointer(3, GL_FLOAT, 0, 0); } if (!tex_coords2.empty()) { - graphics->SetClientActiveTexture(3); - VBO_tex_coords2.Bind(); + graphics->SetClientActiveTexture(3); + VBO_tex_coords2.Bind(); glTexCoordPointer(2, GL_FLOAT, 0, 0); - } - VBO_faces.Bind(); + } + VBO_faces.Bind(); graphics->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, 0); Graphics::Instance()->SetClientActiveTexture(0); Graphics::Instance()->BindArrayVBO(0); - Graphics::Instance()->BindElementVBO(0); + Graphics::Instance()->BindElementVBO(0); } else { - graphics->SetClientActiveTexture(0); + graphics->SetClientActiveTexture(0); glTexCoordPointer(2, GL_FLOAT, 0, &tex_coords[0]); glNormalPointer(GL_FLOAT, 0, &normals[0]); glVertexPointer(2, GL_FLOAT, 0, &tex_coords[0]); - - if(!tangents.empty()){ - graphics->SetClientActiveTexture(1); + + if (!tangents.empty()) { + graphics->SetClientActiveTexture(1); glTexCoordPointer(3, GL_FLOAT, 0, &tangents[0]); - graphics->SetClientActiveTexture(2); + graphics->SetClientActiveTexture(2); glTexCoordPointer(3, GL_FLOAT, 0, &bitangents[0]); } - if(!tex_coords2.empty()){ - graphics->SetClientActiveTexture(3); + if (!tex_coords2.empty()) { + graphics->SetClientActiveTexture(3); glTexCoordPointer(2, GL_FLOAT, 0, &tex_coords2[0]); } graphics->DrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, &faces[0]); @@ -1588,74 +1540,75 @@ void Model::DrawToTextureCoords() } void Model::calcBoundingBox() { - min_coords=0; - max_coords=0; + min_coords = 0; + max_coords = 0; center_coords = 0; - - for(int i=0, len=vertices.size()/3, vert_index=0; i<len; i++, vert_index+=3) { - for(int j=0; j<3; ++j){ - float coord = vertices[vert_index+j]; - if(i==0 || coord > max_coords[j]){ - max_coords[j] = coord; - } - if(i==0 || coord < min_coords[j]){ - min_coords[j] = coord; - } - } - } - - center_coords = (min_coords + max_coords)/2; + + for (int i = 0, len = vertices.size() / 3, vert_index = 0; i < len; i++, vert_index += 3) { + for (int j = 0; j < 3; ++j) { + float coord = vertices[vert_index + j]; + if (i == 0 || coord > max_coords[j]) { + max_coords[j] = coord; + } + if (i == 0 || coord < min_coords[j]) { + min_coords[j] = coord; + } + } + } + + center_coords = (min_coords + max_coords) / 2; } -//Calculate bounding sphere +// Calculate bounding sphere void Model::calcBoundingSphere() { bounding_sphere_origin = center_coords; - float longest_distance=0; + float longest_distance = 0; vec3 vert; - for (int i=0, len=vertices.size()/3; i<len; i++) { - vert.x()=vertices[i*3]; - vert.y()=vertices[i*3+1]; - vert.z()=vertices[i*3+2]; - if(distance_squared(bounding_sphere_origin, vert)>longest_distance) - longest_distance=distance_squared(bounding_sphere_origin, vert); - } - bounding_sphere_radius=sqrtf(longest_distance); + for (int i = 0, len = vertices.size() / 3; i < len; i++) { + vert.x() = vertices[i * 3]; + vert.y() = vertices[i * 3 + 1]; + vert.z() = vertices[i * 3 + 2]; + if (distance_squared(bounding_sphere_origin, vert) > longest_distance) + longest_distance = distance_squared(bounding_sphere_origin, vert); + } + bounding_sphere_radius = sqrtf(longest_distance); } // must be called after center_coords has been set (i.e. after call to calcBoundingSphere void Model::CenterModel() { - for(int i=0, len=vertices.size()/3; i<len; i++) { - vertices[3*i] -= center_coords.x(); - vertices[3*i+1] -= center_coords.y(); - vertices[3*i+2] -= center_coords.z(); + for (int i = 0, len = vertices.size() / 3; i < len; i++) { + vertices[3 * i] -= center_coords.x(); + vertices[3 * i + 1] -= center_coords.y(); + vertices[3 * i + 2] -= center_coords.z(); } - center_coords = vec3(0,0,0); + center_coords = vec3(0, 0, 0); calcBoundingBox(); } void Model::ResizeVertices(int size) { - vertices.resize(size*3); - normals.resize(size*3); - tangents.resize(size*3); - bitangents.resize(size*3); - tex_coords.resize(size*2); - if(!bone_weights.empty()){ + vertices.resize(size * 3); + normals.resize(size * 3); + tangents.resize(size * 3); + bitangents.resize(size * 3); + tex_coords.resize(size * 2); + if (!bone_weights.empty()) { bone_weights.resize(size); - }if(!bone_ids.empty()){ + } + if (!bone_ids.empty()) { bone_ids.resize(size); } } void Model::ResizeFaces(int size) { bool success = false; - while(!success){ + while (!success) { try { - faces.resize(size*3); + faces.resize(size * 3); face_normals.resize(size); success = true; - } catch (std::bad_alloc const&) { + } catch (std::bad_alloc const &) { success = false; SDL_Delay(100); LOGE << "Vector alloc failed, trying again..." << std::endl; @@ -1663,57 +1616,55 @@ void Model::ResizeFaces(int size) { } } - void Model::calcFaceNormals() { face_normals.resize(faces.size() / 3); - #pragma omp parallel for - for(int i=0, len=faces.size()/3; i<len; i++){ - face_normals[i][0] = (vertices[faces[i*3+1]*3+1] - vertices[faces[i*3+0]*3+1])*(vertices[faces[i*3+2]*3+2] - vertices[faces[i*3+0]*3+2]) - (vertices[faces[i*3+1]*3+2] - vertices[faces[i*3+0]*3+2])*(vertices[faces[i*3+2]*3+1] - vertices[faces[i*3+0]*3+1]); - face_normals[i][1] = (vertices[faces[i*3+1]*3+2] - vertices[faces[i*3+0]*3+2])*(vertices[faces[i*3+2]*3+0] - vertices[faces[i*3+0]*3+0]) - (vertices[faces[i*3+1]*3+0] - vertices[faces[i*3+0]*3+0])*(vertices[faces[i*3+2]*3+2] - vertices[faces[i*3+0]*3+2]); - face_normals[i][2] = (vertices[faces[i*3+1]*3+0] - vertices[faces[i*3+0]*3+0])*(vertices[faces[i*3+2]*3+1] - vertices[faces[i*3+0]*3+1]) - (vertices[faces[i*3+1]*3+1] - vertices[faces[i*3+0]*3+1])*(vertices[faces[i*3+2]*3+0] - vertices[faces[i*3+0]*3+0]); +#pragma omp parallel for + for (int i = 0, len = faces.size() / 3; i < len; i++) { + face_normals[i][0] = (vertices[faces[i * 3 + 1] * 3 + 1] - vertices[faces[i * 3 + 0] * 3 + 1]) * (vertices[faces[i * 3 + 2] * 3 + 2] - vertices[faces[i * 3 + 0] * 3 + 2]) - (vertices[faces[i * 3 + 1] * 3 + 2] - vertices[faces[i * 3 + 0] * 3 + 2]) * (vertices[faces[i * 3 + 2] * 3 + 1] - vertices[faces[i * 3 + 0] * 3 + 1]); + face_normals[i][1] = (vertices[faces[i * 3 + 1] * 3 + 2] - vertices[faces[i * 3 + 0] * 3 + 2]) * (vertices[faces[i * 3 + 2] * 3 + 0] - vertices[faces[i * 3 + 0] * 3 + 0]) - (vertices[faces[i * 3 + 1] * 3 + 0] - vertices[faces[i * 3 + 0] * 3 + 0]) * (vertices[faces[i * 3 + 2] * 3 + 2] - vertices[faces[i * 3 + 0] * 3 + 2]); + face_normals[i][2] = (vertices[faces[i * 3 + 1] * 3 + 0] - vertices[faces[i * 3 + 0] * 3 + 0]) * (vertices[faces[i * 3 + 2] * 3 + 1] - vertices[faces[i * 3 + 0] * 3 + 1]) - (vertices[faces[i * 3 + 1] * 3 + 1] - vertices[faces[i * 3 + 0] * 3 + 1]) * (vertices[faces[i * 3 + 2] * 3 + 0] - vertices[faces[i * 3 + 0] * 3 + 0]); } } void Model::calcNormals() { normals.resize(vertices.size()); - #pragma omp parallel for - for(int i=0, len=vertices.size()/3; i<len; i++){ - normals[i*3+0]=0; - normals[i*3+1]=0; - normals[i*3+2]=0; +#pragma omp parallel for + for (int i = 0, len = vertices.size() / 3; i < len; i++) { + normals[i * 3 + 0] = 0; + normals[i * 3 + 1] = 0; + normals[i * 3 + 2] = 0; } - //vec3 edge1,edge2; + // vec3 edge1,edge2; calcFaceNormals(); - for(int i=0, len=faces.size()/3; i<len; i++){ - normals[faces[i*3+0]*3+0]+=face_normals[i].x(); - normals[faces[i*3+0]*3+1]+=face_normals[i].y(); - normals[faces[i*3+0]*3+2]+=face_normals[i].z(); - - normals[faces[i*3+1]*3+0]+=face_normals[i].x(); - normals[faces[i*3+1]*3+1]+=face_normals[i].y(); - normals[faces[i*3+1]*3+2]+=face_normals[i].z(); - - normals[faces[i*3+2]*3+0]+=face_normals[i].x(); - normals[faces[i*3+2]*3+1]+=face_normals[i].y(); - normals[faces[i*3+2]*3+2]+=face_normals[i].z(); - } - #pragma omp parallel for - for(int i=0, len=vertices.size()/3; i<len; i++){ - float length=sqrtf(square(normals[i*3+0])+square(normals[i*3+1])+square(normals[i*3+2])); - - //For some reasons the normals are sometimes 0,0,0 We have to check for this to prevent NaN. - if( length != 0.0f ) - { - normals[i*3+0]/=length; - normals[i*3+1]/=length; - normals[i*3+2]/=length; + for (int i = 0, len = faces.size() / 3; i < len; i++) { + normals[faces[i * 3 + 0] * 3 + 0] += face_normals[i].x(); + normals[faces[i * 3 + 0] * 3 + 1] += face_normals[i].y(); + normals[faces[i * 3 + 0] * 3 + 2] += face_normals[i].z(); + + normals[faces[i * 3 + 1] * 3 + 0] += face_normals[i].x(); + normals[faces[i * 3 + 1] * 3 + 1] += face_normals[i].y(); + normals[faces[i * 3 + 1] * 3 + 2] += face_normals[i].z(); + + normals[faces[i * 3 + 2] * 3 + 0] += face_normals[i].x(); + normals[faces[i * 3 + 2] * 3 + 1] += face_normals[i].y(); + normals[faces[i * 3 + 2] * 3 + 2] += face_normals[i].z(); + } +#pragma omp parallel for + for (int i = 0, len = vertices.size() / 3; i < len; i++) { + float length = sqrtf(square(normals[i * 3 + 0]) + square(normals[i * 3 + 1]) + square(normals[i * 3 + 2])); + + // For some reasons the normals are sometimes 0,0,0 We have to check for this to prevent NaN. + if (length != 0.0f) { + normals[i * 3 + 0] /= length; + normals[i * 3 + 1] /= length; + normals[i * 3 + 2] /= length; } } - #pragma omp parallel for - for(int i=0, len=faces.size()/3; i<len; i++){ +#pragma omp parallel for + for (int i = 0, len = faces.size() / 3; i < len; i++) { face_normals[i] = normalize(face_normals[i]); } } @@ -1722,18 +1673,17 @@ void Model::calcTangents() { tangents.resize(vertices.size()); bitangents.resize(vertices.size()); #pragma omp parallel for - for(int i=0, len=vertices.size(); i<len; i+=3){ - tangents[i+0]=0; - tangents[i+1]=0; - tangents[i+2]=0; + for (int i = 0, len = vertices.size(); i < len; i += 3) { + tangents[i + 0] = 0; + tangents[i + 1] = 0; + tangents[i + 2] = 0; - bitangents[i+0]=0; - bitangents[i+1]=0; - bitangents[i+2]=0; + bitangents[i + 0] = 0; + bitangents[i + 1] = 0; + bitangents[i + 2] = 0; } #pragma omp parallel for - for (long a=0, len=faces.size()/3; a<len; a++) - { + for (long a = 0, len = faces.size() / 3; a < len; a++) { float x1, x2, y1, y2, z1, z2; float s1, s2, t1, t2; float r; @@ -1741,115 +1691,115 @@ void Model::calcTangents() { vec3 sdir; vec3 tdir; - x1 = vertices[faces[a*3+1]*3+0] - vertices[faces[a*3+0]*3+0]; - x2 = vertices[faces[a*3+2]*3+0] - vertices[faces[a*3+0]*3+0]; - y1 = vertices[faces[a*3+1]*3+1] - vertices[faces[a*3+0]*3+1]; - y2 = vertices[faces[a*3+2]*3+1] - vertices[faces[a*3+0]*3+1]; - z1 = vertices[faces[a*3+1]*3+2] - vertices[faces[a*3+0]*3+2]; - z2 = vertices[faces[a*3+2]*3+2] - vertices[faces[a*3+0]*3+2]; + x1 = vertices[faces[a * 3 + 1] * 3 + 0] - vertices[faces[a * 3 + 0] * 3 + 0]; + x2 = vertices[faces[a * 3 + 2] * 3 + 0] - vertices[faces[a * 3 + 0] * 3 + 0]; + y1 = vertices[faces[a * 3 + 1] * 3 + 1] - vertices[faces[a * 3 + 0] * 3 + 1]; + y2 = vertices[faces[a * 3 + 2] * 3 + 1] - vertices[faces[a * 3 + 0] * 3 + 1]; + z1 = vertices[faces[a * 3 + 1] * 3 + 2] - vertices[faces[a * 3 + 0] * 3 + 2]; + z2 = vertices[faces[a * 3 + 2] * 3 + 2] - vertices[faces[a * 3 + 0] * 3 + 2]; - s1 = tex_coords[faces[a*3+1]*2+0] - tex_coords[faces[a*3+0]*2+0]; - s2 = tex_coords[faces[a*3+2]*2+0] - tex_coords[faces[a*3+0]*2+0]; - t1 = tex_coords[faces[a*3+1]*2+1] - tex_coords[faces[a*3+0]*2+1]; - t2 = tex_coords[faces[a*3+2]*2+1] - tex_coords[faces[a*3+0]*2+1]; + s1 = tex_coords[faces[a * 3 + 1] * 2 + 0] - tex_coords[faces[a * 3 + 0] * 2 + 0]; + s2 = tex_coords[faces[a * 3 + 2] * 2 + 0] - tex_coords[faces[a * 3 + 0] * 2 + 0]; + t1 = tex_coords[faces[a * 3 + 1] * 2 + 1] - tex_coords[faces[a * 3 + 0] * 2 + 1]; + t2 = tex_coords[faces[a * 3 + 2] * 2 + 1] - tex_coords[faces[a * 3 + 0] * 2 + 1]; float denom = (s1 * t2 - s2 * t1); - if(denom != 0.0f) { + if (denom != 0.0f) { r = 1.0F / denom; } else { r = 99999.0f; } sdir = vec3((t2 * x1 - t1 * x2) * r, - (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r); + (t2 * y1 - t1 * y2) * r, + (t2 * z1 - t1 * z2) * r); tdir = vec3((s1 * x2 - s2 * x1) * r, - (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r); + (s1 * y2 - s2 * y1) * r, + (s1 * z2 - s2 * z1) * r); - #pragma omp critical +#pragma omp critical { - tangents[faces[a*3+0]*3+0] += sdir.x(); - tangents[faces[a*3+0]*3+1] += sdir.y(); - tangents[faces[a*3+0]*3+2] += sdir.z(); - tangents[faces[a*3+1]*3+0] += sdir.x(); - tangents[faces[a*3+1]*3+1] += sdir.y(); - tangents[faces[a*3+1]*3+2] += sdir.z(); - tangents[faces[a*3+2]*3+0] += sdir.x(); - tangents[faces[a*3+2]*3+1] += sdir.y(); - tangents[faces[a*3+2]*3+2] += sdir.z(); - - bitangents[faces[a*3+0]*3+0] += tdir.x(); - bitangents[faces[a*3+0]*3+1] += tdir.y(); - bitangents[faces[a*3+0]*3+2] += tdir.z(); - bitangents[faces[a*3+1]*3+0] += tdir.x(); - bitangents[faces[a*3+1]*3+1] += tdir.y(); - bitangents[faces[a*3+1]*3+2] += tdir.z(); - bitangents[faces[a*3+2]*3+0] += tdir.x(); - bitangents[faces[a*3+2]*3+1] += tdir.y(); - bitangents[faces[a*3+2]*3+2] += tdir.z(); + tangents[faces[a * 3 + 0] * 3 + 0] += sdir.x(); + tangents[faces[a * 3 + 0] * 3 + 1] += sdir.y(); + tangents[faces[a * 3 + 0] * 3 + 2] += sdir.z(); + tangents[faces[a * 3 + 1] * 3 + 0] += sdir.x(); + tangents[faces[a * 3 + 1] * 3 + 1] += sdir.y(); + tangents[faces[a * 3 + 1] * 3 + 2] += sdir.z(); + tangents[faces[a * 3 + 2] * 3 + 0] += sdir.x(); + tangents[faces[a * 3 + 2] * 3 + 1] += sdir.y(); + tangents[faces[a * 3 + 2] * 3 + 2] += sdir.z(); + + bitangents[faces[a * 3 + 0] * 3 + 0] += tdir.x(); + bitangents[faces[a * 3 + 0] * 3 + 1] += tdir.y(); + bitangents[faces[a * 3 + 0] * 3 + 2] += tdir.z(); + bitangents[faces[a * 3 + 1] * 3 + 0] += tdir.x(); + bitangents[faces[a * 3 + 1] * 3 + 1] += tdir.y(); + bitangents[faces[a * 3 + 1] * 3 + 2] += tdir.z(); + bitangents[faces[a * 3 + 2] * 3 + 0] += tdir.x(); + bitangents[faces[a * 3 + 2] * 3 + 1] += tdir.y(); + bitangents[faces[a * 3 + 2] * 3 + 2] += tdir.z(); } } #pragma omp parallel for - for(int i=0, len=vertices.size(); i<len; i+=3) { - vec3 n(normals[i+0],normals[i+1],normals[i+2]); - vec3 t(tangents[i+0],tangents[i+1],tangents[i+2]); + for (int i = 0, len = vertices.size(); i < len; i += 3) { + vec3 n(normals[i + 0], normals[i + 1], normals[i + 2]); + vec3 t(tangents[i + 0], tangents[i + 1], tangents[i + 2]); // Gram-Schmidt orthogonalize vec3 tangent = normalize(t - n * dot(n, t)); - - tangents[i+0]=tangent.x(); - tangents[i+1]=tangent.y(); - tangents[i+2]=tangent.z(); + + tangents[i + 0] = tangent.x(); + tangents[i + 1] = tangent.y(); + tangents[i + 2] = tangent.z(); } #pragma omp parallel for - for(int i=0, len=vertices.size(); i<len; i+=3){ - vec3 n(normals[i+0],normals[i+1],normals[i+2]); - vec3 t(bitangents[i+0],bitangents[i+1],bitangents[i+2]); + for (int i = 0, len = vertices.size(); i < len; i += 3) { + vec3 n(normals[i + 0], normals[i + 1], normals[i + 2]); + vec3 t(bitangents[i + 0], bitangents[i + 1], bitangents[i + 2]); // Gram-Schmidt orthogonalize vec3 tangent = normalize(t - n * dot(n, t)); - - bitangents[i+0]=tangent.x(); - bitangents[i+1]=tangent.y(); - bitangents[i+2]=tangent.z(); + + bitangents[i + 0] = tangent.x(); + bitangents[i + 1] = tangent.y(); + bitangents[i + 2] = tangent.z(); } } -//Set up simp_vertex buffer object +// Set up simp_vertex buffer object void Model::createVBO() { CHECK_GL_ERROR(); - - VBO_vertices.Fill(kVBOFloat | kVBOStatic, vertices.size()*sizeof(float), &vertices[0]); - if(!normals.empty()){ - VBO_normals.Fill(kVBOFloat | kVBOStatic, vertices.size()*sizeof(float), &normals[0]); + + VBO_vertices.Fill(kVBOFloat | kVBOStatic, vertices.size() * sizeof(float), &vertices[0]); + if (!normals.empty()) { + VBO_normals.Fill(kVBOFloat | kVBOStatic, vertices.size() * sizeof(float), &normals[0]); } CHECK_GL_ERROR(); - if(!tangents.empty()){ - VBO_tangents.Fill(kVBOFloat | kVBOStatic, vertices.size()*sizeof(float), &tangents[0]); + if (!tangents.empty()) { + VBO_tangents.Fill(kVBOFloat | kVBOStatic, vertices.size() * sizeof(float), &tangents[0]); } CHECK_GL_ERROR(); - if(!bitangents.empty()){ - VBO_bitangents.Fill(kVBOFloat | kVBOStatic, vertices.size()*sizeof(float), &bitangents[0]); + if (!bitangents.empty()) { + VBO_bitangents.Fill(kVBOFloat | kVBOStatic, vertices.size() * sizeof(float), &bitangents[0]); } - + CHECK_GL_ERROR(); - VBO_tex_coords.Fill(kVBOFloat | kVBOStatic, vertices.size()/3*2*sizeof(float), &tex_coords[0]); - + VBO_tex_coords.Fill(kVBOFloat | kVBOStatic, vertices.size() / 3 * 2 * sizeof(float), &tex_coords[0]); + CHECK_GL_ERROR(); if (!tex_coords2.empty()) { - VBO_tex_coords2.Fill(kVBOFloat | kVBOStatic, vertices.size()/3*2*sizeof(float), &tex_coords2[0]); + VBO_tex_coords2.Fill(kVBOFloat | kVBOStatic, vertices.size() / 3 * 2 * sizeof(float), &tex_coords2[0]); } - + if (!aux.empty()) { - VBO_aux.Fill(kVBOFloat | kVBOStatic, vertices.size()*sizeof(float), &aux[0]); + VBO_aux.Fill(kVBOFloat | kVBOStatic, vertices.size() * sizeof(float), &aux[0]); } - + CHECK_GL_ERROR(); - VBO_faces.Fill(kVBOElement | kVBOStatic, faces.size()*sizeof(GLuint), &faces[0]); - + VBO_faces.Fill(kVBOElement | kVBOStatic, faces.size() * sizeof(GLuint), &faces[0]); + CHECK_GL_ERROR(); Graphics *graphics = Graphics::Instance(); graphics->BindArrayVBO(0); @@ -1867,63 +1817,68 @@ struct ChildHit { class ChildHitCompare { public: - bool operator()(const ChildHit &a, const ChildHit &b) { - return a.time < b.time; - } + bool operator()(const ChildHit &a, const ChildHit &b) { + return a.time < b.time; + } }; -//Check a line against the model for collision -int Model::lineCheck(const vec3& p1,const vec3& p2, vec3* p, vec3 *normal, bool backface) const { - if(!sphere_line_intersection(p1,p2,bounding_sphere_origin,bounding_sphere_radius))return -1; - +// Check a line against the model for collision +int Model::lineCheck(const vec3 &p1, const vec3 &p2, vec3 *p, vec3 *normal, bool backface) const { + if (!sphere_line_intersection(p1, p2, bounding_sphere_origin, bounding_sphere_radius)) return -1; + float distance; - float olddistance=0; - int intersecting=0; - int firstintersecting=-1; + float olddistance = 0; + int intersecting = 0; + int firstintersecting = -1; vec3 point; vec3 end = p2; int face_index, vert_index; vec3 points[3]; - for (int j=0, len=faces.size()/3;j<len;j++){ - face_index = j*3; - for(unsigned k=0; k<3; ++k){ - vert_index = faces[face_index+k]*3; - points[k][0] = vertices[vert_index+0]; - points[k][1] = vertices[vert_index+1]; - points[k][2] = vertices[vert_index+2]; - } - intersecting=LineFacet(p1,end,points[0],points[1],points[2],&point,face_normals[j]); - if(intersecting){ - distance=distance_squared(p1, point); - if(distance<olddistance||firstintersecting==-1){ - olddistance=distance; firstintersecting=j; if(p)*p=point; end=point; if(normal)*normal = face_normals[j];} + for (int j = 0, len = faces.size() / 3; j < len; j++) { + face_index = j * 3; + for (unsigned k = 0; k < 3; ++k) { + vert_index = faces[face_index + k] * 3; + points[k][0] = vertices[vert_index + 0]; + points[k][1] = vertices[vert_index + 1]; + points[k][2] = vertices[vert_index + 2]; + } + intersecting = LineFacet(p1, end, points[0], points[1], points[2], &point, face_normals[j]); + if (intersecting) { + distance = distance_squared(p1, point); + if (distance < olddistance || firstintersecting == -1) { + olddistance = distance; + firstintersecting = j; + if (p) *p = point; + end = point; + if (normal) *normal = face_normals[j]; + } } } - if(firstintersecting!=-1)return firstintersecting; + if (firstintersecting != -1) return firstintersecting; return -1; } -//Check a line against the model for collision against front face only -int Model::lineCheckNoBackface(const vec3& p1,const vec3& p2, vec3* p, vec3 *normal) const { +// Check a line against the model for collision against front face only +int Model::lineCheckNoBackface(const vec3 &p1, const vec3 &p2, vec3 *p, vec3 *normal) const { return lineCheck(p1, p2, p, normal, false); } float StaticCalcAverageTriangleEdge(const std::vector<unsigned> &faces, const std::vector<float> &vertices) { float total_vert = 0.0f; int num_sample = 0; - for(int i=0, len=faces.size(); i<len; i+=3){ + for (int i = 0, len = faces.size(); i < len; i += 3) { const float *vert[3]; - for(int j=0; j<3; j++) { - int vert_index = faces[i+j]; - vert[j] = &vertices[vert_index*3]; - } - for(int j=0; j<3; j++) { - int next = (j+1)%3; - float vert_distance = sqrtf( square(vert[j][0]-vert[next][0]) + - square(vert[j][1]-vert[next][1]) + - square(vert[j][2]-vert[next][2])); - if(vert_distance != 0.0f){ + for (int j = 0; j < 3; j++) { + int vert_index = faces[i + j]; + vert[j] = &vertices[vert_index * 3]; + } + for (int j = 0; j < 3; j++) { + int next = (j + 1) % 3; + float vert_distance = sqrtf(square(vert[j][0] - vert[next][0]) + + square(vert[j][1] - vert[next][1]) + + square(vert[j][2] - vert[next][2])); + if (vert_distance != 0.0f) { ++num_sample; total_vert += vert_distance; } @@ -1936,96 +1891,96 @@ void Model::CalcAverageTriangleEdge() { average_triangle_edge_length = StaticCalcAverageTriangleEdge(faces, vertices); } -void Model::CopyFacesFromModel( const Model &source_model, const std::vector<int> ©_faces ) { +void Model::CopyFacesFromModel(const Model &source_model, const std::vector<int> ©_faces) { vbo_loaded = false; vbo_enabled = false; - int num_faces = copy_faces.size(); - faces.resize(num_faces*3); + int num_faces = copy_faces.size(); + faces.resize(num_faces * 3); face_normals.resize(num_faces); - for(int i=0; i<num_faces; i++){ - const int index = i*3; - const int copy_index = copy_faces[i]*3; - faces[index+0] = source_model.faces[copy_index+0]; - faces[index+1] = source_model.faces[copy_index+1]; - faces[index+2] = source_model.faces[copy_index+2]; + for (int i = 0; i < num_faces; i++) { + const int index = i * 3; + const int copy_index = copy_faces[i] * 3; + faces[index + 0] = source_model.faces[copy_index + 0]; + faces[index + 1] = source_model.faces[copy_index + 1]; + faces[index + 2] = source_model.faces[copy_index + 2]; face_normals[i] = source_model.face_normals[copy_faces[i]]; } - std::vector<bool> vertex_included(source_model.vertices.size()/3, false); - for(int i=0; i<num_faces; i++){ - const int index = i*3; - vertex_included[faces[index+0]] = true; - vertex_included[faces[index+1]] = true; - vertex_included[faces[index+2]] = true; + std::vector<bool> vertex_included(source_model.vertices.size() / 3, false); + for (int i = 0; i < num_faces; i++) { + const int index = i * 3; + vertex_included[faces[index + 0]] = true; + vertex_included[faces[index + 1]] = true; + vertex_included[faces[index + 2]] = true; } - std::vector<int> vertex_index(source_model.vertices.size()/3); + std::vector<int> vertex_index(source_model.vertices.size() / 3); std::vector<int> reverse_vertex_index; { int counter = 0; - for(unsigned i=0; i<vertex_index.size(); i++){ - if(vertex_included[i]){ + for (unsigned i = 0; i < vertex_index.size(); i++) { + if (vertex_included[i]) { reverse_vertex_index.push_back(i); vertex_index[i] = counter++; } } } - - for(int i=0; i<num_faces; i++){ - const int index = i*3; - faces[index+0] = vertex_index[faces[index+0]]; - faces[index+1] = vertex_index[faces[index+1]]; - faces[index+2] = vertex_index[faces[index+2]]; + + for (int i = 0; i < num_faces; i++) { + const int index = i * 3; + faces[index + 0] = vertex_index[faces[index + 0]]; + faces[index + 1] = vertex_index[faces[index + 1]]; + faces[index + 2] = vertex_index[faces[index + 2]]; } int num_vertices = reverse_vertex_index.size(); - vertices.resize(num_vertices*3); - normals.resize(num_vertices*3); + vertices.resize(num_vertices * 3); + normals.resize(num_vertices * 3); - if(!source_model.tangents.empty()){ - tangents.resize(num_vertices*3); - bitangents.resize(num_vertices*3); + if (!source_model.tangents.empty()) { + tangents.resize(num_vertices * 3); + bitangents.resize(num_vertices * 3); } - tex_coords.resize(num_vertices*2); - if(!source_model.tex_coords2.empty()){ - tex_coords2.resize(num_vertices*2); + tex_coords.resize(num_vertices * 2); + if (!source_model.tex_coords2.empty()) { + tex_coords2.resize(num_vertices * 2); } - for(int i=0; i<num_vertices; i++){ - const int index = i*3; - const int copy_index = reverse_vertex_index[i]*3; - vertices[index+0] = source_model.vertices[copy_index+0]; - vertices[index+1] = source_model.vertices[copy_index+1]; - vertices[index+2] = source_model.vertices[copy_index+2]; + for (int i = 0; i < num_vertices; i++) { + const int index = i * 3; + const int copy_index = reverse_vertex_index[i] * 3; + vertices[index + 0] = source_model.vertices[copy_index + 0]; + vertices[index + 1] = source_model.vertices[copy_index + 1]; + vertices[index + 2] = source_model.vertices[copy_index + 2]; + + normals[index + 0] = source_model.normals[copy_index + 0]; + normals[index + 1] = source_model.normals[copy_index + 1]; + normals[index + 2] = source_model.normals[copy_index + 2]; - normals[index+0] = source_model.normals[copy_index+0]; - normals[index+1] = source_model.normals[copy_index+1]; - normals[index+2] = source_model.normals[copy_index+2]; - - if(!source_model.tangents.empty()){ - tangents[index+0] = source_model.tangents[copy_index+0]; - tangents[index+1] = source_model.tangents[copy_index+1]; - tangents[index+2] = source_model.tangents[copy_index+2]; + if (!source_model.tangents.empty()) { + tangents[index + 0] = source_model.tangents[copy_index + 0]; + tangents[index + 1] = source_model.tangents[copy_index + 1]; + tangents[index + 2] = source_model.tangents[copy_index + 2]; - bitangents[index+0] = source_model.bitangents[copy_index+0]; - bitangents[index+1] = source_model.bitangents[copy_index+1]; - bitangents[index+2] = source_model.bitangents[copy_index+2]; + bitangents[index + 0] = source_model.bitangents[copy_index + 0]; + bitangents[index + 1] = source_model.bitangents[copy_index + 1]; + bitangents[index + 2] = source_model.bitangents[copy_index + 2]; } - const int tex_index = i*2; - const int copy_tex_index = reverse_vertex_index[i]*2; - - tex_coords[tex_index+0] = source_model.tex_coords[copy_tex_index+0]; - tex_coords[tex_index+1] = source_model.tex_coords[copy_tex_index+1]; - - if(!source_model.tex_coords2.empty()){ - tex_coords2[tex_index+0] = source_model.tex_coords2[copy_tex_index+0]; - tex_coords2[tex_index+1] = source_model.tex_coords2[copy_tex_index+1]; + const int tex_index = i * 2; + const int copy_tex_index = reverse_vertex_index[i] * 2; + + tex_coords[tex_index + 0] = source_model.tex_coords[copy_tex_index + 0]; + tex_coords[tex_index + 1] = source_model.tex_coords[copy_tex_index + 1]; + + if (!source_model.tex_coords2.empty()) { + tex_coords2[tex_index + 0] = source_model.tex_coords2[copy_tex_index + 0]; + tex_coords2[tex_index + 1] = source_model.tex_coords2[copy_tex_index + 1]; } } @@ -2033,40 +1988,40 @@ void Model::CopyFacesFromModel( const Model &source_model, const std::vector<int vbo_enabled = true; } -void Model::LoadObjMorph(const std::string &rel_path, const std::string &rel_base_path){ +void Model::LoadObjMorph(const std::string &rel_path, const std::string &rel_base_path) { Dispose(); char abs_path[kPathSize]; ModID modsource; - if( FindFilePath(rel_path.c_str(), abs_path, kPathSize, kDataPaths | kModPaths, true, NULL, &modsource) == -1 ){ + if (FindFilePath(rel_path.c_str(), abs_path, kPathSize, kDataPaths | kModPaths, true, NULL, &modsource) == -1) { FatalError("Error", "Could not find morph file: \"%s\"", rel_path.c_str()); } bool load_model = true; - + size_t read_count = 0; unsigned short checksum = Checksum(abs_path); FILE *cache_file = my_fopen((GetWritePath(modsource) + rel_path + ".mcache").c_str(), "rb"); - if(cache_file){ + if (cache_file) { unsigned short file_checksum = 0; read_count = fread(&file_checksum, sizeof(unsigned short), 1, cache_file); LOG_ASSERT(read_count == 1); unsigned short version; read_count = fread(&version, sizeof(unsigned short), 1, cache_file); LOG_ASSERT(read_count == 1); - if(checksum == file_checksum && version == _morph_cache_version){ + if (checksum == file_checksum && version == _morph_cache_version) { size_t count = 0; read_count = fread(&count, sizeof(int), 1, cache_file); LOG_ASSERT(read_count == 1); ResizeVertices(count); - read_count = fread(&vertices[0], sizeof(GLfloat), count*3, cache_file); - LOG_ASSERT_EQ(read_count, count*3); - read_count = fread(&tex_coords[0], sizeof(GLfloat), count*2, cache_file); - LOG_ASSERT_EQ(read_count, count*2); + read_count = fread(&vertices[0], sizeof(GLfloat), count * 3, cache_file); + LOG_ASSERT_EQ(read_count, count * 3); + read_count = fread(&tex_coords[0], sizeof(GLfloat), count * 2, cache_file); + LOG_ASSERT_EQ(read_count, count * 2); load_model = false; } fclose(cache_file); } - + if (load_model) { // Load base model to get bounding box ObjFileStats obj_stats; @@ -2077,16 +2032,16 @@ void Model::LoadObjMorph(const std::string &rel_path, const std::string &rel_bas TempModel morph_model; LoadTempModel(rel_path, morph_model, obj_stats); - for(unsigned i=0; i<base_model.fc*3; ++i){ - vertices.push_back(base_model.vertices[base_model.vert_indices[i]*3+0]); - vertices.push_back(base_model.vertices[base_model.vert_indices[i]*3+1]); - vertices.push_back(base_model.vertices[base_model.vert_indices[i]*3+2]); + for (unsigned i = 0; i < base_model.fc * 3; ++i) { + vertices.push_back(base_model.vertices[base_model.vert_indices[i] * 3 + 0]); + vertices.push_back(base_model.vertices[base_model.vert_indices[i] * 3 + 1]); + vertices.push_back(base_model.vertices[base_model.vert_indices[i] * 3 + 2]); } std::vector<GLfloat> old_tex_coords; - for(unsigned i=0; i<base_model.fc*3; ++i){ - old_tex_coords.push_back(base_model.tex_coords[base_model.tex_indices[i]*2+0]); - old_tex_coords.push_back(base_model.tex_coords[base_model.tex_indices[i]*2+1]); + for (unsigned i = 0; i < base_model.fc * 3; ++i) { + old_tex_coords.push_back(base_model.tex_coords[base_model.tex_indices[i] * 2 + 0]); + old_tex_coords.push_back(base_model.tex_coords[base_model.tex_indices[i] * 2 + 1]); } std::vector<GLfloat> old_vertices = vertices; @@ -2094,138 +2049,136 @@ void Model::LoadObjMorph(const std::string &rel_path, const std::string &rel_bas // Load morph vertices and tex coords vertices.clear(); tex_coords.clear(); - for(unsigned i=0; i<base_model.fc*3; ++i){ - vertices.push_back(morph_model.vertices[morph_model.vert_indices[i]*3+0]); - vertices.push_back(morph_model.vertices[morph_model.vert_indices[i]*3+1]); - vertices.push_back(morph_model.vertices[morph_model.vert_indices[i]*3+2]); + for (unsigned i = 0; i < base_model.fc * 3; ++i) { + vertices.push_back(morph_model.vertices[morph_model.vert_indices[i] * 3 + 0]); + vertices.push_back(morph_model.vertices[morph_model.vert_indices[i] * 3 + 1]); + vertices.push_back(morph_model.vertices[morph_model.vert_indices[i] * 3 + 2]); } - for(unsigned i=0; i<base_model.fc*3; ++i){ - tex_coords.push_back(morph_model.tex_coords[morph_model.tex_indices[i]*2+0]); - tex_coords.push_back(morph_model.tex_coords[morph_model.tex_indices[i]*2+1]); + for (unsigned i = 0; i < base_model.fc * 3; ++i) { + tex_coords.push_back(morph_model.tex_coords[morph_model.tex_indices[i] * 2 + 0]); + tex_coords.push_back(morph_model.tex_coords[morph_model.tex_indices[i] * 2 + 1]); } - for(unsigned i=0, len=vertices.size(); i<len; ++i){ + for (unsigned i = 0, len = vertices.size(); i < len; ++i) { vertices[i] -= old_vertices[i]; } - for(unsigned i=0, len=tex_coords.size(); i<len; ++i){ + for (unsigned i = 0, len = tex_coords.size(); i < len; ++i) { tex_coords[i] -= old_tex_coords[i]; } - + FILE *cache_file = my_fopen((GetWritePath(modsource) + rel_path + ".mcache").c_str(), "wb"); - if(cache_file){ + if (cache_file) { fwrite(&checksum, sizeof(unsigned short), 1, cache_file); fwrite(&_morph_cache_version, sizeof(unsigned short), 1, cache_file); - size_t count = vertices.size()/3; + size_t count = vertices.size() / 3; fwrite(&count, sizeof(int), 1, cache_file); - fwrite(&vertices[0], sizeof(GLfloat), count*3, cache_file); - fwrite(&tex_coords[0], sizeof(GLfloat), count*2, cache_file); + fwrite(&vertices[0], sizeof(GLfloat), count * 3, cache_file); + fwrite(&tex_coords[0], sizeof(GLfloat), count * 2, cache_file); fclose(cache_file); } } } namespace { - struct VertInfo { - static const int NUM_VERT_INFO_ENTRIES = 8; - float entries[NUM_VERT_INFO_ENTRIES]; - int old_id; - }; - - bool operator<(const VertInfo &a, const VertInfo &b){ - static const int LEN = VertInfo::NUM_VERT_INFO_ENTRIES - 1; - for(int i=0; i<LEN; ++i){ - if(a.entries[i] != b.entries[i]){ - return (a.entries[i] < b.entries[i]); - } +struct VertInfo { + static const int NUM_VERT_INFO_ENTRIES = 8; + float entries[NUM_VERT_INFO_ENTRIES]; + int old_id; +}; + +bool operator<(const VertInfo &a, const VertInfo &b) { + static const int LEN = VertInfo::NUM_VERT_INFO_ENTRIES - 1; + for (int i = 0; i < LEN; ++i) { + if (a.entries[i] != b.entries[i]) { + return (a.entries[i] < b.entries[i]); } - return (a.entries[LEN] < b.entries[LEN]); } + return (a.entries[LEN] < b.entries[LEN]); +} - bool operator==(const VertInfo &a, const VertInfo &b){ - for(int i=0; i<VertInfo::NUM_VERT_INFO_ENTRIES; ++i){ - if(a.entries[i] != b.entries[i]){ - return false; - } +bool operator==(const VertInfo &a, const VertInfo &b) { + for (int i = 0; i < VertInfo::NUM_VERT_INFO_ENTRIES; ++i) { + if (a.entries[i] != b.entries[i]) { + return false; } - return true; } + return true; +} - bool operator!=(const VertInfo &a, const VertInfo &b){ - return !(a==b); - } -} // namespace "" +bool operator!=(const VertInfo &a, const VertInfo &b) { + return !(a == b); +} +} // namespace void Model::RemoveDuplicatedVerts() { - if(vertices.empty()){ + if (vertices.empty()) { DisplayError("Warning", "Calling RemoveDuplicatedVerts on empty mesh."); return; } // Sort vector of vertices so that identical vertices are neighbors std::vector<VertInfo> vert_info; - for(int i=0, vert_index=0, tc_index=0, len=vertices.size(); vert_index<len; ++i, vert_index += 3, tc_index += 2){ + for (int i = 0, vert_index = 0, tc_index = 0, len = vertices.size(); vert_index < len; ++i, vert_index += 3, tc_index += 2) { VertInfo vi; vi.old_id = i; - for(int i=0; i<3; ++i){ - vi.entries[i] = vertices[vert_index+i]; + for (int i = 0; i < 3; ++i) { + vi.entries[i] = vertices[vert_index + i]; } - if(use_tangent && !normals.empty()){ // Only check normal info if the model uses tangent - for(int i=0; i<3; ++i){ - vi.entries[i+3] = normals[vert_index+i]; + if (use_tangent && !normals.empty()) { // Only check normal info if the model uses tangent + for (int i = 0; i < 3; ++i) { + vi.entries[i + 3] = normals[vert_index + i]; } } else { - for(int i=0; i<3; ++i){ - vi.entries[i+3] = 0.0f; + for (int i = 0; i < 3; ++i) { + vi.entries[i + 3] = 0.0f; } } - if(tex_coords.empty() == false) { - for(int i=0; i<2; ++i){ - vi.entries[i+6] = tex_coords[tc_index+i]; + if (tex_coords.empty() == false) { + for (int i = 0; i < 2; ++i) { + vi.entries[i + 6] = tex_coords[tc_index + i]; } } vert_info.push_back(vi); } std::sort(vert_info.begin(), vert_info.end()); - // Collect a vector of each first unique vertex, and the mapping from each old vertex to new unique vertices + // Collect a vector of each first unique vertex, and the mapping from each old vertex to new unique vertices std::vector<int> unique; - std::vector<int> new_vert(vert_info.size(),-1); - for(int i=0, len=vert_info.size(); i<len; ++i){ - if(i==0 || vert_info[i] != vert_info[i-1]){ + std::vector<int> new_vert(vert_info.size(), -1); + for (int i = 0, len = vert_info.size(); i < len; ++i) { + if (i == 0 || vert_info[i] != vert_info[i - 1]) { unique.push_back(i); } - new_vert[vert_info[i].old_id] = unique.size()-1; + new_vert[vert_info[i].old_id] = unique.size() - 1; } // Invert to precollapse vert reorder precollapse_vert_reorder.resize(unique.size()); - for(int i=0, len=unique.size(); i<len; ++i){ + for (int i = 0, len = unique.size(); i < len; ++i) { precollapse_vert_reorder[i] = vert_info[unique[i]].old_id; } - for(unsigned int & face : faces){ + for (unsigned int &face : faces) { face = new_vert[face]; } RearrangeVertices(*this, precollapse_vert_reorder); LOGI << vert_info.size() - unique.size() << " of " << vert_info.size() << " vertices are duplicates." << std::endl; - LOGI << "New vertex size: " << vertices.size()/3 << std::endl; + LOGI << "New vertex size: " << vertices.size() / 3 << std::endl; } - void Model::RemoveDegenerateTriangles() { unsigned count = 0; unsigned index = 0; unsigned copy_index = 0; - for(int i=0, len=faces.size()/3; i<len; i++){ - if(faces[index] == faces[index+1] || - faces[index+1] == faces[index+2] || - faces[index] == faces[index+2]) - { + for (int i = 0, len = faces.size() / 3; i < len; i++) { + if (faces[index] == faces[index + 1] || + faces[index + 1] == faces[index + 2] || + faces[index] == faces[index + 2]) { count++; index += 3; continue; } faces[copy_index] = faces[index]; - faces[copy_index+1] = faces[index+1]; - faces[copy_index+2] = faces[index+2]; + faces[copy_index + 1] = faces[index + 1]; + faces[copy_index + 2] = faces[index + 2]; copy_index += 3; index += 3; } @@ -2233,7 +2186,7 @@ void Model::RemoveDegenerateTriangles() { LOGI << "Removed " << count << " degenerate triangles." << std::endl; } -void Model::CopyVertCollapse( const Model &source_model ) { +void Model::CopyVertCollapse(const Model &source_model) { RearrangeVertices(*this, source_model.precollapse_vert_reorder); RearrangeVertices(*this, source_model.optimize_vert_reorder); } @@ -2257,142 +2210,135 @@ const float _fvs_valence_boost_scale = 2.0f; const float _fvs_valence_boost_power = 0.5f; // Based on http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html -float FindVertexScore ( VertData *vertex_data ) -{ - if ( vertex_data->not_added_triangles == 0 ) - { +float FindVertexScore(VertData *vertex_data) { + if (vertex_data->not_added_triangles == 0) { // No tri needs this vertex! return -1.0f; } float score = 0.0f; int cache_pos = vertex_data->cache_pos; - if ( cache_pos < 0 ) - { + if (cache_pos < 0) { // Vertex is not in FIFO cache - no score. - } - else - { - if ( cache_pos < 3 ) - { + } else { + if (cache_pos < 3) { // This vertex was used in the last triangle, // so it has a fixed score, whichever of the three // it's in. Otherwise, you can get very different // answers depending on whether you add // the triangle 1,2,3 or 3,1,2 - which is silly. score = _fvs_last_tri_score; - } - else - { - assert ( cache_pos < (int)_vertex_cache_size ); + } else { + assert(cache_pos < (int)_vertex_cache_size); // Points for being high in the cache. - const float scaler = 1.0f / ( _vertex_cache_size - 3 ); - score = 1.0f - ( cache_pos - 3 ) * scaler; - score = pow ( score, _fvs_cache_decay_power ); + const float scaler = 1.0f / (_vertex_cache_size - 3); + score = 1.0f - (cache_pos - 3) * scaler; + score = pow(score, _fvs_cache_decay_power); } } // Bonus points for having a low number of tris still to // use the vert, so we get rid of lone verts quickly. - float ValenceBoost = pow ( (float)(vertex_data->not_added_triangles), - -_fvs_valence_boost_power ); + float ValenceBoost = pow((float)(vertex_data->not_added_triangles), + -_fvs_valence_boost_power); score += _fvs_valence_boost_scale * ValenceBoost; return score; } -void Model::PrintACMR(){ +void Model::PrintACMR() { unsigned cache_hits = 0; unsigned total = 0; std::vector<int> fifo(32, -1); unsigned index = 0; - for(unsigned int face : faces){ - for(int j : fifo){ - if(j == (int)face){ + for (unsigned int face : faces) { + for (int j : fifo) { + if (j == (int)face) { cache_hits++; break; } } fifo[index] = face; - index = (index+1)%fifo.size(); + index = (index + 1) % fifo.size(); total++; } LOGI << "Opt: " << cache_hits << " cache hits out of " << total << "." << std::endl; - LOGI << "Opt: ACMR: " << ((float)(total-cache_hits))/(float)total*3.0f << std::endl; + LOGI << "Opt: ACMR: " << ((float)(total - cache_hits)) / (float)total * 3.0f << std::endl; } void Model::OptimizeTriangleOrder() { - std::vector<TriData> tris(faces.size()/3); - std::vector<VertData> verts(vertices.size()/3); + std::vector<TriData> tris(faces.size() / 3); + std::vector<VertData> verts(vertices.size() / 3); unsigned index = 0; - for(int i=0, len=faces.size()/3; i<len; i++){ + for (int i = 0, len = faces.size() / 3; i < len; i++) { tris[i].verts[0] = faces[index++]; tris[i].verts[1] = faces[index++]; tris[i].verts[2] = faces[index++]; - for(unsigned int vert : tris[i].verts){ + for (unsigned int vert : tris[i].verts) { verts[vert].not_added_triangles++; } } - for(int i=0, len=vertices.size()/3; i<len; ++i){ + for (int i = 0, len = vertices.size() / 3; i < len; ++i) { verts[i].cache_pos = -1; verts[i].score = FindVertexScore(&verts[i]); } int best_triangle = 0; float best_score = 0.0f; - for(int i=0, len=faces.size()/3; i<len; i++){ - tris[i].score = verts[tris[i].verts[0]].score + - verts[tris[i].verts[1]].score + + for (int i = 0, len = faces.size() / 3; i < len; i++) { + tris[i].score = verts[tris[i].verts[0]].score + + verts[tris[i].verts[1]].score + verts[tris[i].verts[2]].score; - if(tris[i].score > best_score){ + if (tris[i].score > best_score) { best_score = tris[i].score; best_triangle = i; } } - int num_faces = faces.size()/3;; - std::vector<int> lru(_vertex_cache_size,-1); + int num_faces = faces.size() / 3; + ; + std::vector<int> lru(_vertex_cache_size, -1); std::vector<unsigned> draw_list(num_faces); int draw_list_index = 0; - while(draw_list_index < num_faces){ + while (draw_list_index < num_faces) { draw_list[draw_list_index++] = best_triangle; - if(draw_list_index == num_faces){ + if (draw_list_index == num_faces) { break; } tris[best_triangle].added = true; // Update not_added_triangles - for(unsigned int vert_id : tris[best_triangle].verts){ + for (unsigned int vert_id : tris[best_triangle].verts) { --verts[vert_id].not_added_triangles; } // Update LRU cache - for(unsigned int vert_id : tris[best_triangle].verts){ + for (unsigned int vert_id : tris[best_triangle].verts) { int cp = verts[vert_id].cache_pos; // If vert is in cache, remove it and slide other verts down - if(cp != -1){ - for(unsigned j=cp; j<_vertex_cache_size; ++j){ - if(j == _vertex_cache_size-1){ + if (cp != -1) { + for (unsigned j = cp; j < _vertex_cache_size; ++j) { + if (j == _vertex_cache_size - 1) { lru[j] = -1; } else { - lru[j] = lru[j+1]; - if(lru[j] != -1){ + lru[j] = lru[j + 1]; + if (lru[j] != -1) { verts[lru[j]].cache_pos--; } } } } // Slide other verts up and add vert to cache - for(int j=_vertex_cache_size-1; j>=0; --j){ - if(lru[j] != -1){ + for (int j = _vertex_cache_size - 1; j >= 0; --j) { + if (lru[j] != -1) { verts[lru[j]].cache_pos++; - if(j >= (int)_vertex_cache_size-1){ - verts[lru[j]].cache_pos = -1; //Out of cache entirely + if (j >= (int)_vertex_cache_size - 1) { + verts[lru[j]].cache_pos = -1; // Out of cache entirely } verts[lru[j]].score = FindVertexScore(&verts[lru[j]]); } - if(j != 0){ - lru[j] = lru[j-1]; + if (j != 0) { + lru[j] = lru[j - 1]; } } lru[0] = vert_id; @@ -2403,14 +2349,14 @@ void Model::OptimizeTriangleOrder() { // thave have a vertex in the LRU cache best_score = 0.0f; best_triangle = -1; - for(int i=0; i<num_faces; ++i){ - if(tris[i].added){ + for (int i = 0; i < num_faces; ++i) { + if (tris[i].added) { continue; } - tris[i].score = verts[tris[i].verts[0]].score + - verts[tris[i].verts[1]].score + + tris[i].score = verts[tris[i].verts[0]].score + + verts[tris[i].verts[1]].score + verts[tris[i].verts[2]].score; - if(best_triangle == -1 || tris[i].score > best_score){ + if (best_triangle == -1 || tris[i].score > best_score) { best_score = tris[i].score; best_triangle = i; } @@ -2419,7 +2365,7 @@ void Model::OptimizeTriangleOrder() { { unsigned index = 0; - for(unsigned int i : draw_list){ + for (unsigned int i : draw_list) { faces[index++] = tris[i].verts[0]; faces[index++] = tris[i].verts[1]; faces[index++] = tris[i].verts[2]; @@ -2427,26 +2373,21 @@ void Model::OptimizeTriangleOrder() { } } - void Model::OptimizeVertexOrder() { - std::vector<int> order(vertices.size()/3, -1); + std::vector<int> order(vertices.size() / 3, -1); unsigned index = 0; - for(unsigned int & face : faces){ - if(order[face] == -1){ - order[face] = index++; + for (unsigned int &face : faces) { + if (order[face] == -1) { + order[face] = index++; } face = order[face]; } optimize_vert_reorder.clear(); optimize_vert_reorder.resize(index, -1); - for(int i=0, len=order.size(); i<len; i++) - { - if( order[i] >= 0 && order[i] < (int)optimize_vert_reorder.size() ) - { + for (int i = 0, len = order.size(); i < len; i++) { + if (order[i] >= 0 && order[i] < (int)optimize_vert_reorder.size()) { optimize_vert_reorder[order[i]] = i; - } - else - { + } else { LOGW << "Oddity when running " << __FUNCTION__ << ", order[i] is out of bounds, value is " << order[i] << " on index " << i << std::endl; } } @@ -2458,18 +2399,17 @@ struct edge { }; class TriScoreSorter { -public: + public: bool operator()(const TriData &a, const TriData &b) { return a.score > b.score; } }; -void Model::SortTrianglesBackToFront( const vec3 &camera ) -{ - std::vector<TriData> tris(faces.size()/3); +void Model::SortTrianglesBackToFront(const vec3 &camera) { + std::vector<TriData> tris(faces.size() / 3); unsigned index = 0; - for(int i=0, len=faces.size()/3; i<len; ++i){ + for (int i = 0, len = faces.size() / 3; i < len; ++i) { tris[i].added = false; tris[i].score = 0.0f; tris[i].verts[0] = faces[index++]; @@ -2478,23 +2418,26 @@ void Model::SortTrianglesBackToFront( const vec3 &camera ) } vec3 center; - for(int i=0, len=faces.size()/3; i<len; ++i){ - center[0] = (vertices[tris[i].verts[0]*3+0] + - vertices[tris[i].verts[1]*3+0] + - vertices[tris[i].verts[2]*3+0])/3.0f; - center[1] = (vertices[tris[i].verts[0]*3+1] + - vertices[tris[i].verts[1]*3+1] + - vertices[tris[i].verts[2]*3+1])/3.0f; - center[2] = (vertices[tris[i].verts[0]*3+2] + - vertices[tris[i].verts[1]*3+2] + - vertices[tris[i].verts[2]*3+2])/3.0f; + for (int i = 0, len = faces.size() / 3; i < len; ++i) { + center[0] = (vertices[tris[i].verts[0] * 3 + 0] + + vertices[tris[i].verts[1] * 3 + 0] + + vertices[tris[i].verts[2] * 3 + 0]) / + 3.0f; + center[1] = (vertices[tris[i].verts[0] * 3 + 1] + + vertices[tris[i].verts[1] * 3 + 1] + + vertices[tris[i].verts[2] * 3 + 1]) / + 3.0f; + center[2] = (vertices[tris[i].verts[0] * 3 + 2] + + vertices[tris[i].verts[1] * 3 + 2] + + vertices[tris[i].verts[2] * 3 + 2]) / + 3.0f; tris[i].score = distance_squared(center, camera); } std::sort(tris.begin(), tris.end(), TriScoreSorter()); index = 0; - for(auto & tri : tris){ + for (auto &tri : tris) { faces[index++] = tri.verts[0]; faces[index++] = tri.verts[1]; faces[index++] = tri.verts[2]; |