Loading...
Searching...
No Matches
TinyObj.hpp
1#pragma once
2#include <boost/container/vector.hpp>
3#include <halp/controls.hpp>
4#include <halp/geometry.hpp>
5#include <halp/meta.hpp>
6#include <ossia/detail/pod_vector.hpp>
7
8#include <QMatrix4x4>
9#include <QQuaternion>
10
11#include <cstring>
12#include <vector>
13
14#include <string_view>
15namespace Threedim
16{
17using float_vec = boost::container::vector<float, ossia::pod_allocator<float>>;
18
20 int64_t offset{}; // in elements (floats), not bytes
21 halp::attribute_semantic semantic{};
22 halp::attribute_format format{};
23 int components{}; // 1-4 floats
24 std::string name; // For custom semantics; empty = use semantic name
25};
26
27struct mesh {
28 int64_t vertices{};
29 // offset are in "elements", not bytes
30 int64_t pos_offset{}, texcoord_offset{}, normal_offset{}, color_offset{}, tangent_offset{};
31 bool texcoord{};
32 bool normals{};
33 bool colors{};
34 // How many floats per vertex the colour stream actually carries. PLY writes
35 // three, the vcg importers write four, and a consumer that assumes either one
36 // reads every vertex after the first at the wrong offset.
37 int color_components{3};
38 bool tangents{};
39 bool points{};
40 std::vector<extra_attribute> extras;
41};
42
43std::vector<mesh> ObjFromString(
44 std::string_view obj_data
45 , std::string_view mtl_data
46 , float_vec& data);
47
48std::vector<mesh> ObjFromString(
49 std::string_view obj_data
50 , float_vec& data);
51
52template <std::size_t N>
53static void fromGL(float (&from)[N], auto& to)
54{
55 memcpy(to.data(), from, sizeof(float[N]));
56}
57template <std::size_t N>
58static void toGL(auto& from, float (&to)[N])
59{
60 memcpy(to, from.data(), sizeof(float[N]));
61}
62
63inline void rebuild_transform(auto& inputs, auto& outputs)
64{
65 QMatrix4x4 model{};
66
67 if constexpr(requires { inputs.position; })
68 {
69 auto& pos = inputs.position;
70 model.translate(pos.value.x, pos.value.y, pos.value.z);
71 }
72
73 if constexpr(requires { inputs.rotation; })
74 {
75 auto& rot = inputs.rotation;
76 model.rotate(QQuaternion::fromEulerAngles(rot.value.x, rot.value.y, rot.value.z));
77 }
78
79 if constexpr(requires { inputs.scale; })
80 {
81 auto& sc = inputs.scale;
82 model.scale(sc.value.x, sc.value.y, sc.value.z);
83 }
84
85 // Legacy path: writes into the halp::mesh-style `geometry` output.
86 // Scene-only loaders (GltfParser/FbxParser) have no `outputs.geometry`;
87 // there the Position/Rotation/Scale controls are a no-op.
88 if constexpr(requires {
89 outputs.geometry.transform;
90 outputs.geometry.dirty_transform;
91 })
92 {
93 toGL(model, outputs.geometry.transform);
94 outputs.geometry.dirty_transform = true;
95 }
96}
97struct PositionControl : halp::xyz_spinboxes_f32<"Position", halp::free_range_min<>>
98{
99 void update(auto& o) { rebuild_transform(o.inputs, o.outputs); }
100};
102 : halp::xyz_spinboxes_f32<"Rotation", halp::range{0., 359.9999999, 0.}>
103{
104 void update(auto& o) { rebuild_transform(o.inputs, o.outputs); }
105};
106struct ScaleControl : halp::xyz_spinboxes_f32<"Scale", halp::range{0.00001, 1000., 1.}>
107{
108 void update(auto& o) { rebuild_transform(o.inputs, o.outputs); }
109};
110
111struct Update
112{
113 void update(auto& obj) { obj.update(); }
114};
115
117{
118 struct
119 {
120 halp_meta(name, "Geometry");
121 halp::position_normals_texcoords_geometry_volume mesh;
122 float transform[16]{};
123 bool dirty_mesh = false;
124 bool dirty_transform = false;
125 } geometry;
126};
127}
Definition TinyObj.hpp:98
Definition TinyObj.hpp:117
Definition TinyObj.hpp:103
Definition TinyObj.hpp:107
Definition TinyObj.hpp:112
Definition TinyObj.hpp:19
Definition TinyObj.hpp:27