diff options
author | Erik Biederstadt <biederstadterik@gmail.com> | 2021-05-19 11:57:59 -0600 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-05-19 19:34:12 +0100 |
commit | 585e7890cdd416b77bd28c2ef853477b42c606ef (patch) | |
tree | b44d8a4bb7a6306f8b947a566056976afa6ff36c /Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp | |
parent | 132ecfc47b2b21706fff16f08ab30bcb7879af73 (diff) | |
download | serenity-585e7890cdd416b77bd28c2ef853477b42c606ef.zip |
3DFileViewer: Move `Demos/GLTeapot` to `Applications/3DFileViewer`
Also changes the category to `Graphics`
Diffstat (limited to 'Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp')
-rw-r--r-- | Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp b/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp new file mode 100644 index 0000000000..891f13dc8f --- /dev/null +++ b/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com> + * Copyright (c) 2021, Mathieu Gaillard <gaillard.mathieu.39@gmail.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "WavefrontOBJLoader.h" +#include <LibCore/File.h> +#include <stdlib.h> + +RefPtr<Mesh> WavefrontOBJLoader::load(const String& fname) +{ + auto obj_file_or_error = Core::File::open(fname, Core::OpenMode::ReadOnly); + Vector<Vertex> vertices; + Vector<Triangle> triangles; + + dbgln("Wavefront: Loading {}...", fname); + + if (obj_file_or_error.is_error()) + return nullptr; + + // Start reading file line by line + for (auto line = obj_file_or_error.value()->line_begin(); !line.at_end(); ++line) { + auto object_line = *line; + + // FIXME: Parse texture coordinates and vertex normals + if (object_line.starts_with("vt") || object_line.starts_with("vn")) { + continue; + } + + // This line describes a vertex (a position in 3D space) + if (object_line.starts_with("v")) { + auto vertex_line = object_line.split_view(' '); + if (vertex_line.size() != 4) { + dbgln("Wavefront: Malformed vertex line. Aborting."); + return nullptr; + } + + vertices.append( + { static_cast<GLfloat>(atof(String(vertex_line.at(1)).characters())), + static_cast<GLfloat>(atof(String(vertex_line.at(2)).characters())), + static_cast<GLfloat>(atof(String(vertex_line.at(3)).characters())) }); + } + // This line describes a face (a collection of 3 vertices, aka a triangle) + else if (object_line.starts_with("f")) { + auto face_line = object_line.split_view(' '); + if (face_line.size() != 4) { + dbgln("Wavefront: Malformed face line. Aborting."); + return nullptr; + } + + if (object_line.contains("/")) { + for (int i = 1; i <= 3; ++i) { + face_line.at(i) = face_line.at(i).split_view("/").at(0); + } + } + + // Create a new triangle + triangles.append( + { + face_line.at(1).to_uint().value() - 1, + face_line.at(2).to_uint().value() - 1, + face_line.at(3).to_uint().value() - 1, + }); + } + } + + if (vertices.is_empty()) { + dbgln("Wavefront: Failed to read any data from 3D file: {}", fname); + return nullptr; + } + + dbgln("Wavefront: Done."); + return adopt_ref(*new Mesh(vertices, triangles)); +} |