import_obj.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. function import_obj_run(path: string, replace_existing: bool = true) {
  2. let i: split_type_t = context_raw.split_by;
  3. let is_udim: bool = i == split_type_t.UDIM;
  4. let split_code: i32 =
  5. (i == split_type_t.OBJECT || is_udim) ? char_code_at("o", 0) :
  6. i == split_type_t.GROUP ? char_code_at("g", 0) :
  7. char_code_at("u", 0); // usemtl
  8. let b: buffer_t = data_get_blob(path);
  9. if (is_udim) {
  10. let part: raw_mesh_t = obj_parse(b, split_code, 0, is_udim);
  11. let name: string = part.name;
  12. for (let i: i32 = 0; i < part.udims.length; ++i) {
  13. let a: u32_array_t = part.udims[i];
  14. if (a.length == 0) {
  15. continue;
  16. }
  17. let u: i32 = i % part.udims_u;
  18. let v: i32 = math_floor(i / part.udims_u);
  19. let id: i32 = (1000 + v * 10 + u + 1);
  20. part.name = name + "." + id;
  21. part.inda = a;
  22. if (i == 0) {
  23. if (replace_existing) {
  24. import_mesh_make_mesh(part);
  25. }
  26. else {
  27. import_mesh_add_mesh(part);
  28. }
  29. }
  30. else {
  31. import_mesh_add_mesh(part);
  32. }
  33. }
  34. }
  35. else {
  36. let parts: raw_mesh_t[] = [];
  37. let part: raw_mesh_t = obj_parse(b, split_code, 0, false);
  38. array_push(parts, part);
  39. while (part.has_next) {
  40. part = obj_parse(b, split_code, part.pos, false);
  41. // This part does not contain faces (may contain lines only)
  42. if (part.inda.length == 0) {
  43. continue;
  44. }
  45. array_push(parts, part);
  46. }
  47. if (context_raw.split_by == split_type_t.MATERIAL) {
  48. let posa0: i16_array_t;
  49. let posa1: i16_array_t;
  50. let nora0: i16_array_t;
  51. let nora1: i16_array_t;
  52. let texa0: i16_array_t;
  53. let texa1: i16_array_t;
  54. let inda0: u32_array_t;
  55. let inda1: u32_array_t;
  56. // Merge to single object per material
  57. for (let i: i32 = 0; i < parts.length; ++i) {
  58. let j: i32 = i + 1;
  59. while (j < parts.length) {
  60. let iname: string = parts[i].name;
  61. let jname: string = parts[j].name;
  62. if (iname == jname) {
  63. posa0 = parts[i].posa;
  64. posa1 = parts[j].posa;
  65. nora0 = parts[i].nora;
  66. nora1 = parts[j].nora;
  67. texa0 = parts[i].texa != null ? parts[i].texa : null;
  68. texa1 = parts[j].texa != null ? parts[j].texa : null;
  69. inda0 = parts[i].inda;
  70. inda1 = parts[j].inda;
  71. let voff: i32 = math_floor(posa0.length / 4);
  72. // Repack merged positions
  73. let posa32: f32_array_t = f32_array_create(math_floor(posa0.length / 4) * 3 + math_floor(posa1.length / 4) * 3);
  74. for (let k: i32 = 0; k < math_floor(posa0.length / 4); ++k) {
  75. posa32[k * 3 ] = posa0[k * 4 ] / 32767 * parts[i].scale_pos;
  76. posa32[k * 3 + 1] = posa0[k * 4 + 1] / 32767 * parts[i].scale_pos;
  77. posa32[k * 3 + 2] = posa0[k * 4 + 2] / 32767 * parts[i].scale_pos;
  78. }
  79. for (let k: i32 = 0; k < math_floor(posa1.length / 4); ++k) {
  80. posa32[voff * 3 + k * 3 ] = posa1[k * 4 ] / 32767 * parts[j].scale_pos;
  81. posa32[voff * 3 + k * 3 + 1] = posa1[k * 4 + 1] / 32767 * parts[j].scale_pos;
  82. posa32[voff * 3 + k * 3 + 2] = posa1[k * 4 + 2] / 32767 * parts[j].scale_pos;
  83. }
  84. let scale_pos: f32 = 0.0;
  85. for (let k: i32 = 0; k < posa32.length; ++k) {
  86. let f: f32 = math_abs(posa32[k]);
  87. if (scale_pos < f) {
  88. scale_pos = f;
  89. }
  90. }
  91. let inv: f32 = 32767 * (1 / scale_pos);
  92. let posa: i16_array_t = i16_array_create(posa0.length + posa1.length);
  93. for (let k: i32 = 0; k < math_floor(posa.length / 4); ++k) {
  94. posa[k * 4 ] = math_floor(posa32[k * 3 ] * inv);
  95. posa[k * 4 + 1] = math_floor(posa32[k * 3 + 1] * inv);
  96. posa[k * 4 + 2] = math_floor(posa32[k * 3 + 2] * inv);
  97. }
  98. for (let k: i32 = 0; k < math_floor(posa0.length / 4); ++k) {
  99. posa[k * 4 + 3] = posa0[k * 4 + 3];
  100. }
  101. for (let k: i32 = 0; k < math_floor(posa1.length / 4); ++k) {
  102. posa[posa0.length + k * 4 + 3] = posa1[k * 4 + 3];
  103. }
  104. // Merge normals and uvs
  105. let nora: i16_array_t = i16_array_create(nora0.length + nora1.length);
  106. let texa: i16_array_t = (texa0 != null && texa1 != null) ? i16_array_create(texa0.length + texa1.length) : null;
  107. let inda: u32_array_t = u32_array_create(inda0.length + inda1.length);
  108. for (let k: i32 = 0; k < nora0.length; ++k) {
  109. nora[k] = nora0[k];
  110. }
  111. for (let k: i32 = 0; k < nora1.length; ++k) {
  112. nora[k + nora0.length] = nora1[k];
  113. }
  114. if (texa != null) {
  115. for (let k: i32 = 0; k < texa0.length; ++k) {
  116. texa[k] = texa0[k];
  117. }
  118. for (let k: i32 = 0; k < texa1.length; ++k) {
  119. texa[k + texa0.length] = texa1[k];
  120. }
  121. }
  122. for (let k: i32 = 0; k < inda0.length; ++k) {
  123. inda[k] = inda0[k];
  124. }
  125. for (let k: i32 = 0; k < inda1.length; ++k) {
  126. inda[k + inda0.length] = inda1[k] + voff;
  127. }
  128. parts[i].posa = posa;
  129. parts[i].nora = nora;
  130. parts[i].texa = texa;
  131. parts[i].inda = inda;
  132. parts[i].scale_pos = scale_pos;
  133. array_splice(parts, j, 1);
  134. }
  135. else {
  136. j++;
  137. }
  138. }
  139. }
  140. }
  141. replace_existing ? import_mesh_make_mesh(parts[0]) : import_mesh_add_mesh(parts[0]);
  142. for (let i: i32 = 1; i < parts.length; ++i) {
  143. import_mesh_add_mesh(parts[i]);
  144. }
  145. }
  146. data_delete_blob(path);
  147. }