MeshPrimitive.h 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. #ifndef GUL_MESH_PRIMITIVE_H
  2. #define GUL_MESH_PRIMITIVE_H
  3. #include <variant>
  4. #include <vector>
  5. #include <array>
  6. #include <cstring>
  7. #include <tuple>
  8. #include <string>
  9. #include <fstream>
  10. #include <sstream>
  11. #include <map>
  12. #include <glm/glm.hpp>
  13. namespace gul
  14. {
  15. #define _VECTYPES(_T) \
  16. std::vector< _T >, \
  17. std::vector< glm::vec<2, _T, glm::defaultp> >, \
  18. std::vector< glm::vec<3, _T, glm::defaultp> >, \
  19. std::vector< glm::vec<4, _T, glm::defaultp> >
  20. using VertexAttribute_v = std::variant<
  21. _VECTYPES(float) ,
  22. _VECTYPES(double) ,
  23. _VECTYPES(int32_t) ,
  24. _VECTYPES(uint32_t) ,
  25. _VECTYPES(int16_t) ,
  26. _VECTYPES(uint16_t) ,
  27. _VECTYPES(int8_t) ,
  28. _VECTYPES(uint8_t) ,
  29. std::vector< glm::mat3 >,
  30. std::vector< glm::mat4 >,
  31. std::vector< glm::dmat3 >,
  32. std::vector< glm::dmat4 >
  33. >;
  34. #undef _VECTYPES
  35. template<typename T>
  36. VertexAttribute_v generateFromAccessor_t(uint32_t numComponents)
  37. {
  38. switch(numComponents)
  39. {
  40. case 1: return std::vector< T >();
  41. break;
  42. case 2: return std::vector< glm::vec<2, T, glm::defaultp > >();
  43. break;
  44. case 3: return std::vector< glm::vec<3, T, glm::defaultp > >();
  45. break;
  46. case 4: return std::vector< glm::vec<4, T, glm::defaultp > >();
  47. break;
  48. default:
  49. throw std::runtime_error("Not supported for vertex attributes");
  50. }
  51. }
  52. inline VertexAttribute_v generateFromGLTFAccessor(uint32_t GL_componentType, uint32_t numComponents)
  53. {
  54. switch(GL_componentType)
  55. {
  56. case 5120: return generateFromAccessor_t<int8_t>(numComponents);
  57. case 5121: return generateFromAccessor_t<uint8_t>(numComponents);
  58. case 5122: return generateFromAccessor_t<int16_t>(numComponents);
  59. case 5123: return generateFromAccessor_t<uint16_t>(numComponents);
  60. case 5124: return generateFromAccessor_t<int32_t>(numComponents);
  61. case 5125: return generateFromAccessor_t<uint32_t>(numComponents);
  62. case 5126: return generateFromAccessor_t<float>(numComponents);
  63. case 5130: return generateFromAccessor_t<double>(numComponents);
  64. default:
  65. throw std::runtime_error("Not supported component type");
  66. }
  67. }
  68. template<typename T>
  69. inline constexpr uint32_t getNumComponents()
  70. {
  71. if constexpr( std::is_fundamental<T>::value )
  72. {
  73. return 1u;
  74. }
  75. else // glm type
  76. {
  77. return static_cast<uint32_t>(T::length());
  78. }
  79. }
  80. /**
  81. * @brief byteSize
  82. * @param v
  83. * @return
  84. *
  85. * Returns the byte size of the entire attribute
  86. */
  87. inline uint64_t VertexAttributeByteSize(VertexAttribute_v const & v)
  88. {
  89. return std::visit( [&](auto && arg)
  90. {
  91. using V = std::decay_t<decltype(arg)>; //std::vector<attr_type>
  92. using attr_type = typename V::value_type;
  93. return arg.size() * sizeof(attr_type);
  94. }, v);
  95. }
  96. /**
  97. * @brief attributeSize
  98. * @param v
  99. * @return
  100. *
  101. * Returns the size of the attribute array's value_type
  102. */
  103. inline size_t VertexAttributeSizeOf(VertexAttribute_v const & v)
  104. {
  105. return std::visit( [&](auto && arg)
  106. {
  107. using V = std::decay_t<decltype(arg)>; //std::vector<attr_type>
  108. using attr_type = typename V::value_type;
  109. return sizeof(attr_type);
  110. }, v);
  111. }
  112. /**
  113. * @brief attributeCount
  114. * @param v
  115. * @return
  116. * Returns the number of attributes
  117. */
  118. inline size_t VertexAttributeCount(VertexAttribute_v const & v)
  119. {
  120. return std::visit( [&](auto && arg)
  121. {
  122. return arg.size();
  123. }, v);
  124. }
  125. /**
  126. * @brief attributeCount
  127. * @param v
  128. * @return
  129. * Returns the number of attributes
  130. */
  131. inline size_t VertexAttributeNumComponents(VertexAttribute_v const & v)
  132. {
  133. return std::visit( [&](auto && arg)
  134. {
  135. using V = std::decay_t<decltype(arg)>; //std::vector<attr_type>
  136. using attr_type = typename V::value_type;
  137. return getNumComponents<attr_type>();
  138. }, v);
  139. }
  140. /**
  141. * @brief VertexAttributeMerge
  142. * @param v
  143. * @return
  144. *
  145. * Merges all the values from B into A, returns the size of A before the merge.
  146. */
  147. inline size_t VertexAttributeMerge(VertexAttribute_v & A, VertexAttribute_v const & B)
  148. {
  149. return std::visit( [&](auto && arg)
  150. {
  151. using V = std::decay_t<decltype(arg)>; //std::vector<attr_type>
  152. auto c = arg.size();
  153. auto & b = std::get<V>(B);
  154. arg.insert(arg.end(), b.begin(), b.end());
  155. return c;
  156. }, A);
  157. }
  158. /**
  159. * @brief copySequential
  160. * @param data
  161. * @param V
  162. * @return
  163. *
  164. * Copies the attribute data sequentially
  165. * if given two attributes p and n,
  166. * the data is copied as follows
  167. *
  168. * p0,p1,p2,p3....n0,n1,n2,n3
  169. */
  170. inline std::vector<size_t> VertexAttributeCopySequential(void * data, std::vector<VertexAttribute_v const*> const & V)
  171. {
  172. std::vector<size_t> offsets;
  173. size_t off=0;
  174. for(auto & v : V)
  175. {
  176. if(v)
  177. {
  178. auto count = VertexAttributeCount(*v);
  179. if(count)
  180. {
  181. offsets.push_back( off);
  182. off += VertexAttributeByteSize(*v);
  183. }
  184. else
  185. {
  186. offsets.push_back(0);
  187. }
  188. }
  189. else
  190. {
  191. offsets.push_back(0);
  192. }
  193. }
  194. auto dOut = static_cast<uint8_t*>(data);
  195. for(auto & v : V)
  196. {
  197. if( v != nullptr)
  198. {
  199. std::visit( [&](auto && arg)
  200. {
  201. using T = std::decay_t<decltype(arg)>;
  202. std::memcpy(dOut, arg.data(), arg.size()*sizeof(typename T::value_type));
  203. dOut += arg.size()*sizeof(typename T::value_type);
  204. }, *v);
  205. }
  206. }
  207. return offsets;
  208. }
  209. /**
  210. * @brief strideCopy
  211. * @param start
  212. * @param v
  213. * @param stride
  214. *
  215. * Performs a stride copy of the attribute's data
  216. *
  217. * stride should be at least as large as attributeSize(v), otherwise
  218. * data will be overwrritten.
  219. */
  220. inline void VertexAttributeStrideCopy(void * start, VertexAttribute_v const &v, size_t stride)
  221. {
  222. return std::visit( [stride, start](auto && arg)
  223. {
  224. auto dOut = static_cast<uint8_t*>(start);
  225. for(auto & a : arg)
  226. {
  227. std::memcpy(dOut, &a, sizeof(a));
  228. dOut += stride;
  229. }
  230. }, v);
  231. }
  232. /**
  233. * @brief copyInterleaved
  234. * @param data
  235. * @param V
  236. * @param startIndex
  237. * @param count
  238. *
  239. * Copies the attribute data into the buffer but
  240. * interleaves each attribute.
  241. *
  242. * if given two attributes p and n,
  243. * the data is copied as follows
  244. *
  245. * p0,n0,p1,n1,p2,n2...
  246. */
  247. inline size_t VertexAttributeInterleaved(void * data, std::vector<VertexAttribute_v const*> const & V, size_t startIndex=0, size_t count=std::numeric_limits<size_t>::max())
  248. {
  249. //size_t byteSize=0;
  250. uint64_t stride=0;
  251. uint8_t * out = static_cast<uint8_t*>(data);
  252. //size_t off=0;
  253. (void)startIndex;
  254. for(auto & v : V)
  255. {
  256. auto attrCount = VertexAttributeCount(*v);
  257. if(attrCount)
  258. {
  259. count = std::min(attrCount,count);
  260. stride += VertexAttributeSizeOf(*v);
  261. }
  262. }
  263. size_t offset = 0;
  264. for(auto & v : V)
  265. {
  266. auto attrCount = VertexAttributeCount(*v);
  267. if(attrCount)
  268. {
  269. VertexAttributeStrideCopy(out + offset, *v, stride);
  270. offset += VertexAttributeSizeOf(*v);
  271. }
  272. }
  273. return stride * count;
  274. }
  275. enum class Topology
  276. {
  277. POINT_LIST = 0,
  278. LINE_LIST = 1,
  279. LINE_STRIP = 2,
  280. TRIANGLE_LIST = 3,
  281. TRIANGLE_STRIP = 4,
  282. TRIANGLE_FAN = 5,
  283. LINE_LIST_WITH_ADJACENCY = 6,
  284. LINE_STRIP_WITH_ADJACENCY = 7,
  285. TRIANGLE_LIST_WITH_ADJACENCY = 8,
  286. TRIANGLE_STRIP_WITH_ADJACENCY = 9,
  287. PATCH_LIST = 10,
  288. };
  289. struct DrawCall
  290. {
  291. uint32_t indexCount = 0;
  292. uint32_t vertexCount = 0;
  293. int32_t vertexOffset = 0;
  294. int32_t indexOffset = 0;
  295. Topology topology = Topology::TRIANGLE_LIST;
  296. };
  297. /**
  298. * @brief The MeshPrimitive struct
  299. *
  300. * A Mesh Primitive is a class which allows
  301. * you to represent a triangular mesh
  302. *
  303. * The attributes are
  304. */
  305. struct MeshPrimitive
  306. {
  307. using attribute_type = VertexAttribute_v;
  308. attribute_type POSITION = std::vector<glm::vec3> ();
  309. attribute_type NORMAL = std::vector<glm::vec3> ();
  310. attribute_type TANGENT = std::vector<glm::vec3> ();
  311. attribute_type TEXCOORD_0 = std::vector<glm::vec2> ();
  312. attribute_type TEXCOORD_1 = std::vector<glm::vec2> ();
  313. attribute_type COLOR_0 = std::vector<glm::u8vec4>();
  314. attribute_type JOINTS_0 = std::vector<glm::u16vec4>();
  315. attribute_type WEIGHTS_0 = std::vector<glm::vec4>();
  316. attribute_type INDEX = std::vector<uint32_t>();
  317. Topology topology = Topology::TRIANGLE_LIST;
  318. std::vector<DrawCall> subMeshes;
  319. void clear()
  320. {
  321. for(auto * attr : {&POSITION ,
  322. &NORMAL ,
  323. &TANGENT ,
  324. &TEXCOORD_0,
  325. &TEXCOORD_1,
  326. &COLOR_0 ,
  327. &JOINTS_0 ,
  328. &WEIGHTS_0 ,
  329. &INDEX})
  330. {
  331. std::visit([](auto&& arg)
  332. {
  333. arg.clear();
  334. }, *attr );
  335. }
  336. }
  337. /**
  338. * @brief calculateDeviceSize
  339. * @return
  340. *
  341. * Calculate the amount of bytes this mesh takes on the
  342. * the GPU if all vertices were placed one after the
  343. * other
  344. */
  345. uint64_t calculateDeviceSize() const
  346. {
  347. uint64_t size = 0;
  348. size += VertexAttributeByteSize(POSITION );
  349. size += VertexAttributeByteSize(NORMAL );
  350. size += VertexAttributeByteSize(TANGENT );
  351. size += VertexAttributeByteSize(TEXCOORD_0);
  352. size += VertexAttributeByteSize(TEXCOORD_1);
  353. size += VertexAttributeByteSize(COLOR_0 );
  354. size += VertexAttributeByteSize(JOINTS_0 );
  355. size += VertexAttributeByteSize(WEIGHTS_0 );
  356. size += VertexAttributeByteSize(INDEX);
  357. return size;
  358. }
  359. /**
  360. * @brief isSimilar
  361. * @param P
  362. * @return
  363. *
  364. * Returns true if two mesh primitives are similar.
  365. * Two mesh primitives are similar if they have the same attributes
  366. * and their attribute have the same type
  367. */
  368. bool isSimilar( MeshPrimitive const & P) const
  369. {
  370. return
  371. POSITION .index() == P.POSITION .index() &&
  372. NORMAL .index() == P.NORMAL .index() &&
  373. TANGENT .index() == P.TANGENT .index() &&
  374. TEXCOORD_0.index() == P.TEXCOORD_0 .index() &&
  375. TEXCOORD_1.index() == P.TEXCOORD_1 .index() &&
  376. COLOR_0 .index() == P.COLOR_0 .index() &&
  377. JOINTS_0 .index() == P.JOINTS_0 .index() &&
  378. WEIGHTS_0 .index() == P.WEIGHTS_0 .index() &&
  379. INDEX .index() == P.INDEX .index();
  380. }
  381. size_t indexCount() const
  382. {
  383. return VertexAttributeCount(INDEX);
  384. }
  385. size_t vertexCount() const
  386. {
  387. return VertexAttributeCount(POSITION);
  388. }
  389. DrawCall getDrawCall() const
  390. {
  391. DrawCall dc;
  392. dc.indexOffset = static_cast<int32_t>(0);
  393. dc.vertexOffset = static_cast<int32_t>(0);
  394. dc.vertexCount = static_cast<uint32_t>(vertexCount());
  395. dc.indexCount = static_cast<uint32_t>(indexCount());
  396. dc.topology = topology;
  397. return dc;
  398. }
  399. DrawCall merge(MeshPrimitive const & P)
  400. {
  401. DrawCall dc;
  402. dc.indexOffset = static_cast<int32_t>(indexCount() );
  403. dc.vertexOffset = static_cast<int32_t>(vertexCount());
  404. dc.vertexCount = static_cast<uint32_t>(P.vertexCount());
  405. dc.indexCount = static_cast<uint32_t>(P.indexCount() );
  406. if( isSimilar(P) )
  407. {
  408. VertexAttributeMerge(POSITION , P.POSITION );
  409. VertexAttributeMerge(NORMAL , P.NORMAL );
  410. VertexAttributeMerge(TANGENT , P.TANGENT );
  411. VertexAttributeMerge(TEXCOORD_0, P.TEXCOORD_0);
  412. VertexAttributeMerge(TEXCOORD_1, P.TEXCOORD_1);
  413. VertexAttributeMerge(COLOR_0 , P.COLOR_0 );
  414. VertexAttributeMerge(JOINTS_0 , P.JOINTS_0 );
  415. VertexAttributeMerge(WEIGHTS_0 , P.WEIGHTS_0 );
  416. VertexAttributeMerge(INDEX , P.INDEX );
  417. subMeshes.push_back(dc);
  418. return dc;
  419. }
  420. throw std::runtime_error("MeshPrimitives are not similar");
  421. }
  422. /**
  423. * @brief copySequential
  424. * @param data
  425. * @return
  426. *
  427. * Copies all the vertex attributes sequentually into the provided buffer
  428. * and returns the offsets of each attribute
  429. *
  430. * [p0,p1,p2,n0,n1,n2,t0,t1,t2...]
  431. *
  432. *
  433. */
  434. inline std::vector<size_t> copySequential(void * data) const
  435. {
  436. return VertexAttributeCopySequential(data,
  437. {
  438. &POSITION,
  439. &NORMAL,
  440. &TANGENT,
  441. &TEXCOORD_0,
  442. &TEXCOORD_1,
  443. &COLOR_0,
  444. &JOINTS_0,
  445. &WEIGHTS_0,
  446. &INDEX
  447. });
  448. }
  449. inline size_t copyVertexAttributesInterleaved(void * data) const
  450. {
  451. size_t attrCount=0;
  452. auto stride = calculateInterleavedStride();
  453. uint8_t * offset = static_cast<uint8_t*>(data);
  454. for(auto & V : { &POSITION,
  455. &NORMAL,
  456. &TANGENT,
  457. &TEXCOORD_0,
  458. &TEXCOORD_1,
  459. &COLOR_0,
  460. &JOINTS_0,
  461. &WEIGHTS_0})
  462. {
  463. auto count = gul::VertexAttributeCount(*V);
  464. if( count != 0)
  465. {
  466. VertexAttributeStrideCopy(offset, *V, stride);
  467. offset += gul::VertexAttributeSizeOf(*V);
  468. attrCount = std::max(count, attrCount);
  469. }
  470. }
  471. return attrCount * stride;
  472. //return VertexAttributeInterleaved(data,
  473. // {
  474. // &POSITION,
  475. // &NORMAL,
  476. // &TANGENT,
  477. // &TEXCOORD_0,
  478. // &TEXCOORD_1,
  479. // &COLOR_0,
  480. // &JOINTS_0,
  481. // &WEIGHTS_0,
  482. // });
  483. }
  484. inline size_t copyIndex(void * data) const
  485. {
  486. return std::visit( [data](auto && arg)
  487. {
  488. using type_ = typename std::decay_t<decltype(arg)>::value_type;
  489. std::memcpy(data, arg.data(), arg.size() * sizeof(type_));
  490. return arg.size() * sizeof(type_);
  491. }, INDEX);
  492. }
  493. inline size_t calculateInterleavedStride() const
  494. {
  495. size_t stride = 0;
  496. for(auto & V : { &POSITION,
  497. &NORMAL,
  498. &TANGENT,
  499. &TEXCOORD_0,
  500. &TEXCOORD_1,
  501. &COLOR_0,
  502. &JOINTS_0,
  503. &WEIGHTS_0})
  504. {
  505. auto count = gul::VertexAttributeCount(*V);
  506. if(count)
  507. {
  508. stride += gul::VertexAttributeSizeOf(*V);
  509. }
  510. }
  511. return stride;
  512. }
  513. inline uint64_t calculateInterleavedBufferSize() const
  514. {
  515. size_t bufferSize = 0;
  516. for(auto & V : { &POSITION,
  517. &NORMAL,
  518. &TANGENT,
  519. &TEXCOORD_0,
  520. &TEXCOORD_1,
  521. &COLOR_0,
  522. &JOINTS_0,
  523. &WEIGHTS_0})
  524. {
  525. auto count = gul::VertexAttributeCount(*V);
  526. if(count)
  527. {
  528. bufferSize += gul::VertexAttributeByteSize(*V);
  529. }
  530. }
  531. return bufferSize;
  532. }
  533. /**
  534. * @brief fuseVertices
  535. *
  536. * Fuse near by vertices. This may not be accurate
  537. */
  538. void fuseVertices()
  539. {
  540. std::map< std::tuple<int32_t, int32_t, int32_t>, uint32_t> posToIndex;
  541. auto & _POS = std::get< std::vector<glm::vec3> >(POSITION);
  542. auto & _NOR = std::get< std::vector<glm::vec3> >(NORMAL);
  543. auto & _UV = std::get< std::vector<glm::vec2> >(TEXCOORD_0);
  544. auto & _INDEX = std::get< std::vector<uint32_t> >(INDEX);
  545. std::vector<glm::vec3> NEW_POS;
  546. std::vector<glm::vec3> NEW_NOR;
  547. std::vector<glm::vec2> NEW_UV;
  548. uint32_t index = 0;
  549. uint32_t j=0;
  550. for(auto & p : _POS)
  551. {
  552. glm::ivec3 P( p*100.0f );
  553. if( posToIndex.insert( { {P.x, P.y, P.z}, index }).second)
  554. {
  555. NEW_POS.push_back(p);
  556. if(!_NOR.empty())
  557. NEW_NOR.push_back(_NOR[j]);
  558. if(!_UV.empty())
  559. NEW_UV.push_back(_UV[j]);
  560. index++;
  561. }
  562. j++;
  563. }
  564. std::vector<uint32_t> newINDEX;
  565. for(auto i : _INDEX)
  566. {
  567. auto & p = _POS[i];
  568. glm::ivec3 P( p*100.0f );
  569. newINDEX.push_back( posToIndex[{P.x,P.y,P.z}]);
  570. }
  571. INDEX = std::move(newINDEX);
  572. POSITION = std::move(NEW_POS);
  573. NORMAL = std::move(NEW_NOR);
  574. TEXCOORD_0= std::move(NEW_UV);
  575. }
  576. void rebuildNormals()
  577. {
  578. if( std::holds_alternative< std::vector<uint32_t> >(INDEX))
  579. {
  580. auto & I = std::get< std::vector<uint32_t > >(INDEX);
  581. auto & P = std::get< std::vector<glm::vec3> >(POSITION);
  582. std::vector< glm::vec3 > normals(P.size(), glm::vec3(0,0,0));
  583. for(size_t i=0;i<I.size();i+=3)
  584. {
  585. auto v1 = P[i+1] - P[i];
  586. auto v2 = P[i+2] - P[i];
  587. auto n = glm::cross(v1,v2);
  588. normals[i] += n;
  589. normals[i+1] += n;
  590. normals[i+2] += n;
  591. }
  592. for(auto & n : normals)
  593. {
  594. n = glm::normalize(n);
  595. }
  596. NORMAL = std::move(normals);
  597. }
  598. }
  599. };
  600. inline MeshPrimitive Box(float dx , float dy , float dz )
  601. {
  602. using _vec2 = glm::vec2;//std::array<float,2>;
  603. using _vec3 = glm::vec3;//std::array<float,3>;
  604. MeshPrimitive M;
  605. auto & P = std::get< std::vector<glm::vec3> >(M.POSITION);
  606. auto & N = std::get< std::vector<glm::vec3> >(M.NORMAL);
  607. auto & U = std::get< std::vector<glm::vec2> >(M.TEXCOORD_0);
  608. auto & I = std::get< std::vector<uint32_t > >(M.INDEX);
  609. // | Position | UV | Normal |
  610. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{0.0f, 0.0f, 1.0f}) ;
  611. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{0.0f, 0.0f, 1.0f}) ;
  612. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{0.0f, 0.0f, 1.0f}) ;
  613. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{0.0f, 0.0f, 1.0f}) ;
  614. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{0.0f, 0.0f, 1.0f}) ;
  615. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{0.0f, 0.0f, 1.0f}) ;
  616. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{0.0f, 0.0f, -1.0f}) ;
  617. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{0.0f, 0.0f, -1.0f}) ;
  618. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{0.0f, 0.0f, -1.0f}) ;
  619. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{0.0f, 0.0f, -1.0f}) ;
  620. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{0.0f, 0.0f, -1.0f}) ;
  621. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{0.0f, 0.0f, -1.0f}) ;
  622. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{-1.0f, 0.0f, 0.0f }) ;
  623. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{-1.0f, 0.0f, 0.0f }) ;
  624. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{-1.0f, 0.0f, 0.0f }) ;
  625. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{-1.0f, 0.0f, 0.0f }) ;
  626. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{-1.0f, 0.0f, 0.0f }) ;
  627. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{-1.0f, 0.0f, 0.0f }) ;
  628. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{1.0f, 0.0f, 0.0f }) ;
  629. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{1.0f, 0.0f, 0.0f }) ;
  630. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{1.0f, 0.0f, 0.0f }) ;
  631. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{1.0f, 0.0f, 0.0f }) ;
  632. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{1.0f, 0.0f, 0.0f }) ;
  633. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{1.0f, 0.0f, 0.0f }) ;
  634. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{0.0f,-1.0f, 0.0f }) ;
  635. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{0.0f,-1.0f, 0.0f }) ;
  636. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{0.0f,-1.0f, 0.0f }) ;
  637. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{0.0f,-1.0f, 0.0f }) ;
  638. P.push_back( _vec3{dx - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{0.0f,-1.0f, 0.0f }) ;
  639. P.push_back( _vec3{0.0f - 0.5f*dx ,0.0f - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{0.0f,-1.0f, 0.0f }) ;
  640. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{0.0f, 1.0f, 0.0f }) ;
  641. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{1.0f,1.0f}) ; N.push_back( _vec3{0.0f, 1.0f, 0.0f }) ;
  642. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{0.0f, 1.0f, 0.0f }) ;
  643. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,dz -0.5f*dz} ) ; U.push_back( _vec2{0.0f,1.0f}) ; N.push_back( _vec3{0.0f, 1.0f, 0.0f }) ;
  644. P.push_back( _vec3{dx - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{1.0f,0.0f}) ; N.push_back( _vec3{0.0f, 1.0f, 0.0f }) ;
  645. P.push_back( _vec3{0.0f - 0.5f*dx ,dy - 0.5f*dy ,0.0f -0.5f*dz} ) ; U.push_back( _vec2{0.0f,0.0f}) ; N.push_back( _vec3{0.0f, 1.0f, 0.0f }) ;
  646. //=========================
  647. // Edges of the triangle : postion delta
  648. //=========================
  649. for( uint16_t j=0;j<36;j++)
  650. I.push_back( j );
  651. return M;
  652. }
  653. inline MeshPrimitive Box(float dx )
  654. {
  655. return Box(dx,dx,dx);
  656. }
  657. inline MeshPrimitive Grid(int length, int width, int dl=1, int dw=1, int majorL=5, int majorW=5, float lscale=1.0f, float wscale=1.0f)
  658. {
  659. using _vec3 = glm::vec3;//std::array<float,3>;
  660. using _uvec4 = glm::u8vec4;//std::array<uint8_t,4>;
  661. MeshPrimitive M;
  662. M.topology = Topology::LINE_LIST;
  663. auto & P = std::get< std::vector<glm::vec3> >(M.POSITION);
  664. auto & C = std::get< std::vector<glm::u8vec4> >(M.COLOR_0);
  665. //_uvec4 xColor{1,1,1,255};
  666. _uvec4 xColor{80,80,80,255};
  667. _uvec4 majorColor{128,128,128,255};
  668. // _uvec4 minorColor{255,0,0,255};
  669. _uvec4 borderColor{255,255,255,255};
  670. for(int x=-length;x<=length;x+=dl)
  671. {
  672. _vec3 p0{ static_cast<float>(x)*lscale, 0.0f, static_cast<float>(-width)*wscale };
  673. _vec3 p1{ static_cast<float>(x)*lscale, 0.0f, static_cast<float>( width)*wscale };
  674. P.push_back(p0);
  675. P.push_back(p1);
  676. if( x == -length || x==length)
  677. {
  678. C.push_back(borderColor);
  679. C.push_back(borderColor);
  680. }
  681. else if( x % majorL==0)
  682. {
  683. C.push_back(majorColor);
  684. C.push_back(majorColor);
  685. }
  686. else
  687. {
  688. C.push_back(xColor);
  689. C.push_back(xColor);
  690. }
  691. }
  692. for(int x=-width;x<=width;x+=dw)
  693. {
  694. _vec3 p0{ static_cast<float>( length)*lscale, 0.0, static_cast<float>(x)*wscale };
  695. _vec3 p1{ static_cast<float>(-length)*lscale, 0.0, static_cast<float>(x)*wscale };
  696. P.push_back(p0);
  697. P.push_back(p1);
  698. if( x == -length || x==length)
  699. {
  700. C.push_back(borderColor);
  701. C.push_back(borderColor);
  702. }
  703. else if( x % majorW==0)
  704. {
  705. C.push_back(majorColor);
  706. C.push_back(majorColor);
  707. }
  708. else
  709. {
  710. C.push_back(xColor);
  711. C.push_back(xColor);
  712. }
  713. }
  714. return M;
  715. }
  716. inline MeshPrimitive Sphere(float radius , uint32_t rings=20, uint32_t sectors=20)
  717. {
  718. using _vec2 = glm::vec2;//std::array<float,2>;
  719. using _vec3 = glm::vec3;//std::array<float,3>;
  720. MeshPrimitive M;
  721. auto & P = std::get< std::vector<glm::vec3> >(M.POSITION);
  722. auto & N = std::get< std::vector<glm::vec3> >(M.NORMAL);
  723. auto & U = std::get< std::vector<glm::vec2> >(M.TEXCOORD_0);
  724. auto & I = std::get< std::vector<uint32_t > >(M.INDEX);
  725. float const R = 1.0f / static_cast<float>(rings-1);
  726. float const S = 1.0f / static_cast<float>(sectors-1);
  727. unsigned int r, s;
  728. for(r = 0; r < rings; r++)
  729. {
  730. auto rf = static_cast<float>(r);
  731. for(s = 0; s < sectors; s++)
  732. {
  733. auto sf = static_cast<float>(s);
  734. float const y = std::sin( -3.141592653589f*0.5f + 3.141592653589f * rf * R );
  735. float const x = std::cos(2*3.141592653589f * sf * S) * std::sin( 3.141592653589f * rf * R );
  736. float const z = std::sin(2*3.141592653589f * sf * S) * std::sin( 3.141592653589f * rf * R );
  737. P.push_back( _vec3{ radius*x ,radius*y ,radius*z} );
  738. U.push_back( _vec2{sf*S, rf*R} );
  739. N.push_back( _vec3{x,y,z} );
  740. }
  741. }
  742. for(r = 0 ; r < rings - 1 ; r++)
  743. {
  744. for(s = 0 ; s < sectors - 1 ; s++)
  745. {
  746. I.push_back( static_cast<uint16_t>( (r+1) * sectors + s) ); //0
  747. I.push_back( static_cast<uint16_t>( (r+1) * sectors + (s+1) ) ); //1
  748. I.push_back( static_cast<uint16_t>( r * sectors + (s+1) )); //2
  749. I.push_back( static_cast<uint16_t>( (r+1) * sectors + s )); //0
  750. I.push_back( static_cast<uint16_t>( r * sectors + (s+1) )); //2
  751. I.push_back( static_cast<uint16_t>( r * sectors + s )); //3
  752. }
  753. }
  754. return M;
  755. }
  756. /**
  757. * @brief Imposter
  758. * @return
  759. *
  760. * An imposter is a simple quad in the XY plane
  761. */
  762. inline MeshPrimitive Imposter(float sideLength=1.0f)
  763. {
  764. MeshPrimitive M;
  765. auto & P = std::get< std::vector<glm::vec3> >(M.POSITION);
  766. auto & N = std::get< std::vector<glm::vec3> >(M.NORMAL);
  767. auto & I = std::get< std::vector<uint32_t > >(M.INDEX);
  768. auto & U = std::get< std::vector<glm::vec2> >(M.TEXCOORD_0);
  769. P.emplace_back(-sideLength,-sideLength,0);
  770. P.emplace_back( sideLength,-sideLength,0);
  771. P.emplace_back( sideLength, sideLength,0);
  772. P.emplace_back(-sideLength, sideLength,0);
  773. U.emplace_back( 0.0f, 1.0f);
  774. U.emplace_back( 1.0f, 1.0f);
  775. U.emplace_back( 1.0f, 0.0f);
  776. U.emplace_back( 0.0f, 0.0f);
  777. N.emplace_back(0,0,1);
  778. N.emplace_back(0,0,1);
  779. N.emplace_back(0,0,1);
  780. N.emplace_back(0,0,1);
  781. I = {0,1,2,0,2,3};
  782. return M;
  783. }
  784. inline MeshPrimitive ReadOBJ(std::ifstream & in)
  785. {
  786. std::vector< glm::vec3 > position;
  787. std::vector< glm::vec3 > normal;
  788. std::vector< glm::vec2 > uv;
  789. struct faceIndex
  790. {
  791. uint32_t p=0;
  792. uint32_t t=0;
  793. uint32_t n=0;
  794. };
  795. std::vector< faceIndex > quads;
  796. std::vector< faceIndex > tris;
  797. auto split = [](std::string s, std::string delimiter)
  798. {
  799. using namespace std;
  800. size_t pos_start = 0, pos_end, delim_len = delimiter.length();
  801. string token;
  802. vector<string> res;
  803. while ((pos_end = s.find (delimiter, pos_start)) != string::npos) {
  804. token = s.substr (pos_start, pos_end - pos_start);
  805. pos_start = pos_end + delim_len;
  806. res.push_back (token);
  807. }
  808. res.push_back (s.substr (pos_start));
  809. return res;
  810. };
  811. auto getFace = [&](std::string s) -> faceIndex
  812. {
  813. faceIndex F;
  814. auto S = split(s, "/");
  815. if(S.size() == 3)
  816. {
  817. F.p = static_cast<uint32_t>(std::stoi( S[0] ));
  818. if( S[1].size() != 0)
  819. F.t = static_cast<uint32_t>(std::stoi(S[1]));
  820. if( S[2].size() != 0)
  821. F.n = static_cast<uint32_t>(std::stoi(S[2]));
  822. return F;
  823. }
  824. else if(S.size() == 1)
  825. {
  826. F.p = static_cast<uint32_t>(std::stoi( S[0] ));
  827. }
  828. return F;
  829. };
  830. while(!in.eof())
  831. {
  832. std::string line;
  833. std::string fullLine;
  834. std::getline(in, fullLine);
  835. std::istringstream ins(fullLine);
  836. ins >> line;
  837. if(line == "v")
  838. {
  839. glm::vec3 p;
  840. ins >> p.x;
  841. ins >> p.y;
  842. ins >> p.z;
  843. position.push_back(p);
  844. }
  845. else if(line == "vn")
  846. {
  847. glm::vec3 p;
  848. ins >> p.x;
  849. ins >> p.y;
  850. ins >> p.z;
  851. normal.push_back(p);
  852. }
  853. else if(line == "vt")
  854. {
  855. glm::vec2 p;
  856. ins >> p.x;
  857. ins >> p.y;
  858. uv.push_back(p);
  859. }
  860. else if(line == "f")
  861. {
  862. std::string faceLine;
  863. if(fullLine.front() == 'f')
  864. {
  865. faceLine = fullLine.substr(2);
  866. }
  867. auto sp = split(faceLine, " ");
  868. if(sp.size() == 4)
  869. {
  870. for(auto & v : sp)
  871. {
  872. faceIndex Fa = getFace(v);
  873. quads.push_back(Fa);
  874. }
  875. }
  876. if(sp.size() == 3)
  877. {
  878. for(auto & v : sp)
  879. {
  880. faceIndex Fa = getFace(v);
  881. tris.push_back(Fa);
  882. }
  883. }
  884. //std::cout << faceLine << std::endl;
  885. }
  886. else
  887. {
  888. //std::string bah;
  889. //std::getline(in, bah);
  890. // std::cout << line << std::endl;
  891. }
  892. }
  893. gul::MeshPrimitive M;
  894. std::vector<glm::vec3> POSITION;
  895. std::vector<glm::vec2> TEXCOORD;
  896. std::vector<glm::vec3> NORMAL;
  897. std::vector<uint32_t> INDEX;
  898. for(size_t i=0;i<tris.size(); i+= 3)
  899. {
  900. auto & I1 = tris[i];
  901. auto & I2 = tris[i+1];
  902. auto & I3 = tris[i+2];
  903. POSITION.push_back(position[I1.p-1]);
  904. POSITION.push_back(position[I2.p-1]);
  905. POSITION.push_back(position[I3.p-1]);
  906. if(I1.n*I2.n*I3.n > 0 )
  907. {
  908. NORMAL.push_back(normal[I1.n-1]);
  909. NORMAL.push_back(normal[I2.n-1]);
  910. NORMAL.push_back(normal[I3.n-1]);
  911. }
  912. if(I1.t*I2.t*I3.t > 0 )
  913. {
  914. TEXCOORD.push_back(uv[I1.t-1]);
  915. TEXCOORD.push_back(uv[I2.t-1]);
  916. TEXCOORD.push_back(uv[I3.t-1]);
  917. }
  918. }
  919. for(size_t i=0;i<quads.size(); i+= 4)
  920. {
  921. auto & I1 = quads[i];
  922. auto & I2 = quads[i+1];
  923. auto & I3 = quads[i+2];
  924. auto & I4 = quads[i+3];
  925. POSITION.push_back(position[I1.p - 1]);
  926. POSITION.push_back(position[I2.p - 1]);
  927. POSITION.push_back(position[I3.p - 1]);
  928. POSITION.push_back(position[I1.p - 1]);
  929. POSITION.push_back(position[I3.p - 1]);
  930. POSITION.push_back(position[I4.p - 1]);
  931. NORMAL.push_back(normal[I1.n - 1] );
  932. NORMAL.push_back(normal[I2.n - 1] );
  933. NORMAL.push_back(normal[I3.n - 1] );
  934. NORMAL.push_back(normal[I1.n - 1] );
  935. NORMAL.push_back(normal[I3.n - 1] );
  936. NORMAL.push_back(normal[I4.n - 1] );
  937. TEXCOORD.push_back(uv[I1.t - 1] );
  938. TEXCOORD.push_back(uv[I2.t - 1] );
  939. TEXCOORD.push_back(uv[I3.t - 1] );
  940. TEXCOORD.push_back(uv[I1.t - 1] );
  941. TEXCOORD.push_back(uv[I3.t - 1] );
  942. TEXCOORD.push_back(uv[I4.t - 1] );
  943. }
  944. uint32_t i=0;
  945. for(auto & x : POSITION)
  946. {
  947. (void)x;
  948. INDEX.push_back(i++);
  949. }
  950. M.POSITION = std::move(POSITION);
  951. M.INDEX = std::move(INDEX);
  952. if(NORMAL.size() == 0)
  953. {
  954. M.rebuildNormals();
  955. }
  956. else
  957. {
  958. M.NORMAL = std::move(NORMAL);
  959. }
  960. M.TEXCOORD_0 = std::move(TEXCOORD);
  961. return M;
  962. }
  963. }
  964. #endif