PeriDyno 1.0.0
Loading...
Searching...
No Matches
tinyobj_helper.cpp
Go to the documentation of this file.
1#include "tinyobj_helper.h"
2
3#include "ImageLoader.h"
4
5#define TINYOBJLOADER_IMPLEMENTATION
6#include <tinyobjloader/tiny_obj_loader.h>
7
8namespace dyno
9{
10 bool loadTextureMeshFromObj(std::shared_ptr<TextureMesh> texMesh, const FilePath& fullname)
11 {
12 tinyobj::attrib_t attrib;
13 std::vector<tinyobj::shape_t> shapes;
14 std::vector<tinyobj::material_t> materials;
15 std::string err, warn;
16
17 auto name = fullname;
18 auto root = name.path().parent_path();
19
20 bool result = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
21 name.string().c_str(), root.string().c_str());
22
23 if (!err.empty()) {
24 std::cerr << err << std::endl;
25 return false;
26 }
27
28 if (!warn.empty()) {
29 std::cerr << warn << std::endl;
30 }
31
32 std::vector<dyno::Vec3f> vertices;
33 std::vector<dyno::Vec3f> normals;
34 std::vector<dyno::Vec2f> texCoords;
35
36 std::vector<dyno::Vec3i> pIndex;
37 std::vector<dyno::Vec3i> nIndex;
38 std::vector<dyno::Vec3i> tIndex;
39
40 for (int i = 0; i < attrib.vertices.size(); i += 3) {
41 vertices.push_back({ attrib.vertices[i], attrib.vertices[i + 1], attrib.vertices[i + 2] });
42 }
43
44 for (int i = 0; i < attrib.normals.size(); i += 3) {
45 normals.push_back({ attrib.normals[i], attrib.normals[i + 1], attrib.normals[i + 2] });
46 }
47
48 for (int i = 0; i < attrib.texcoords.size(); i += 2) {
49 texCoords.push_back({ attrib.texcoords[i], attrib.texcoords[i + 1] });
50 }
51
52 // load texture...
53 dyno::CArray2D<dyno::Vec4f> texture(1, 1);
54 texture[0, 0] = dyno::Vec4f(1);
55
56 auto& tMats = texMesh->materials();
57 tMats.resize(materials.size());
58
59 uint mId = 0;
60 for (const auto& mtl : materials) {
61 tMats[mId] = std::make_shared<Material>();
62 //tMats[mId]->ambient = { mtl.ambient[0], mtl.ambient[1], mtl.ambient[2] };
63 //tMats[mId]->diffuse = { mtl.diffuse[0], mtl.diffuse[1], mtl.diffuse[2] };
64 //tMats[mId]->specular = { mtl.specular[0], mtl.specular[1], mtl.specular[2] };
65 //tMats[mId]->roughness = 1.0f - mtl.shininess;
66 tMats[mId]->baseColor = { mtl.diffuse[0], mtl.diffuse[1], mtl.diffuse[2] };
67
68 std::shared_ptr<ImageLoader> loader = std::make_shared<ImageLoader>();
69
70 if (!mtl.diffuse_texname.empty())
71 {
72 auto tex_path = (root / mtl.diffuse_texname).string();
73
74 if (loader->loadImage(tex_path.c_str(), texture))
75 {
76 tMats[mId]->texColor.assign(texture);
77 }
78 }
79 if (!mtl.bump_texname.empty())
80 {
81 auto tex_path = (root / mtl.bump_texname).string();
82
83 if (loader->loadImage(tex_path.c_str(), texture))
84 {
85 tMats[mId]->texBump.assign(texture);
86 auto texOpt = mtl.bump_texopt;
87 tMats[mId]->bumpScale = texOpt.bump_multiplier;
88 }
89 }
90
91 mId++;
92 }
93
94
95 auto& tShapes = texMesh->shapes();
96 tShapes.resize(shapes.size());
97
98 uint sId = 0;
99 for (const tinyobj::shape_t& shape : shapes) {
100 // only load triangle mesh...
101 const auto& mesh = shape.mesh;
102 tShapes[sId] = std::make_shared<Shape>();
103 std::vector<TopologyModule::Triangle> vertexIndex;
104 std::vector<TopologyModule::Triangle> normalIndex;
105 std::vector<TopologyModule::Triangle> texCoordIndex;
106
107 if (mesh.material_ids.size() > 0 && mesh.material_ids[0] >= 0)
108 {
109 tShapes[sId]->material = tMats[mesh.material_ids[0]];
110 }
111
112 Vec3f lo = Vec3f(REAL_MAX);
113 Vec3f hi = Vec3f(-REAL_MAX);
114 for (int i = 0; i < mesh.indices.size(); i += 3) {
115 auto idx0 = mesh.indices[i];
116 auto idx1 = mesh.indices[i + 1];
117 auto idx2 = mesh.indices[i + 2];
118
119 vertexIndex.push_back({ idx0.vertex_index, idx1.vertex_index, idx2.vertex_index });
120 normalIndex.push_back({ idx0.normal_index, idx1.normal_index, idx2.normal_index });
121 texCoordIndex.push_back({ idx0.texcoord_index, idx1.texcoord_index, idx2.texcoord_index });
122
123 lo = lo.minimum(vertices[idx0.vertex_index]);
124 lo = lo.minimum(vertices[idx1.vertex_index]);
125 lo = lo.minimum(vertices[idx2.vertex_index]);
126
127 hi = hi.maximum(vertices[idx0.vertex_index]);
128 hi = hi.maximum(vertices[idx1.vertex_index]);
129 hi = hi.maximum(vertices[idx2.vertex_index]);
130 }
131 tShapes[sId]->vertexIndex.assign(vertexIndex);
132 tShapes[sId]->normalIndex.assign(normalIndex);
133 tShapes[sId]->texCoordIndex.assign(texCoordIndex);
134
135 auto shapeCenter = (lo + hi) / 2;
136 tShapes[sId]->boundingBox = TAlignedBox3D<Real>(lo, hi);
137 tShapes[sId]->boundingTransform = Transform3f(shapeCenter, Quat1f().toMatrix3x3());
138
139 //Move to center
140 std::vector<int> indicator(vertices.size(), 0);
141 for (int i = 0; i < mesh.indices.size(); i += 3)
142 {
143 auto idx0 = mesh.indices[i];
144 auto idx1 = mesh.indices[i + 1];
145 auto idx2 = mesh.indices[i + 2];
146
147 if (indicator[idx0.vertex_index] == 0)
148 {
149 vertices[idx0.vertex_index] -= shapeCenter;
150 indicator[idx0.vertex_index] = 1;
151 }
152 if (indicator[idx1.vertex_index] == 0)
153 {
154 vertices[idx1.vertex_index] -= shapeCenter;
155 indicator[idx1.vertex_index] = 1;
156 }
157 if (indicator[idx2.vertex_index] == 0)
158 {
159 vertices[idx2.vertex_index] -= shapeCenter;
160 indicator[idx2.vertex_index] = 1;
161 }
162 }
163
164 vertexIndex.clear();
165 normalIndex.clear();
166 texCoordIndex.clear();
167
168 sId++;
169 }
170
171 texMesh->vertices().assign(vertices);
172 texMesh->normals().assign(normals);
173 texMesh->texCoords().assign(texCoords);
174
175 vertices.clear();
176 normals.clear();
177 texCoords.clear();
178
179 return true;
180 }
181}
fs::path & path()
Definition FilePath.h:17
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
constexpr Real REAL_MAX
Definition Typedef.inl:45
Array2D< T, DeviceType::CPU > CArray2D
Definition Array2D.h:131
Quat< float > Quat1f
Definition Quat.h:136
Vector< float, 4 > Vec4f
Definition Vector4D.h:86
bool loadTextureMeshFromObj(std::shared_ptr< TextureMesh > texMesh, const FilePath &fullname)
Transform< float, 3 > Transform3f
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
unsigned int uint
Definition VkProgram.h:14