unit-MeshPrimitive2.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. #include <catch2/catch_all.hpp>
  2. #include <iostream>
  3. #include <gul/MeshPrimitive2.h>
  4. #include <glm/glm.hpp>
  5. #include <glm/gtc/vec1.hpp>
  6. SCENARIO("types")
  7. {
  8. REQUIRE( gul::type_to_component<glm::vec1>() == gul::eComponentType::FLOAT);
  9. REQUIRE( gul::type_to_component<float >() == gul::eComponentType::FLOAT);
  10. REQUIRE( gul::type_to_component<glm::mat2>() == gul::eComponentType::FLOAT);
  11. REQUIRE( gul::type_to_component<glm::vec4>() == gul::eComponentType::FLOAT);
  12. REQUIRE( gul::type_to_component<glm::mat4>() == gul::eComponentType::FLOAT);
  13. REQUIRE( gul::type_to_type<uint32_t>() == gul::eType::SCALAR);
  14. REQUIRE( gul::type_to_type<glm::vec1>() == gul::eType::SCALAR);
  15. REQUIRE( gul::type_to_type<glm::vec2>() == gul::eType::VEC2);
  16. REQUIRE( gul::type_to_type<glm::vec3>() == gul::eType::VEC3);
  17. REQUIRE( gul::type_to_type<glm::vec4>() == gul::eType::VEC4);
  18. REQUIRE( gul::type_to_type<glm::mat2>() == gul::eType::MAT2);
  19. REQUIRE( gul::type_to_type<glm::mat3>() == gul::eType::MAT3);
  20. REQUIRE( gul::type_to_type<glm::mat4>() == gul::eType::MAT4);
  21. }
  22. SCENARIO("Initialize attribute with vector")
  23. {
  24. GIVEN("A vertex attribute with items")
  25. {
  26. gul::VertexAttribute V = std::vector<glm::uvec2>( {{1,2}, {3,4}});
  27. REQUIRE( V.getComponentType() == gul::eComponentType::UNSIGNED_INT);
  28. REQUIRE( V.getType() == gul::eType::VEC2);
  29. REQUIRE( V.attributeCount() == 2);
  30. REQUIRE( V.size() == 4); // 4 total components
  31. auto readBack = V.toVector<glm::uvec2>();
  32. REQUIRE( readBack[0][0] == 1);
  33. REQUIRE( readBack[0][1] == 2);
  34. REQUIRE( readBack[1][0] == 3);
  35. REQUIRE( readBack[1][1] == 4);
  36. }
  37. }
  38. SCENARIO("changing types")
  39. {
  40. GIVEN("A vertex attribute with 3 items")
  41. {
  42. gul::VertexAttribute V = std::vector<glm::uvec2>( {{1,2}, {3,4}, {5,6}});
  43. REQUIRE( V.getComponentType() == gul::eComponentType::UNSIGNED_INT);
  44. REQUIRE( V.getType() == gul::eType::VEC2);
  45. REQUIRE( V.attributeCount() == 3);
  46. REQUIRE( V.size() == 6); // 4 total components
  47. WHEN("We change the type to a scalar")
  48. {
  49. V.setType( gul::eType::SCALAR);
  50. REQUIRE(V.attributeCount() == 6);
  51. REQUIRE(V.size() == 6);
  52. auto readBack = V.toVector<uint32_t>();
  53. REQUIRE(readBack.size() == V.attributeCount() );
  54. REQUIRE( readBack[0] == 1);
  55. REQUIRE( readBack[1] == 2);
  56. REQUIRE( readBack[2] == 3);
  57. REQUIRE( readBack[3] == 4);
  58. REQUIRE( readBack[4] == 5);
  59. REQUIRE( readBack[5] == 6);
  60. }
  61. WHEN("We change the type to a VEC3")
  62. {
  63. V.setType( gul::eType::VEC3);
  64. REQUIRE(V.attributeCount() == 2);
  65. REQUIRE(V.size() == 6);
  66. auto readBack = V.toVector<glm::uvec3>();
  67. REQUIRE(readBack.size() == V.attributeCount() );
  68. REQUIRE( readBack[0][0] == 1);
  69. REQUIRE( readBack[0][1] == 2);
  70. REQUIRE( readBack[0][2] == 3);
  71. REQUIRE( readBack[1][0] == 4);
  72. REQUIRE( readBack[1][1] == 5);
  73. REQUIRE( readBack[1][2] == 6);
  74. }
  75. WHEN("We change the type to a VEC4")
  76. {
  77. V.setType( gul::eType::VEC4);
  78. THEN("We have only 1 attribute, since 4 does not evenly divide 6")
  79. {
  80. // only 1 item is available
  81. REQUIRE(V.attributeCount() == 1);
  82. REQUIRE(V.size() == 4);
  83. auto readBack = V.toVector<glm::uvec4>();
  84. REQUIRE(readBack.size() == V.attributeCount() );
  85. REQUIRE( readBack[0][0] == 1);
  86. REQUIRE( readBack[0][1] == 2);
  87. REQUIRE( readBack[0][2] == 3);
  88. REQUIRE( readBack[0][3] == 4);
  89. }
  90. }
  91. WHEN("We change the type to a MAT2")
  92. {
  93. V.setType( gul::eType::MAT2);
  94. THEN("We have only 1 attribute, since 4 does not evenly divide 6")
  95. {
  96. // only 1 item is available
  97. REQUIRE(V.attributeCount() == 1);
  98. REQUIRE(V.size() == 4);
  99. auto readBack = V.toVector<glm::umat2x2>();
  100. REQUIRE(readBack.size() == V.attributeCount() );
  101. REQUIRE( readBack[0][0][0] == 1);
  102. REQUIRE( readBack[0][0][1] == 2);
  103. REQUIRE( readBack[0][1][0] == 3);
  104. REQUIRE( readBack[0][1][1] == 4);
  105. }
  106. }
  107. }
  108. }
  109. SCENARIO("strideCopyOffset")
  110. {
  111. GIVEN("A vertex attribute with 3 items")
  112. {
  113. gul::VertexAttribute V = std::vector<glm::uvec2>( {{1,2}, {3,4}, {5,6}});
  114. REQUIRE( V.getComponentType() == gul::eComponentType::UNSIGNED_INT);
  115. REQUIRE( V.getType() == gul::eType::VEC2);
  116. REQUIRE( V.attributeCount() == 3);
  117. REQUIRE( V.size() == 6); // 4 total components
  118. auto readBack = V.toVector<glm::uvec2>();
  119. WHEN("We do a strideCopy with a stride size of 2*sizeof( glm::vec2)")
  120. {
  121. std::vector<uint32_t> D = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  122. V.strideCopyOffset(D.data(),
  123. 2*sizeof(glm::uvec2),
  124. 0, // copy data to
  125. 1, // start at the second index
  126. 10); // copy 10 attributes
  127. THEN("Every other value is copied")
  128. {
  129. REQUIRE( D[0] == 3);
  130. REQUIRE( D[1] == 4);
  131. REQUIRE( D[2] == 0); // skipped
  132. REQUIRE( D[3] == 0); // skipped
  133. REQUIRE( D[4] == 5);
  134. REQUIRE( D[5] == 6);
  135. REQUIRE( D[6] == 0); // not copied, overflow
  136. REQUIRE( D[7] == 0); // not copied, overflow
  137. REQUIRE( D[8] == 0); // not copied, overflow
  138. REQUIRE( D[9] == 0); // not copied, overflow
  139. }
  140. }
  141. }
  142. }
  143. SCENARIO("Accessing data")
  144. {
  145. GIVEN("A vertex attribute with items")
  146. {
  147. gul::VertexAttribute V = std::vector<glm::uvec2>( {{1,2}, {3,4}, {5,6}});
  148. WHEN("When we use get()")
  149. {
  150. REQUIRE(V.get<uint32_t>(0) == 1);
  151. REQUIRE(V.get<uint32_t>(1) == 2);
  152. REQUIRE(V.get<uint32_t>(2) == 3);
  153. REQUIRE(V.get<uint32_t>(3) == 4);
  154. REQUIRE(V.get<uint32_t>(4) == 5);
  155. REQUIRE(V.get<uint32_t>(5) == 6);
  156. }
  157. WHEN("When we use getAttributeAs()")
  158. {
  159. REQUIRE(V.getAttributeAs<uint32_t>(0) == 1); // reads V[0][0]
  160. REQUIRE(V.getAttributeAs<uint32_t>(1) == 3); // reads V[1][0]
  161. REQUIRE(V.getAttributeAs<uint32_t>(2) == 5); // reads V[2][0]
  162. }
  163. }
  164. }
  165. SCENARIO("Merging")
  166. {
  167. GIVEN("A vertex attribute with items")
  168. {
  169. gul::VertexAttribute V = std::vector<glm::uvec2>( {{1,2}, {3,4}, {5,6}});
  170. gul::VertexAttribute V2 = std::vector<glm::uvec2>( {{7,8}, {9,10}});
  171. auto byteOffset = V.merge(V2);
  172. REQUIRE( byteOffset == sizeof(glm::uvec2) * 3);
  173. REQUIRE( V.attributeCount() == 5);
  174. }
  175. }
  176. SCENARIO("Mesh::calculateInterleavedStride")
  177. {
  178. GIVEN("A 2 vertex attribute with items")
  179. {
  180. gul::VertexAttribute V1 = std::vector<glm::uvec2>( {{1,2}, {3,4}, {5,6}});
  181. gul::VertexAttribute V2 = std::vector<glm::ivec2>( {{-1,-2}, {-3,-4}, {-5,-6}});
  182. REQUIRE(16 == gul::calculateInterleavedStride({&V1, &V2}));
  183. }
  184. }
  185. SCENARIO("Mesh::calculateInterleavedBytes")
  186. {
  187. GIVEN("A 2 vertex attribute with items")
  188. {
  189. gul::VertexAttribute V1 = std::vector<glm::uvec2>( {{1,2}, {3,4}, {5,6}});
  190. gul::VertexAttribute V2 = std::vector<glm::ivec2>( {{-1,-2}, {-3,-4}, {-5,-6}});
  191. REQUIRE(48 == gul::calculateInterleavedBytes({&V1, &V2}));
  192. }
  193. }
  194. SCENARIO("Mesh::copyVertexAttributesInterleaved")
  195. {
  196. GIVEN("A 2 vertex attribute with items")
  197. {
  198. gul::VertexAttribute V1 = std::vector<glm::uvec2>( {{1,2}, {3,4}, {5,6}});
  199. gul::VertexAttribute V2 = std::vector<glm::ivec2>( {{-1,-2}, {-3,-4}, {-5,-6}});
  200. struct Vertex
  201. {
  202. glm::uvec2 a;
  203. glm::ivec2 b;
  204. };
  205. REQUIRE( offsetof(Vertex, a) == 0);
  206. REQUIRE( offsetof(Vertex, b) == sizeof(glm::uvec2));
  207. THEN("We can copy each attribute sequentually to a vertex vector")
  208. {
  209. std::vector<Vertex> raw;
  210. gul::MeshPrimitive::copyVertexAttributesInterleaved(raw, {&V1,&V2});
  211. REQUIRE( raw.size() == 3);
  212. WHEN("When we use get()")
  213. {
  214. REQUIRE(raw[0].a[0] == 1);
  215. REQUIRE(raw[0].a[1] == 2);
  216. REQUIRE(raw[1].a[0] == 3);
  217. REQUIRE(raw[1].a[1] == 4);
  218. REQUIRE(raw[2].a[0] == 5);
  219. REQUIRE(raw[2].a[1] == 6);
  220. REQUIRE(raw[0].b[0] == -1);
  221. REQUIRE(raw[0].b[1] == -2);
  222. REQUIRE(raw[1].b[0] == -3);
  223. REQUIRE(raw[1].b[1] == -4);
  224. REQUIRE(raw[2].b[0] == -5);
  225. REQUIRE(raw[2].b[1] == -6);
  226. }
  227. }
  228. }
  229. }
  230. SCENARIO("get minmax")
  231. {
  232. GIVEN("A vertex attribute with 3 items")
  233. {
  234. gul::VertexAttribute V = std::vector<glm::uvec2>( {{1,2}, {3,4}, {5,6}, {7,8} });
  235. WHEN("We change the type to a scalar")
  236. {
  237. V.setType( gul::eType::SCALAR);
  238. auto [_m, _M] = V.getMinMax<uint32_t>();
  239. REQUIRE( _m.size() == 1);
  240. REQUIRE( _M.size() == 1);
  241. REQUIRE( _m[0] == 1);
  242. REQUIRE( _M[0] == 8);
  243. }
  244. WHEN("We change the type to a vec2")
  245. {
  246. V.setType( gul::eType::VEC2);
  247. auto [_m, _M] = V.getMinMax<uint32_t>();
  248. REQUIRE( _m.size() == 2);
  249. REQUIRE( _M.size() == 2);
  250. REQUIRE( _m[0] == 1);
  251. REQUIRE( _m[1] == 2);
  252. REQUIRE( _M[0] == 7);
  253. REQUIRE( _M[1] == 8);
  254. }
  255. WHEN("We change the type to a vec4")
  256. {
  257. V.setType( gul::eType::VEC4);
  258. auto [_m, _M] = V.getMinMax<uint32_t>();
  259. REQUIRE( _m.size() == 4);
  260. REQUIRE( _M.size() == 4);
  261. REQUIRE( _m[0] == 1);
  262. REQUIRE( _m[1] == 2);
  263. REQUIRE( _m[2] == 3);
  264. REQUIRE( _m[3] == 4);
  265. REQUIRE( _M[0] == 5);
  266. REQUIRE( _M[1] == 6);
  267. REQUIRE( _M[2] == 7);
  268. REQUIRE( _M[3] == 8);
  269. }
  270. WHEN("We change the type to a mat4")
  271. {
  272. V.setType( gul::eType::MAT2);
  273. auto [_m, _M] = V.getMinMax<uint32_t>();
  274. REQUIRE( _m.size() == 4);
  275. REQUIRE( _M.size() == 4);
  276. REQUIRE( _m[0] == 1);
  277. REQUIRE( _m[1] == 2);
  278. REQUIRE( _m[2] == 3);
  279. REQUIRE( _m[3] == 4);
  280. REQUIRE( _M[0] == 5);
  281. REQUIRE( _M[1] == 6);
  282. REQUIRE( _M[2] == 7);
  283. REQUIRE( _M[3] == 8);
  284. }
  285. }
  286. GIVEN("A vertex attribute with 3 items")
  287. {
  288. gul::VertexAttribute V = std::vector<glm::vec2>( {{1,2}, {7,8}, {3,4}, {5,6} });
  289. WHEN("We change the type to a scalar")
  290. {
  291. auto [_m, _M] = V.getMinMax<float>();
  292. REQUIRE( _m[0] == Catch::Approx(1));
  293. REQUIRE( _m[1] == Catch::Approx(2));
  294. REQUIRE( _M[0] == Catch::Approx(7));
  295. REQUIRE( _M[1] == Catch::Approx(8));
  296. }
  297. }
  298. }
  299. SCENARIO("Mesh")
  300. {
  301. // box mesh has position, normals, texcoords0, index
  302. auto S = gul::Box(1,1,1);
  303. constexpr uint64_t vertexCount = 36;
  304. constexpr uint64_t indexCount = 36;
  305. constexpr uint64_t vertexSize = sizeof(glm::vec3) + sizeof(glm::vec3) + sizeof(glm::vec2);
  306. constexpr uint64_t vertexDeviceSize = vertexCount * vertexSize;
  307. constexpr uint64_t indexDeviceSize = indexCount * sizeof(uint32_t);
  308. constexpr uint64_t deviceSize = indexDeviceSize + vertexDeviceSize;
  309. REQUIRE(S.INDEX.attributeCount() == indexCount);
  310. REQUIRE(S.indexCount() == indexCount);
  311. REQUIRE( S.POSITION.attributeCount() == vertexCount);
  312. REQUIRE( S.NORMAL.attributeCount() == vertexCount);
  313. REQUIRE( S.TEXCOORD_0.attributeCount() == vertexCount);
  314. REQUIRE( S.calculateDeviceSize() == deviceSize);
  315. REQUIRE(S.getVertexByteSize() == vertexSize);
  316. REQUIRE( vertexDeviceSize == S.calculateInterleavedBufferSize() );
  317. THEN("We can copy the mesh vertices in interleaved format")
  318. {
  319. std::vector<uint8_t> raw;
  320. raw.resize(vertexDeviceSize);
  321. auto totalCopied = S.copyVertexAttributesInterleaved(raw.data(), 0);
  322. REQUIRE( totalCopied == vertexCount);
  323. }
  324. THEN("We can copy the mesh vertices in sequential format")
  325. {
  326. std::vector<uint8_t> raw;
  327. raw.resize( S.calculateDeviceSize() ); // need device size
  328. auto offsets = S.copyVertexAttributesSquential(raw.data());
  329. REQUIRE( offsets.size() == 9);
  330. REQUIRE( offsets[0] == 0); // positions at 0
  331. REQUIRE( offsets[1] == 36*12); // normal after position
  332. REQUIRE( offsets[2] == 0);
  333. REQUIRE( offsets[3] == 36*(12+12)); // texcoord after position/normal
  334. REQUIRE( offsets[4] == 0);
  335. REQUIRE( offsets[5] == 0);
  336. REQUIRE( offsets[6] == 0);
  337. REQUIRE( offsets[7] == 0);
  338. REQUIRE( offsets[8] == 36*(12+12+8)); // indices after position/normal/texcoord
  339. }
  340. }
  341. SCENARIO("Mesh Merge")
  342. {
  343. // box mesh has position, normals, texcoords0, index
  344. auto FirstMesh = gul::Box(1,1,1);
  345. auto S = gul::Sphere(1.0);
  346. // only a single primitive in the box mesh
  347. REQUIRE( FirstMesh.primitives.size() == 1 );
  348. REQUIRE(FirstMesh.primitives[0].indexCount == 36);
  349. REQUIRE(FirstMesh.primitives[0].vertexCount == 36);
  350. REQUIRE(FirstMesh.primitives[0].indexOffset == 0);
  351. REQUIRE(FirstMesh.primitives[0].vertexOffset == 0);
  352. WHEN("We merge the sphere into the box with renumbering the indices")
  353. {
  354. FirstMesh.merge(S, true);
  355. THEN("There are two primitives")
  356. {
  357. REQUIRE(FirstMesh.primitives.size() == 2);
  358. THEN("The index offset will be the number of indices in the first mesh. and the vertex offset is zero")
  359. {
  360. REQUIRE( static_cast<uint32_t>(FirstMesh.primitives[1].indexOffset) == FirstMesh.primitives[0].indexCount );
  361. REQUIRE( FirstMesh.primitives[1].vertexOffset == 0 );
  362. }
  363. THEN("Each index in the merged mesh is offset")
  364. {
  365. uint32_t indexOffset = FirstMesh.primitives[0].indexCount;
  366. for(uint32_t i=0; i < FirstMesh.primitives[1].indexCount; i++)
  367. {
  368. uint32_t j = i + static_cast<uint32_t>(FirstMesh.primitives[1].indexOffset);
  369. REQUIRE(FirstMesh.INDEX.get<uint32_t>(j) - indexOffset == S.INDEX.get<uint32_t>(i) );
  370. }
  371. }
  372. }
  373. }
  374. WHEN("We merge the sphere into the box without renumbering the indices")
  375. {
  376. FirstMesh.merge(S, false);
  377. THEN("There are two primitives")
  378. {
  379. REQUIRE(FirstMesh.primitives.size() == 2);
  380. }
  381. THEN("The index offset will be the number of indices in the first mesh. and the vertex offset is the number of vertices in the first mesh")
  382. {
  383. REQUIRE( static_cast<uint32_t>(FirstMesh.primitives[1].indexOffset) == FirstMesh.primitives[0].indexCount );
  384. REQUIRE( static_cast<uint32_t>(FirstMesh.primitives[1].vertexOffset) == FirstMesh.primitives[0].vertexCount );
  385. }
  386. THEN("Each index in the merged mesh is NOT offset")
  387. {
  388. for(uint32_t i=0; i < FirstMesh.primitives[1].indexCount; i++)
  389. {
  390. uint32_t j = i + static_cast<uint32_t>(FirstMesh.primitives[1].indexOffset);
  391. REQUIRE(S.INDEX.get<uint32_t>(i) == FirstMesh.INDEX.get<uint32_t>(j) );
  392. }
  393. }
  394. }
  395. }
  396. SCENARIO("Bounding Sphere")
  397. {
  398. // box mesh has position, normals, texcoords0, index
  399. auto B = gul::Box(1,1,1);
  400. auto S = gul::Sphere(1.0);
  401. auto br = B.calculateBoundingSphereRadius();
  402. auto sr = S.calculateBoundingSphereRadius();
  403. REQUIRE( sr > 0.99f );
  404. REQUIRE( sr < 1.09f );
  405. REQUIRE( br > 0.865f );
  406. REQUIRE( br < 0.867f ); // sqrt(1+1+1)
  407. {
  408. auto sr1 = S.calculateBoundingSphereRadius(S.primitives[0]);
  409. REQUIRE( sr1 > 0.99f );
  410. REQUIRE( sr1 < 1.09f );
  411. }
  412. {
  413. B.merge(S);
  414. auto sr1 = B.calculateBoundingSphereRadius(B.primitives[1]);
  415. REQUIRE( sr1 > 0.99f );
  416. REQUIRE( sr1 < 1.09f );
  417. }
  418. }
  419. SCENARIO("Test Base Primitives")
  420. {
  421. // box mesh has position, normals, texcoords0, index
  422. auto B = gul::Box(1,1,1);
  423. auto S = gul::Sphere(1.0);
  424. auto C = gul::Cylinder();
  425. REQUIRE( B.vertexCount() > 0);
  426. REQUIRE( S.vertexCount() > 0);
  427. REQUIRE( C.vertexCount() > 0);
  428. }
  429. SCENARIO("Load OBJ")
  430. {
  431. std::istringstream SSO;
  432. SSO.str(R"foo(# Blender v3.0.1 OBJ File: ''
  433. # www.blender.org
  434. mtllib untitled.mtl
  435. o Cube
  436. v 1.000000 1.000000 -1.000000
  437. v 1.000000 -1.000000 -1.000000
  438. v 1.000000 1.000000 1.000000
  439. v 1.000000 -1.000000 1.000000
  440. v -1.000000 1.000000 -1.000000
  441. v -1.000000 -1.000000 -1.000000
  442. v -1.000000 1.000000 1.000000
  443. v -1.000000 -1.000000 1.000000
  444. vt 0.625000 0.500000
  445. vt 0.875000 0.500000
  446. vt 0.875000 0.750000
  447. vt 0.625000 0.750000
  448. vt 0.375000 0.750000
  449. vt 0.625000 1.000000
  450. vt 0.375000 1.000000
  451. vt 0.375000 0.000000
  452. vt 0.625000 0.000000
  453. vt 0.625000 0.250000
  454. vt 0.375000 0.250000
  455. vt 0.125000 0.500000
  456. vt 0.375000 0.500000
  457. vt 0.125000 0.750000
  458. vn 0.0000 1.0000 0.0000
  459. vn 0.0000 0.0000 1.0000
  460. vn -1.0000 0.0000 0.0000
  461. vn 0.0000 -1.0000 0.0000
  462. vn 1.0000 0.0000 0.0000
  463. vn 0.0000 0.0000 -1.0000
  464. usemtl Material
  465. s off
  466. f 1/1/1 5/2/1 7/3/1 3/4/1
  467. f 4/5/2 3/4/2 7/6/2 8/7/2
  468. f 8/8/3 7/9/3 5/10/3 6/11/3
  469. f 6/12/4 2/13/4 4/5/4 8/14/4
  470. f 2/13/5 1/1/5 3/4/5 4/5/5
  471. f 6/11/6 5/10/6 1/1/6 2/13/6
  472. )foo");
  473. using vec3 = std::array<float, 3>;
  474. using vec2 = std::array<float, 2>;
  475. using tri_face = std::array<uint32_t, 3>;
  476. using quad_face = std::array<uint32_t, 4>;
  477. std::vector<vec3> pos, norm;
  478. std::vector<vec2> uv;
  479. std::vector<tri_face> tris;
  480. std::vector<quad_face> quads;
  481. using vertex_id = std::tuple<uint32_t, uint32_t, uint32_t>;
  482. std::map<vertex_id, uint32_t> vertex_to_index;
  483. std::string blah;
  484. std::string line;
  485. while(!SSO.eof())
  486. {
  487. std::getline(SSO, line);
  488. if(line.empty())
  489. continue;
  490. // std::cout << line << std::endl;
  491. if(line[1] == 'n')
  492. {
  493. std::istringstream ss(line);
  494. std::string v;
  495. vec3 & p = norm.emplace_back();
  496. ss >> v;
  497. ss >> p[0];
  498. ss >> p[1];
  499. ss >> p[2];
  500. std::cout << p[0] << ", " << p[1] << ", " << p[2] << std::endl;
  501. }
  502. else if(line[1] == 't')
  503. {
  504. std::istringstream ss(line);
  505. std::string v;
  506. vec2 & p = uv.emplace_back();
  507. ss >> v;
  508. ss >> p[0];
  509. ss >> p[1];
  510. std::cout << p[0] << ", " << p[1] << std::endl;
  511. }
  512. else if(line[0] == 'v')
  513. {
  514. std::istringstream ss(line);
  515. std::string v;
  516. vec3 & p = pos.emplace_back();
  517. ss >> v;
  518. ss >> p[0];
  519. ss >> p[1];
  520. ss >> p[2];
  521. std::cout << p[0] << ", " << p[1] << ", " << p[2] << std::endl;
  522. }
  523. else if(line[0] == 'f')
  524. {
  525. // f 6/11/6 5/10/6 1/1/6 2/13/6
  526. // f 6/11/6 5/10/6 1/1/6
  527. // f 6//6 5//6 1//6
  528. // f 6 5 1
  529. std::istringstream ss(line);
  530. std::string _b;
  531. ss >> _b; // read the 'f'
  532. auto _extractVertexID = [](std::string str)
  533. {
  534. std::istringstream s(str);
  535. vertex_id v = {};
  536. // can either be a/b/c
  537. // a//c
  538. // a
  539. s >> std::get<0>(v);
  540. if(s.eof())
  541. return v;
  542. if(s.peek() == '/')
  543. {
  544. s.get();
  545. }
  546. if(s.peek() == '/')
  547. {
  548. s.get();
  549. s >> std::get<2>(v);
  550. }
  551. else
  552. {
  553. s >> std::get<1>(v);
  554. }
  555. if(s.peek() == '/')
  556. {
  557. s.get();
  558. s >> std::get<2>(v);
  559. }
  560. return v;
  561. };
  562. std::array<vertex_id, 4> _faceIndex;
  563. uint32_t j=0;
  564. while(!ss.eof())
  565. {
  566. std::string vertex_id_str;
  567. ss >> vertex_id_str;
  568. if(!vertex_id_str.empty())
  569. {
  570. auto & V = _faceIndex[j++] = _extractVertexID(vertex_id_str);
  571. std::cout << std::get<0>(V) << " " << std::get<1>(V) << " " << std::get<2>(V) << std::endl;
  572. }
  573. }
  574. // we now have the verttex'x position index, normal index and uv index
  575. // in the form of a 3-tuple
  576. // Insert the tuple into the ma
  577. if(j==3) // triangle
  578. {
  579. tri_face t = { vertex_to_index.insert( {_faceIndex[0], static_cast<uint32_t>(vertex_to_index.size())}).first->second,
  580. vertex_to_index.insert( {_faceIndex[1], static_cast<uint32_t>(vertex_to_index.size())}).first->second,
  581. vertex_to_index.insert( {_faceIndex[2], static_cast<uint32_t>(vertex_to_index.size())}).first->second};
  582. tris.push_back(t);
  583. }
  584. if(j==4) // triangle
  585. {
  586. quad_face t = { vertex_to_index.insert( {_faceIndex[0], static_cast<uint32_t>(vertex_to_index.size())}).first->second,
  587. vertex_to_index.insert( {_faceIndex[1], static_cast<uint32_t>(vertex_to_index.size())}).first->second,
  588. vertex_to_index.insert( {_faceIndex[2], static_cast<uint32_t>(vertex_to_index.size())}).first->second,
  589. vertex_to_index.insert( {_faceIndex[3], static_cast<uint32_t>(vertex_to_index.size())}).first->second};
  590. quads.push_back(t);
  591. }
  592. // end
  593. }
  594. }
  595. for(auto & t : quads)
  596. {
  597. //std::cout << t[0] << ", " << t[1] << ", " << t[2] << ", " << t[3] << std::endl;
  598. tris.push_back( {t[0], t[1], t[2]});
  599. tris.push_back( {t[0], t[2], t[3]});
  600. }
  601. std::cout << "Total Unique Vertices: " << vertex_to_index.size() << std::endl;
  602. for(auto & t : tris)
  603. {
  604. std::cout << t[0] << ", " << t[1] << ", " << t[2] << std::endl;
  605. }
  606. pos.resize(vertex_to_index.size());
  607. norm.resize(vertex_to_index.size());
  608. uv.resize(vertex_to_index.size());
  609. gul::MeshPrimitive P;
  610. P.TEXCOORD_0.setType(gul::eType::VEC2);
  611. P.TEXCOORD_0.setComponent(gul::eComponentType::FLOAT);
  612. P.POSITION.setType(gul::eType::VEC3);
  613. P.POSITION.setComponent(gul::eComponentType::FLOAT);
  614. P.NORMAL.setType(gul::eType::VEC3);
  615. P.NORMAL.setComponent(gul::eComponentType::FLOAT);
  616. P.POSITION.resize(vertex_to_index.size());
  617. P.TEXCOORD_0.resize(vertex_to_index.size());
  618. P.NORMAL.resize(vertex_to_index.size());
  619. for(auto & [v, index] : vertex_to_index)
  620. {
  621. if(std::get<0>(v) != 0) P.POSITION.set(index , pos.at( std::get<0>(v)-1) );
  622. if(std::get<1>(v) != 0) P.NORMAL.set(index , norm.at(std::get<1>(v)-1) );
  623. if(std::get<2>(v) != 0) P.TEXCOORD_0.set(index, uv.at( std::get<2>(v)-1) );
  624. }
  625. if(P.NORMAL.attributeCount() != P.POSITION.attributeCount())
  626. P.NORMAL = {};
  627. if(P.TEXCOORD_0.attributeCount() != P.POSITION.attributeCount())
  628. P.TEXCOORD_0 = {};
  629. //for(auto & t : tris)
  630. //{
  631. // P.INDEX.push_back(t[0]);
  632. // P.INDEX.push_back(t[1]);
  633. // P.INDEX.push_back(t[2]);
  634. //}
  635. }