|
|
|
|
@ -15,7 +15,8 @@ model* initModel(model_assets* assets,
|
|
|
|
|
memory_arena* arena, |
|
|
|
|
tinygltf::Model t_mdl, |
|
|
|
|
const char* filename); |
|
|
|
|
bool parseMeshNode(mesh& m, |
|
|
|
|
bool parseMeshNode(mesh* m, |
|
|
|
|
texture_assets* textures, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
const tinygltf::Node& node, |
|
|
|
|
const tinygltf::Model& t_mdl); |
|
|
|
|
@ -24,7 +25,7 @@ bool parseMeshNode(mesh& m,
|
|
|
|
|
// interface
|
|
|
|
|
|
|
|
|
|
model_assets* |
|
|
|
|
assetInitBlock(memory_arena* arena, uint asset_count) |
|
|
|
|
assetInitModelBlock(memory_arena* arena, uint asset_count) |
|
|
|
|
{ |
|
|
|
|
model_assets* assets = |
|
|
|
|
(model_assets*) arenaAllocateBlock(arena, sizeof(model_assets)); |
|
|
|
|
@ -35,8 +36,52 @@ assetInitBlock(memory_arena* arena, uint asset_count)
|
|
|
|
|
return assets; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
texture_assets* |
|
|
|
|
assetInitTextureBlock(memory_arena* arena, uint asset_count) |
|
|
|
|
{ |
|
|
|
|
texture_assets* assets = |
|
|
|
|
(texture_assets*) arenaAllocateBlock(arena, sizeof(texture_assets)); |
|
|
|
|
assets->images = (util_image*) arenaAllocateBlock( |
|
|
|
|
arena, asset_count * sizeof(util_image)); |
|
|
|
|
assets->max = asset_count; |
|
|
|
|
|
|
|
|
|
return assets; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// FIXME: move to internal when finished
|
|
|
|
|
util_image* |
|
|
|
|
copyDiffuseTexture(texture_assets* textures, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
const tinygltf::Model& t_mdl) |
|
|
|
|
{ |
|
|
|
|
// NOTE: assuming material[0] since we're using pallete texture
|
|
|
|
|
assert(t_mdl.materials.size() == 1 |
|
|
|
|
&& t_mdl.textures.size() == 1 |
|
|
|
|
&& t_mdl.images.size() == 1 |
|
|
|
|
&& t_mdl.images[0].image.size() > 0); |
|
|
|
|
tinygltf::Image t_img = t_mdl.images[0]; |
|
|
|
|
|
|
|
|
|
// TODO: re-alloc array when out of space
|
|
|
|
|
assert(textures->count < textures->max && arena != nullptr); |
|
|
|
|
util_image* dtex = &textures->images[textures->count]; |
|
|
|
|
textures->count++; |
|
|
|
|
|
|
|
|
|
dtex->w = t_img.width; |
|
|
|
|
dtex->h = t_img.height; |
|
|
|
|
dtex->bits_per_channel = t_img.bits; |
|
|
|
|
dtex->num_channels = t_img.component; |
|
|
|
|
dtex->data_len = t_img.image.size(); |
|
|
|
|
dtex->pixels = (uint8*) arenaAllocateBlock(arena, dtex->data_len); |
|
|
|
|
std::strncpy(dtex->file_path, t_img.uri.c_str(), t_img.uri.size()); |
|
|
|
|
dtex->filepath_hash = utilFNV64a_str(t_img.uri.c_str()); |
|
|
|
|
std::memcpy(dtex->pixels, t_img.image.data(), dtex->data_len); |
|
|
|
|
|
|
|
|
|
return dtex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
model* |
|
|
|
|
assetLoadFromFile(model_assets* assets, |
|
|
|
|
texture_assets* textures, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
const char* filename) |
|
|
|
|
{ |
|
|
|
|
@ -52,19 +97,28 @@ assetLoadFromFile(model_assets* assets,
|
|
|
|
|
<< " , msg: " << err << "\n"; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
dumpNodes(t_mdl); |
|
|
|
|
#endif |
|
|
|
|
// NOTE: assume we're working with a single buffer
|
|
|
|
|
assert(t_mdl.buffers.size() == 1); |
|
|
|
|
model* mdl = initModel(assets, arena, t_mdl, filename); |
|
|
|
|
// FIXME: also need to dump textures/materials
|
|
|
|
|
#if 0 |
|
|
|
|
dumpNodes(t_mdl); |
|
|
|
|
mdl->diffuse_texture = copyDiffuseTexture(textures, arena, t_mdl); |
|
|
|
|
#if 1 |
|
|
|
|
if (mdl->diffuse_texture == nullptr) { |
|
|
|
|
LOG(Error) << "Error Loading diffuse texture\n"; |
|
|
|
|
// TODO: reclaim arena memory
|
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
uint mesh_idx = 0; |
|
|
|
|
|
|
|
|
|
for (tinygltf::Node node : t_mdl.nodes) { |
|
|
|
|
if (node.mesh >= 0) { |
|
|
|
|
if (!parseMeshNode(mdl->meshes[mesh_idx++], arena, node, t_mdl)) { |
|
|
|
|
if (!parseMeshNode(&mdl->meshes[mesh_idx++], |
|
|
|
|
textures, arena, node, t_mdl)) |
|
|
|
|
{ |
|
|
|
|
LOG(Error) << "Error parsing node\n"; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
@ -122,6 +176,7 @@ copyBuffer(uint8_t*& buffer_ref,
|
|
|
|
|
const tinygltf::BufferView& bv = t_mdl.bufferViews[acc.bufferView]; |
|
|
|
|
const tinygltf::Buffer& t_buf = t_mdl.buffers[bv.buffer]; |
|
|
|
|
|
|
|
|
|
// TODO: clean up validation
|
|
|
|
|
if (bv.target == TINYGLTF_TARGET_ARRAY_BUFFER) { |
|
|
|
|
assert(acc.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT |
|
|
|
|
&& (acc.type == TINYGLTF_TYPE_VEC3 |
|
|
|
|
@ -176,7 +231,8 @@ parseNodeTransform(memory_arena* arena, const tinygltf::Node* node)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
parseMeshNode(mesh& m, |
|
|
|
|
parseMeshNode(mesh* m, |
|
|
|
|
texture_assets* textures, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
const tinygltf::Node& node, |
|
|
|
|
const tinygltf::Model& t_mdl) |
|
|
|
|
@ -195,26 +251,26 @@ parseMeshNode(mesh& m,
|
|
|
|
|
const tinygltf::Accessor& vert_acc = |
|
|
|
|
t_mdl.accessors[prim.attributes["POSITION"]]; |
|
|
|
|
const tinygltf::Accessor& index_acc = t_mdl.accessors[prim.indices]; |
|
|
|
|
m.num_vertices = vert_acc.count; |
|
|
|
|
m.num_indices = index_acc.count; |
|
|
|
|
m.draw_mode = prim.mode; |
|
|
|
|
m.usage = GL_STATIC_DRAW; // TODO: logic for updating dynamic meshes
|
|
|
|
|
m->num_vertices = vert_acc.count; |
|
|
|
|
m->num_indices = index_acc.count; |
|
|
|
|
m->draw_mode = prim.mode; |
|
|
|
|
m->usage = GL_STATIC_DRAW; // TODO: logic for updating dynamic meshes
|
|
|
|
|
// FIXME: the node transforms from blender only work as part of a node tree
|
|
|
|
|
#if 1 |
|
|
|
|
m.xform = (glm::mat4*) arenaAllocateBlock(arena, sizeof(glm::mat4)); |
|
|
|
|
*m.xform = glm::mat4(1.0f); |
|
|
|
|
m->xform = (glm::mat4*) arenaAllocateBlock(arena, sizeof(glm::mat4)); |
|
|
|
|
*m->xform = glm::mat4(1.0f); |
|
|
|
|
#else |
|
|
|
|
m.xform = parseNodeTransform(arena, &node); |
|
|
|
|
m->xform = parseNodeTransform(arena, &node); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (m.xform != nullptr |
|
|
|
|
&& copyBuffer((uint8_t*&) m.vertices, arena, |
|
|
|
|
if (m->xform != nullptr |
|
|
|
|
&& copyBuffer((uint8_t*&) m->vertices, arena, |
|
|
|
|
prim.attributes["POSITION"], t_mdl) |
|
|
|
|
&& copyBuffer((uint8_t*&) m.normals, arena, |
|
|
|
|
&& copyBuffer((uint8_t*&) m->normals, arena, |
|
|
|
|
prim.attributes["NORMAL"], t_mdl) |
|
|
|
|
&& copyBuffer((uint8_t*&) m.texture_coords, arena, |
|
|
|
|
&& copyBuffer((uint8_t*&) m->texture_coords, arena, |
|
|
|
|
prim.attributes["TEXCOORD_0"], t_mdl) |
|
|
|
|
&& copyBuffer((uint8_t*&) m.indices, arena, |
|
|
|
|
&& copyBuffer((uint8_t*&) m->indices, arena, |
|
|
|
|
prim.indices, t_mdl)) |
|
|
|
|
{ |
|
|
|
|
return true; |
|
|
|
|
|