1#ifndef NNGN_RENDER_OBJ_H
2#define NNGN_RENDER_OBJ_H
12#include "utils/span.h"
21 std::size_t line, std::string_view args,
const char *
name,
vec3 *
v);
23 std::size_t line, std::string_view args,
24 std::string_view *
ps,
zvec3 *pv);
55 std::span<char> buffer,
56 std::invocable<vec3>
auto &&vertex,
57 std::invocable<vec3>
auto &&tex,
58 std::invocable<vec3>
auto &&normal,
60 std::invocable<std::array<zvec3, 3>>
auto &&face);
64 std::span<char> buffer,
65 std::invocable<vec3>
auto &&vertex,
66 std::invocable<vec3>
auto &&tex,
67 std::invocable<vec3>
auto &&normal,
68 std::invocable<std::array<zvec3, 3>>
auto &&face)
71 constexpr auto read_vec = [](
72 std::size_t line, std::string_view args,
const char *
name,
auto &&fn)
76 && (
FWD(fn)(
v),
true);
78 constexpr auto read_face = [](
79 std::size_t line, std::string_view args,
auto &&fn)
82 constexpr auto dec = [](
auto *
v) {
for(
auto &x : *
v) --x; };
83 std::string_view
s = args;
84 zvec3 f0 = {}, f1 = {}, f2 = {};
86 read(line, args, &
s, &f0)
87 && read(line, args, &
s, &f1)
88 && read(line, args, &
s, &f2)
91 dec(&f0), dec(&f1), dec(&f2);
92 FWD(fn)(std::array{f0, f1, f2});
94 if(!read(line, args, &
s, &f1))
98 FWD(fn)(std::array{f0, f1, f2});
102 using namespace std::string_view_literals;
103 constexpr std::array ignored = {
104 "g"sv,
"mtl"sv,
"mtllib"sv,
"o"sv,
"s"sv,
"usemtl"sv,
106 static_assert(std::ranges::is_sorted(ignored));
107 const auto max =
static_cast<std::streamsize
>(buffer.size());
108 for(std::size_t line = 1;; ++line) {
109 if(!
f->getline(buffer.data(), max)) {
112 Log::l() <<
"line " << line <<
" too long (max: " << max <<
")\n";
118 const auto [cmd, args] =
split(
s, std::ranges::find(
s,
' '));
120 if(!read_vec(line, args,
"vertex",
FWD(vertex)))
122 }
else if(cmd ==
"vt") {
123 if(!read_vec(line, args,
"texture coordinates",
FWD(tex)))
125 }
else if(cmd ==
"vn") {
126 if(!read_vec(line, args,
"vertex normal",
FWD(normal)))
128 }
else if(cmd ==
"f") {
129 if(!read_face(line, args,
FWD(face)))
131 }
else if(!std::ranges::binary_search(ignored, cmd))
static std::ostream & l()
Definition: log.cpp:56
for i
Definition: font.lua:5
name
Definition: cathedral.lua:11
n
Definition: dump_lights.lua:5
v[1]
Definition: math.lua:19
std::chrono::seconds s
Definition: timing.cpp:6
#define NNGN_LOG_CONTEXT_F()
Definition: log.h:10
#define FWD(...)
Definition: utils.h:18
bool obj_read_vec(std::size_t line, std::string_view args, const char *name, vec3 *v)
Definition: obj.cpp:29
bool obj_read_face_indices(std::size_t line, std::string_view args, std::string_view *ps, zvec3 *pv)
Definition: obj.cpp:49
std::string_view obj_parse_line(const char *p, std::streamsize n)
Definition: obj.cpp:16
bool obj_invalid(std::size_t i, std::string_view line)
Definition: obj.cpp:9
vec3_base< std::size_t > zvec3
Definition: vec3.h:50
bool parse_obj(std::istream *f, std::span< char > buffer, std::invocable< vec3 > auto &&vertex, std::invocable< vec3 > auto &&tex, std::invocable< vec3 > auto &&normal, std::invocable< std::array< zvec3, 3 > > auto &&face)
Processes an OBJ file using the callable arguments.
Definition: obj.h:62
auto split(std::span< T > s, std::size_t i)
Definition: span.h:24
vec3_base< float > vec3
Definition: vec3.h:51