mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-27 01:50:24 +00:00
Applications: Support .obj
polygons in 3DFileViewer
Our `WavefrontOBJLoader` only supported faces with 3 vertices, but `.obj` files can specify arbitrary polygons with 4 or more vertices.
This commit is contained in:
parent
1577a8ba42
commit
a021a7e240
Notes:
sideshowbarker
2024-07-17 14:12:05 +09:00
Author: https://github.com/gmta Commit: https://github.com/SerenityOS/serenity/commit/a021a7e240 Pull-request: https://github.com/SerenityOS/serenity/pull/13598 Reviewed-by: https://github.com/Quaker762 ✅
1 changed files with 31 additions and 40 deletions
|
@ -7,9 +7,15 @@
|
|||
*/
|
||||
|
||||
#include "WavefrontOBJLoader.h"
|
||||
#include <AK/FixedArray.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline GLuint get_index_value(StringView& representation)
|
||||
{
|
||||
return representation.to_uint().value_or(1) - 1;
|
||||
}
|
||||
|
||||
RefPtr<Mesh> WavefrontOBJLoader::load(Core::File& file)
|
||||
{
|
||||
Vector<Vertex> vertices;
|
||||
|
@ -29,7 +35,6 @@ RefPtr<Mesh> WavefrontOBJLoader::load(Core::File& file)
|
|||
auto tex_coord_line = object_line.split_view(' ');
|
||||
if (tex_coord_line.size() != 3) {
|
||||
dbgln("Wavefront: Malformed TexCoord line. Aborting.");
|
||||
dbgln("{}", object_line);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -68,54 +73,40 @@ RefPtr<Mesh> WavefrontOBJLoader::load(Core::File& file)
|
|||
continue;
|
||||
}
|
||||
|
||||
// This line describes a face (a collection of 3 vertices, aka a triangle)
|
||||
// This line describes a face (a collection of 3+ vertices, aka a triangle or polygon)
|
||||
if (object_line.starts_with("f")) {
|
||||
auto face_line = object_line.split_view(' ');
|
||||
if (face_line.size() != 4) {
|
||||
auto face_line = object_line.substring_view(2).split_view(' ');
|
||||
auto number_of_vertices = face_line.size();
|
||||
if (number_of_vertices < 3) {
|
||||
dbgln("Wavefront: Malformed face line. Aborting.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GLuint vert_index[3];
|
||||
GLuint tex_coord_index[3];
|
||||
GLuint normal_index[3];
|
||||
if (object_line.contains("/")) {
|
||||
for (int i = 1; i <= 3; ++i) {
|
||||
auto vertex_data = face_line.at(i).split_view("/", true);
|
||||
auto vertex_indices = FixedArray<GLuint>::must_create_but_fixme_should_propagate_errors(number_of_vertices);
|
||||
auto tex_coord_indices = FixedArray<GLuint>::must_create_but_fixme_should_propagate_errors(number_of_vertices);
|
||||
auto normal_indices = FixedArray<GLuint>::must_create_but_fixme_should_propagate_errors(number_of_vertices);
|
||||
|
||||
vert_index[i - 1] = vertex_data.at(0).to_uint().value_or(1);
|
||||
tex_coord_index[i - 1] = vertex_data.at(1).to_uint().value_or(1);
|
||||
|
||||
if (vertex_data.size() == 3)
|
||||
normal_index[i - 1] = vertex_data.at(2).to_uint().value_or(1);
|
||||
else
|
||||
normal_index[i - 1] = 1;
|
||||
}
|
||||
} else {
|
||||
vert_index[0] = (face_line.at(1).to_uint().value_or(1));
|
||||
vert_index[1] = (face_line.at(2).to_uint().value_or(1));
|
||||
vert_index[2] = (face_line.at(3).to_uint().value_or(1));
|
||||
tex_coord_index[0] = 0;
|
||||
tex_coord_index[1] = 0;
|
||||
tex_coord_index[2] = 0;
|
||||
normal_index[0] = 0;
|
||||
normal_index[1] = 0;
|
||||
normal_index[2] = 0;
|
||||
for (size_t i = 0; i < number_of_vertices; ++i) {
|
||||
auto vertex_parts = face_line.at(i).split_view('/', true);
|
||||
vertex_indices[i] = get_index_value(vertex_parts[0]);
|
||||
tex_coord_indices[i] = (vertex_parts.size() >= 2) ? get_index_value(vertex_parts[1]) : 0;
|
||||
normal_indices[i] = (vertex_parts.size() >= 3) ? get_index_value(vertex_parts[2]) : 0;
|
||||
}
|
||||
|
||||
// Create a new triangle
|
||||
triangles.append(
|
||||
{
|
||||
vert_index[0] - 1,
|
||||
vert_index[1] - 1,
|
||||
vert_index[2] - 1,
|
||||
tex_coord_index[0] - 1,
|
||||
tex_coord_index[1] - 1,
|
||||
tex_coord_index[2] - 1,
|
||||
normal_index[0] - 1,
|
||||
normal_index[1] - 1,
|
||||
normal_index[2] - 1,
|
||||
// Create a triangle for each part of the polygon
|
||||
for (size_t i = 0; i < number_of_vertices - 2; ++i) {
|
||||
triangles.append({
|
||||
vertex_indices[0],
|
||||
vertex_indices[i + 1],
|
||||
vertex_indices[i + 2],
|
||||
tex_coord_indices[0],
|
||||
tex_coord_indices[i + 1],
|
||||
tex_coord_indices[i + 2],
|
||||
normal_indices[0],
|
||||
normal_indices[i + 1],
|
||||
normal_indices[i + 2],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue