aboutsummaryrefslogtreecommitdiff
path: root/src/model_loader
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-02-22 08:55:48 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-18 15:22:10 +0100
commit9ab59b76c0ece5e261c0152af3f830f48532e103 (patch)
treeae66d456fa58d4f98ea74759bcc2bb9e2f50efae /src/model_loader
parentf2f8ccc1c24ab372ffe5e932780eeb1c49a4d277 (diff)
Fix rendering of character
Diffstat (limited to 'src/model_loader')
-rw-r--r--src/model_loader/ObjModelLoader.cpp96
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;
}
}