2024-04-12 12:51:07 +02:00
|
|
|
#include <stdint.h>
|
2023-02-08 17:15:19 +01:00
|
|
|
#include <math.h>
|
2024-08-24 11:17:02 +02:00
|
|
|
#include "tinyusdz/tinyusdz.hh"
|
2024-09-03 15:52:05 +02:00
|
|
|
#include "iron_obj.h"
|
2024-08-24 11:17:02 +02:00
|
|
|
#include "iron_array.h"
|
2023-02-08 17:15:19 +01:00
|
|
|
|
2024-08-24 11:17:02 +02:00
|
|
|
extern "C" void *io_usd_parse(uint8_t *buf, size_t size) {
|
2023-02-08 17:15:19 +01:00
|
|
|
tinyusdz::Scene scene;
|
|
|
|
|
std::string warn;
|
|
|
|
|
std::string err;
|
|
|
|
|
tinyusdz::LoadUSDCFromMemory(buf, size, &scene, &warn, &err);
|
|
|
|
|
tinyusdz::GeomMesh mesh = scene.geom_meshes[0];
|
|
|
|
|
|
|
|
|
|
std::vector<float> vertices = mesh.points.buffer.GetAsVec3fArray();
|
|
|
|
|
std::vector<uint32_t> dst_facevarying_indices;
|
|
|
|
|
std::vector<float> dst_facevarying_normals;
|
|
|
|
|
std::vector<float> dst_facevarying_texcoords;
|
|
|
|
|
|
|
|
|
|
std::vector<float> facevarying_normals;
|
|
|
|
|
mesh.GetFacevaryingNormals(&facevarying_normals);
|
|
|
|
|
std::vector<float> facevarying_texcoords;
|
|
|
|
|
mesh.GetFacevaryingTexcoords(&facevarying_texcoords);
|
|
|
|
|
|
|
|
|
|
// Make facevarying indices
|
|
|
|
|
size_t face_offset = 0;
|
|
|
|
|
for (size_t fid = 0; fid < mesh.faceVertexCounts.size(); fid++) {
|
|
|
|
|
int f_count = mesh.faceVertexCounts[fid];
|
|
|
|
|
if (f_count == 3) {
|
|
|
|
|
for (size_t f = 0; f < f_count; f++) {
|
|
|
|
|
dst_facevarying_indices.push_back(mesh.faceVertexIndices[face_offset + f]);
|
|
|
|
|
if (facevarying_normals.size()) {
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * (face_offset + f) + 0]);
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * (face_offset + f) + 1]);
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * (face_offset + f) + 2]);
|
|
|
|
|
}
|
|
|
|
|
if (facevarying_texcoords.size()) {
|
|
|
|
|
dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * (face_offset + f) + 0]);
|
|
|
|
|
dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * (face_offset + f) + 1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// Simple triangulation with triangle-fan decomposition
|
|
|
|
|
for (size_t f = 0; f < f_count - 2; f++) {
|
|
|
|
|
size_t f0 = 0;
|
|
|
|
|
size_t f1 = f + 1;
|
|
|
|
|
size_t f2 = f + 2;
|
|
|
|
|
size_t fid0 = face_offset + f0;
|
|
|
|
|
size_t fid1 = face_offset + f1;
|
|
|
|
|
size_t fid2 = face_offset + f2;
|
|
|
|
|
dst_facevarying_indices.push_back(mesh.faceVertexIndices[fid0]);
|
|
|
|
|
dst_facevarying_indices.push_back(mesh.faceVertexIndices[fid1]);
|
|
|
|
|
dst_facevarying_indices.push_back(mesh.faceVertexIndices[fid2]);
|
|
|
|
|
if (facevarying_normals.size()) {
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid0 + 0]);
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid0 + 1]);
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid0 + 2]);
|
|
|
|
|
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid1 + 0]);
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid1 + 1]);
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid1 + 2]);
|
|
|
|
|
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid2 + 0]);
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid2 + 1]);
|
|
|
|
|
dst_facevarying_normals.push_back(facevarying_normals[3 * fid2 + 2]);
|
|
|
|
|
}
|
|
|
|
|
if (facevarying_texcoords.size()) {
|
|
|
|
|
size_t fid0 = face_offset + f0;
|
|
|
|
|
size_t fid1 = face_offset + f1;
|
|
|
|
|
size_t fid2 = face_offset + f2;
|
|
|
|
|
|
|
|
|
|
dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid0 + 0]);
|
|
|
|
|
dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid0 + 1]);
|
|
|
|
|
|
|
|
|
|
dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid1 + 0]);
|
|
|
|
|
dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid1 + 1]);
|
|
|
|
|
|
|
|
|
|
dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid2 + 0]);
|
|
|
|
|
dst_facevarying_texcoords.push_back(facevarying_texcoords[2 * fid2 + 1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
face_offset += f_count;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-24 11:17:02 +02:00
|
|
|
int vertex_count = dst_facevarying_indices.size();
|
|
|
|
|
int index_count = dst_facevarying_indices.size();
|
2023-02-08 17:15:19 +01:00
|
|
|
|
|
|
|
|
// Pack positions to (-1, 1) range
|
|
|
|
|
float hx = 0.0;
|
|
|
|
|
float hy = 0.0;
|
|
|
|
|
float hz = 0.0;
|
|
|
|
|
for (int i = 0; i < vertices.size() / 3; ++i) {
|
|
|
|
|
float f = fabsf(vertices[i * 3]);
|
|
|
|
|
if (hx < f) hx = f;
|
|
|
|
|
f = fabsf(vertices[i * 3 + 1]);
|
|
|
|
|
if (hy < f) hy = f;
|
|
|
|
|
f = fabsf(vertices[i * 3 + 2]);
|
|
|
|
|
if (hz < f) hz = f;
|
|
|
|
|
}
|
2024-08-24 11:17:02 +02:00
|
|
|
float scale_pos = fmax(hx, fmax(hy, hz));
|
2023-02-08 17:15:19 +01:00
|
|
|
float inv = 1 / scale_pos;
|
|
|
|
|
|
|
|
|
|
// Pack into 16bit
|
2024-08-24 11:17:02 +02:00
|
|
|
uint32_t *inda = (uint32_t *)malloc(sizeof(uint32_t) * index_count);
|
2023-02-08 17:15:19 +01:00
|
|
|
for (int i = 0; i < index_count; ++i) {
|
|
|
|
|
inda[i] = i;
|
|
|
|
|
}
|
2024-08-24 11:17:02 +02:00
|
|
|
int16_t *posa = (int16_t *)malloc(sizeof(int16_t) * vertex_count * 4);
|
|
|
|
|
int16_t *nora = (int16_t *)malloc(sizeof(int16_t) * vertex_count * 2);
|
|
|
|
|
int16_t *texa = (int16_t *)malloc(sizeof(int16_t) * vertex_count * 2);
|
2023-02-08 17:15:19 +01:00
|
|
|
|
|
|
|
|
for (int i = 0; i < vertex_count; ++i) {
|
|
|
|
|
posa[i * 4 ] = vertices[dst_facevarying_indices[i] * 3 ] * 32767 * inv;
|
|
|
|
|
posa[i * 4 + 1] = vertices[dst_facevarying_indices[i] * 3 + 1] * 32767 * inv;
|
|
|
|
|
posa[i * 4 + 2] = vertices[dst_facevarying_indices[i] * 3 + 2] * 32767 * inv;
|
|
|
|
|
posa[i * 4 + 3] = dst_facevarying_normals[i * 3 + 2] * 32767;
|
|
|
|
|
nora[i * 2 ] = dst_facevarying_normals[i * 3 ] * 32767;
|
|
|
|
|
nora[i * 2 + 1] = dst_facevarying_normals[i * 3 + 1] * 32767;
|
|
|
|
|
texa[i * 2 ] = dst_facevarying_texcoords[i * 2 ] * 32767;
|
|
|
|
|
texa[i * 2 + 1] = (1.0 - dst_facevarying_texcoords[i * 2 + 1]) * 32767;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-24 11:17:02 +02:00
|
|
|
raw_mesh_t *raw = (raw_mesh_t *)calloc(sizeof(raw_mesh_t), 1);
|
2023-02-08 17:15:19 +01:00
|
|
|
|
2024-08-24 11:17:02 +02:00
|
|
|
raw->name = (char *)malloc(mesh.name.length() + 1);
|
|
|
|
|
strcpy(raw->name, mesh.name.c_str());
|
|
|
|
|
|
|
|
|
|
raw->posa = (i16_array_t *)malloc(sizeof(i16_array_t));
|
|
|
|
|
raw->posa->buffer = posa;
|
|
|
|
|
raw->posa->length = raw->posa->capacity = vertex_count * 4;
|
|
|
|
|
|
|
|
|
|
raw->nora = (i16_array_t *)malloc(sizeof(i16_array_t));
|
|
|
|
|
raw->nora->buffer = nora;
|
|
|
|
|
raw->nora->length = raw->nora->capacity = vertex_count * 2;
|
|
|
|
|
|
|
|
|
|
raw->texa = (i16_array_t *)malloc(sizeof(i16_array_t));
|
|
|
|
|
raw->texa->buffer = texa;
|
|
|
|
|
raw->texa->length = raw->texa->capacity = vertex_count * 2;
|
|
|
|
|
|
|
|
|
|
raw->inda = (u32_array_t *)malloc(sizeof(u32_array_t));
|
|
|
|
|
raw->inda->buffer = inda;
|
|
|
|
|
raw->inda->length = raw->inda->capacity = vertex_count * 2;
|
|
|
|
|
|
|
|
|
|
raw->scale_pos = scale_pos;
|
|
|
|
|
raw->scale_tex = 1.0;
|
|
|
|
|
|
|
|
|
|
return raw;
|
|
|
|
|
}
|