diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-02-22 08:55:48 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-11-18 15:22:10 +0100 |
commit | 9ab59b76c0ece5e261c0152af3f830f48532e103 (patch) | |
tree | ae66d456fa58d4f98ea74759bcc2bb9e2f50efae /src/model_loader | |
parent | f2f8ccc1c24ab372ffe5e932780eeb1c49a4d277 (diff) |
Fix rendering of character
Diffstat (limited to 'src/model_loader')
-rw-r--r-- | src/model_loader/ObjModelLoader.cpp | 96 |
1 files changed, 61 insertions, 35 deletions
diff --git a/src/model_loader/ObjModelLoader.cpp b/src/model_loader/ObjModelLoader.cpp index f70123a..7976bc9 100644 --- a/src/model_loader/ObjModelLoader.cpp +++ b/src/model_loader/ObjModelLoader.cpp @@ -11,10 +11,12 @@ namespace amalgine { static StringView get_line(char *str, size_t size) { - char *found_ptr = (char*)memchr(str, '\n', size); - if(!found_ptr) - found_ptr = str + size; - return { str, static_cast<size_t>(found_ptr - str) }; + for(size_t i = 0; i < size; ++i) { + char c = str[i]; + if(c == '\n' || c == '\r') + return { str, i }; + } + return { str, size }; } static bool is_whitespace(char c) { @@ -70,6 +72,29 @@ namespace amalgine { return static_cast<size_t>(found_ptr - str.data); } + struct FaceData { + int vertex_index; + int texcoord_index; + int normal_index; + }; + + // TODO: Optimize? dont use sscanf 3 times + static bool split_faces(StringView *input, FaceData *face_data) { + input->data[input->size] = '\0'; + + face_data->vertex_index = 0; + face_data->texcoord_index = 0; + face_data->normal_index = 0; + if(sscanf(input->data, "%d/%d/%d", &face_data->vertex_index, &face_data->texcoord_index, &face_data->normal_index) == 3) + return true; + + face_data->texcoord_index = 0; + if(sscanf(input->data, "%d//%d", &face_data->vertex_index, &face_data->normal_index) == 2) + return true; + + return sscanf(input->data, "%d/%d", &face_data->vertex_index, &face_data->texcoord_index) == 2; + } + struct Material { Image *image; }; @@ -120,21 +145,22 @@ namespace amalgine { int num_columns = split_columns(column_data, ' ', columns, max_columns); if(num_columns == 3 || num_columns == 4) { bool valid = true; + // TODO: Handle these when they are not set in the below loop int vertex_indices[4]; int texture_coord_indices[4]; + int normal_indices[4]; // TODO: Use this for(int i = 0; i < num_columns; ++i) { - const int max_attributes = 3; - StringView attributes[max_attributes]; - int num_attributes = split_columns(columns[i], '/', attributes, max_attributes); - assert(num_attributes == 3); - - attributes[0].data[attributes[0].size] = '\0'; - attributes[1].data[attributes[1].size] = '\0'; - attributes[2].data[attributes[2].size] = '\0'; + FaceData face_data; + if(!split_faces(&columns[i], &face_data)) { + valid = false; + abort(); + break; + } - vertex_indices[i] = atoi(attributes[0].data); - texture_coord_indices[i] = atoi(attributes[1].data); + vertex_indices[i] = face_data.vertex_index; + texture_coord_indices[i] = face_data.texcoord_index; + normal_indices[i] = face_data.normal_index; if(vertex_indices[i] < 1 || vertex_indices[i] > vertices.size()) { valid = false; @@ -142,7 +168,7 @@ namespace amalgine { break; } - if(texture_coord_indices[i] < 1 || texture_coord_indices[i] > temp_texture_coords.size()) { + if(texture_coord_indices[i] != 0 && (texture_coord_indices[i] < 1 || texture_coord_indices[i] > temp_texture_coords.size())) { valid = false; abort(); break; @@ -150,26 +176,31 @@ namespace amalgine { --vertex_indices[i]; --texture_coord_indices[i]; + --normal_indices[i]; } if(valid) { if(num_columns == 3) { // Triangle triangles.push_back({ vertices[vertex_indices[0]], vertices[vertex_indices[1]], vertices[vertex_indices[2]] }); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[0]]); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[1]]); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[2]]); + if(texture_coord_indices[0] >= 0) { + texture_coords.push_back(temp_texture_coords[texture_coord_indices[0]]); + texture_coords.push_back(temp_texture_coords[texture_coord_indices[1]]); + texture_coords.push_back(temp_texture_coords[texture_coord_indices[2]]); + } } else if(num_columns == 4) { // Quad, convert to triangle. TODO: Support rendering quads instead of converting to triangles triangles.push_back({ vertices[vertex_indices[0]], vertices[vertex_indices[1]], vertices[vertex_indices[2]] }); triangles.push_back({ vertices[vertex_indices[2]], vertices[vertex_indices[3]], vertices[vertex_indices[0]] }); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[0]]); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[1]]); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[2]]); + if(texture_coord_indices[0] >= 0) { + texture_coords.push_back(temp_texture_coords[texture_coord_indices[0]]); + texture_coords.push_back(temp_texture_coords[texture_coord_indices[1]]); + texture_coords.push_back(temp_texture_coords[texture_coord_indices[2]]); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[2]]); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[3]]); - texture_coords.push_back(temp_texture_coords[texture_coord_indices[0]]); + texture_coords.push_back(temp_texture_coords[texture_coord_indices[2]]); + texture_coords.push_back(temp_texture_coords[texture_coord_indices[3]]); + texture_coords.push_back(temp_texture_coords[texture_coord_indices[0]]); + } } } } @@ -185,22 +216,17 @@ namespace amalgine { StringView column_data = { line_data.data + 7, line_data.size - 7 }; int num_columns = split_columns(column_data, ' ', columns, max_columns); if(num_columns == 1) { - std::string material_path; - material_path.resize(dir_path_size + 1 + columns[0].size); - memcpy(&material_path[0], dir_path.data(), dir_path_size); - material_path[dir_path_size] = '/'; - memcpy(&material_path[dir_path_size + 1], columns[0].data, columns[0].size); - printf("mtl file: %.*s\n", material_path.size(), material_path.data()); + std::string material_path = dir_path + '/'; + material_path.append(columns[0].data, columns[0].size); + printf("mtl file: %s\n", material_path.c_str()); assert(!*image); Result<Material> material = load_material_from_file(material_path.c_str()); if(!material) { - fprintf(stderr, "Error: %s\n", material.getErrorMsg().c_str()); - abort(); - goto cleanup; + fprintf(stderr, "Warning: %s\n", material.getErrorMsg().c_str()); + } else { + *image = material->image; } - - *image = material->image; } } |