io_usd.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <stdint.h>
  2. #include <math.h>
  3. #include "tinyusdz/tinyusdz.hh"
  4. #include "iron_obj.h"
  5. #include "iron_array.h"
  6. extern "C" void *io_usd_parse(uint8_t *buf, size_t size) {
  7. tinyusdz::Scene scene;
  8. std::string warn;
  9. std::string err;
  10. tinyusdz::LoadUSDCFromMemory(buf, size, &scene, &warn, &err);
  11. tinyusdz::GeomMesh mesh = scene.geom_meshes[0];
  12. std::vector<float> vertices = mesh.points.buffer.GetAsVec3fArray();
  13. std::vector<uint32_t> dst_facevarying_indices;
  14. std::vector<float> dst_facevarying_normals;
  15. std::vector<float> dst_facevarying_texcoords;
  16. std::vector<float> facevarying_normals;
  17. mesh.GetFacevaryingNormals(&facevarying_normals);
  18. std::vector<float> facevarying_texcoords;
  19. mesh.GetFacevaryingTexcoords(&facevarying_texcoords);
  20. // Make facevarying indices
  21. size_t face_offset = 0;
  22. for (size_t fid = 0; fid < mesh.faceVertexCounts.size(); fid++) {
  23. int f_count = mesh.faceVertexCounts[fid];
  24. if (f_count == 3) {
  25. for (size_t f = 0; f < f_count; f++) {
  26. dst_facevarying_indices.push_back(mesh.faceVertexIndices[face_offset + f]);
  27. if (facevarying_normals.size()) {
  28. dst_facevarying_normals.push_back(facevarying_normals[3 * (face_offset + f) + 0]);
  29. dst_facevarying_normals.push_back(facevarying_normals[3 * (face_offset + f) + 1]);
  30. dst_facevarying_normals.push_back(facevarying_normals[3 * (face_offset + f) + 2]);
  31. }
  32. if (facevarying_texcoords.size()) {
  33. dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * (face_offset + f) + 0]);
  34. dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * (face_offset + f) + 1]);
  35. }
  36. }
  37. }
  38. else {
  39. // Simple triangulation with triangle-fan decomposition
  40. for (size_t f = 0; f < f_count - 2; f++) {
  41. size_t f0 = 0;
  42. size_t f1 = f + 1;
  43. size_t f2 = f + 2;
  44. size_t fid0 = face_offset + f0;
  45. size_t fid1 = face_offset + f1;
  46. size_t fid2 = face_offset + f2;
  47. dst_facevarying_indices.push_back(mesh.faceVertexIndices[fid0]);
  48. dst_facevarying_indices.push_back(mesh.faceVertexIndices[fid1]);
  49. dst_facevarying_indices.push_back(mesh.faceVertexIndices[fid2]);
  50. if (facevarying_normals.size()) {
  51. dst_facevarying_normals.push_back(facevarying_normals[3 * fid0 + 0]);
  52. dst_facevarying_normals.push_back(facevarying_normals[3 * fid0 + 1]);
  53. dst_facevarying_normals.push_back(facevarying_normals[3 * fid0 + 2]);
  54. dst_facevarying_normals.push_back(facevarying_normals[3 * fid1 + 0]);
  55. dst_facevarying_normals.push_back(facevarying_normals[3 * fid1 + 1]);
  56. dst_facevarying_normals.push_back(facevarying_normals[3 * fid1 + 2]);
  57. dst_facevarying_normals.push_back(facevarying_normals[3 * fid2 + 0]);
  58. dst_facevarying_normals.push_back(facevarying_normals[3 * fid2 + 1]);
  59. dst_facevarying_normals.push_back(facevarying_normals[3 * fid2 + 2]);
  60. }
  61. if (facevarying_texcoords.size()) {
  62. size_t fid0 = face_offset + f0;
  63. size_t fid1 = face_offset + f1;
  64. size_t fid2 = face_offset + f2;
  65. dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid0 + 0]);
  66. dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid0 + 1]);
  67. dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid1 + 0]);
  68. dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid1 + 1]);
  69. dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid2 + 0]);
  70. dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid2 + 1]);
  71. }
  72. }
  73. }
  74. face_offset += f_count;
  75. }
  76. int vertex_count = dst_facevarying_indices.size();
  77. int index_count = dst_facevarying_indices.size();
  78. // Pack positions to (-1, 1) range
  79. float hx = 0.0;
  80. float hy = 0.0;
  81. float hz = 0.0;
  82. for (int i = 0; i < vertices.size() / 3; ++i) {
  83. float f = fabsf(vertices[i * 3]);
  84. if (hx < f) hx = f;
  85. f = fabsf(vertices[i * 3 + 1]);
  86. if (hy < f) hy = f;
  87. f = fabsf(vertices[i * 3 + 2]);
  88. if (hz < f) hz = f;
  89. }
  90. float scale_pos = fmax(hx, fmax(hy, hz));
  91. float inv = 1 / scale_pos;
  92. // Pack into 16bit
  93. uint32_t *inda = (uint32_t *)malloc(sizeof(uint32_t) * index_count);
  94. for (int i = 0; i < index_count; ++i) {
  95. inda[i] = i;
  96. }
  97. int16_t *posa = (int16_t *)malloc(sizeof(int16_t) * vertex_count * 4);
  98. int16_t *nora = (int16_t *)malloc(sizeof(int16_t) * vertex_count * 2);
  99. int16_t *texa = (int16_t *)malloc(sizeof(int16_t) * vertex_count * 2);
  100. for (int i = 0; i < vertex_count; ++i) {
  101. posa[i * 4 ] = vertices[dst_facevarying_indices[i] * 3 ] * 32767 * inv;
  102. posa[i * 4 + 1] = vertices[dst_facevarying_indices[i] * 3 + 1] * 32767 * inv;
  103. posa[i * 4 + 2] = vertices[dst_facevarying_indices[i] * 3 + 2] * 32767 * inv;
  104. posa[i * 4 + 3] = dst_facevarying_normals[i * 3 + 2] * 32767;
  105. nora[i * 2 ] = dst_facevarying_normals[i * 3 ] * 32767;
  106. nora[i * 2 + 1] = dst_facevarying_normals[i * 3 + 1] * 32767;
  107. texa[i * 2 ] = dst_facevarying_texcoords[i * 2 ] * 32767;
  108. texa[i * 2 + 1] = (1.0 - dst_facevarying_texcoords[i * 2 + 1]) * 32767;
  109. }
  110. raw_mesh_t *raw = (raw_mesh_t *)calloc(sizeof(raw_mesh_t), 1);
  111. raw->name = (char *)malloc(mesh.name.length() + 1);
  112. strcpy(raw->name, mesh.name.c_str());
  113. raw->posa = (i16_array_t *)malloc(sizeof(i16_array_t));
  114. raw->posa->buffer = posa;
  115. raw->posa->length = raw->posa->capacity = vertex_count * 4;
  116. raw->nora = (i16_array_t *)malloc(sizeof(i16_array_t));
  117. raw->nora->buffer = nora;
  118. raw->nora->length = raw->nora->capacity = vertex_count * 2;
  119. raw->texa = (i16_array_t *)malloc(sizeof(i16_array_t));
  120. raw->texa->buffer = texa;
  121. raw->texa->length = raw->texa->capacity = vertex_count * 2;
  122. raw->inda = (u32_array_t *)malloc(sizeof(u32_array_t));
  123. raw->inda->buffer = inda;
  124. raw->inda->length = raw->inda->capacity = vertex_count * 2;
  125. raw->scale_pos = scale_pos;
  126. raw->scale_tex = 1.0;
  127. return raw;
  128. }