|
|
|
|
@ -21,9 +21,9 @@ const char*
|
|
|
|
|
getElementType(int type) |
|
|
|
|
{ |
|
|
|
|
switch (type) { |
|
|
|
|
case 2: return "VEC2"; |
|
|
|
|
case 3: return "VEC3"; |
|
|
|
|
case 4: return "VEC4"; |
|
|
|
|
case 2: return "TINYGLTF_TYPE_VEC2"; |
|
|
|
|
case 3: return "TINYGLTF_TYPE_VEC3"; |
|
|
|
|
case 4: return "TINYGLTF_TYPE_VEC4"; |
|
|
|
|
case 65: return "TINYGLTF_TYPE_SCALAR"; |
|
|
|
|
default: return "UNKNOWN"; |
|
|
|
|
} |
|
|
|
|
@ -118,6 +118,7 @@ dumpNodes(tinygltf::Model t_mdl)
|
|
|
|
|
{ |
|
|
|
|
for (tinygltf::Node node : t_mdl.nodes) { |
|
|
|
|
LOG(Debug) << "##################\n"; |
|
|
|
|
LOG(Debug) << "node name: " << node.name << "\n"; |
|
|
|
|
LOG(Debug) << "node mesh idx: " << node.mesh << "\n"; |
|
|
|
|
|
|
|
|
|
if (node.mesh >= 0) { |
|
|
|
|
@ -141,6 +142,70 @@ dumpNodes(tinygltf::Model t_mdl)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
copyBuffer(uint8_t*& buffer_ref, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
int acc_idx, |
|
|
|
|
const tinygltf::Model& t_mdl) |
|
|
|
|
{ |
|
|
|
|
const tinygltf::Accessor& acc = t_mdl.accessors[acc_idx]; |
|
|
|
|
const tinygltf::BufferView& bv = t_mdl.bufferViews[acc.bufferView]; |
|
|
|
|
const tinygltf::Buffer& t_buf = t_mdl.buffers[bv.buffer]; |
|
|
|
|
|
|
|
|
|
if (bv.target == TINYGLTF_TARGET_ARRAY_BUFFER) { |
|
|
|
|
assert(acc.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT |
|
|
|
|
&& (acc.type == TINYGLTF_TYPE_VEC3 |
|
|
|
|
|| acc.type == TINYGLTF_TYPE_VEC2)); |
|
|
|
|
} else if (bv.target == TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER) { |
|
|
|
|
assert(acc.type == TINYGLTF_TYPE_SCALAR |
|
|
|
|
&& acc.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT); |
|
|
|
|
} else { |
|
|
|
|
LOG(Error) << "unknown target\n"; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert(bv.byteStride == 0); |
|
|
|
|
buffer_ref = (uint8_t*) arenaAllocateBlock(arena, bv.byteLength); |
|
|
|
|
std::memcpy(buffer_ref, &t_buf.data[bv.byteOffset], bv.byteLength); |
|
|
|
|
|
|
|
|
|
return buffer_ref == nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
parseMeshNode(mesh& m, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
const tinygltf::Node& node, |
|
|
|
|
const tinygltf::Model& t_mdl) |
|
|
|
|
{ |
|
|
|
|
tinygltf::Mesh t_mesh = t_mdl.meshes[node.mesh]; |
|
|
|
|
// NOTE: assume only 1 primitive object per mesh
|
|
|
|
|
assert(t_mdl.meshes[node.mesh].primitives.size() == 1); |
|
|
|
|
tinygltf::Primitive prim = t_mesh.primitives[0]; |
|
|
|
|
|
|
|
|
|
// NOTE: verify assumptions about input
|
|
|
|
|
assert(prim.attributes.find("POSITION") != prim.attributes.end() |
|
|
|
|
&& prim.attributes.find("NORMAL") != prim.attributes.end() |
|
|
|
|
&& prim.attributes.find("TEXCOORD_0") != prim.attributes.end() |
|
|
|
|
&& prim.indices >= 0); |
|
|
|
|
|
|
|
|
|
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 meshes
|
|
|
|
|
m.xform = (glm::mat4*) arenaAllocateBlock(arena, sizeof(glm::mat4)); |
|
|
|
|
copyBuffer( |
|
|
|
|
(uint8_t*&) m.vertices, arena, prim.attributes["POSITION"], t_mdl); |
|
|
|
|
copyBuffer((uint8_t*&) m.normals, arena, prim.attributes["NORMAL"], t_mdl); |
|
|
|
|
copyBuffer((uint8_t*&) m.texture_coords, |
|
|
|
|
arena, prim.attributes["TEXCOORD_0"], t_mdl); |
|
|
|
|
copyBuffer((uint8_t*&) m.indices, arena, prim.indices, t_mdl); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
model* |
|
|
|
|
assetLoadFromFile(model_assets* assets, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
@ -157,11 +222,25 @@ assetLoadFromFile(model_assets* assets,
|
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// NOTE: assume we're working with a single buffer
|
|
|
|
|
assert(t_mdl.buffers.size() == 1); |
|
|
|
|
model* mdl = initModel(assets, arena, t_mdl, filename); |
|
|
|
|
// TODO: also need to get each node xform
|
|
|
|
|
// TODO: also need to dump textures/materials
|
|
|
|
|
dumpNodes(t_mdl); |
|
|
|
|
|
|
|
|
|
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)) { |
|
|
|
|
// FIXME: error handling
|
|
|
|
|
LOG(Error) << "Some mesh parsing error\n"; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return mdl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|