|
|
|
|
@ -8,54 +8,20 @@
|
|
|
|
|
#include "asset.h" |
|
|
|
|
#include "dumbLog.h" |
|
|
|
|
|
|
|
|
|
const char* |
|
|
|
|
getTargetStr(int target) |
|
|
|
|
{ |
|
|
|
|
switch (target) { |
|
|
|
|
case 34962: return "GL_ARRAY_BUFFER"; |
|
|
|
|
case 34963: return "GL_ELEMENT_ARRAY_BUFFER"; |
|
|
|
|
default: return "UNKNOWN"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char* |
|
|
|
|
getElementType(int type) |
|
|
|
|
{ |
|
|
|
|
switch (type) { |
|
|
|
|
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"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// forward declarations
|
|
|
|
|
void dumpNodes(tinygltf::Model t_mdl); |
|
|
|
|
model* initModel(model_assets* assets, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
tinygltf::Model t_mdl, |
|
|
|
|
const char* filename); |
|
|
|
|
bool parseMeshNode(mesh& m, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
const tinygltf::Node& node, |
|
|
|
|
const tinygltf::Model& t_mdl); |
|
|
|
|
|
|
|
|
|
const char* |
|
|
|
|
getComponentType(int componentType) |
|
|
|
|
{ |
|
|
|
|
switch (componentType) { |
|
|
|
|
case 5123: return "TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT"; |
|
|
|
|
case 5124: return "TINYGLTF_COMPONENT_TYPE_INT"; |
|
|
|
|
case 5125: return "TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT"; |
|
|
|
|
case 5126: return "TINYGLTF_COMPONENT_TYPE_FLOAT"; |
|
|
|
|
case 5130: return "TINYGLTF_COMPONENT_TYPE_DOUBLE"; |
|
|
|
|
default: return "UNKOWN"; } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char* |
|
|
|
|
getDrawMode(int drawMode) |
|
|
|
|
{ |
|
|
|
|
switch (drawMode) { |
|
|
|
|
case 0: return "TINYGLTF_MODE_POINTS"; |
|
|
|
|
case 1: return "TINYGLTF_MODE_LINE"; |
|
|
|
|
case 2: return "TINYGLTF_MODE_LINE_LOOP"; |
|
|
|
|
case 3: return "TINYGLTF_MODE_LINE_STRIP"; |
|
|
|
|
case 4: return "TINYGLTF_MODE_TRIANGLES"; |
|
|
|
|
case 5: return "TINYGLTF_MODE_TRIANGLE_STRIP"; |
|
|
|
|
case 6: return "TINYGLTF_MODE_TRIANGLE_FAN"; |
|
|
|
|
default: return "UNKOWN MODE"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// interface
|
|
|
|
|
|
|
|
|
|
model_assets* |
|
|
|
|
assetInitBlock(memory_arena* arena, uint asset_count) |
|
|
|
|
@ -69,26 +35,60 @@ assetInitBlock(memory_arena* arena, uint asset_count)
|
|
|
|
|
return assets; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
dumpBuffer(tinygltf::Model model, tinygltf::Accessor acc) |
|
|
|
|
model* |
|
|
|
|
assetLoadFromFile(model_assets* assets, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
const char* filename) |
|
|
|
|
{ |
|
|
|
|
size_t bv_idx = acc.bufferView; |
|
|
|
|
assert(bv_idx >= 0 && bv_idx < model.bufferViews.size()); |
|
|
|
|
tinygltf::BufferView bv = model.bufferViews[bv_idx]; |
|
|
|
|
tinygltf::Model t_mdl; |
|
|
|
|
tinygltf::TinyGLTF gltf_ctx; |
|
|
|
|
std::string err; |
|
|
|
|
std::string warn; |
|
|
|
|
|
|
|
|
|
LOG(Debug) << "-----------------------\n"; |
|
|
|
|
LOG(Debug) << "buf idx: " << bv_idx << "\n"; |
|
|
|
|
LOG(Debug) << "buf target: " << getTargetStr(bv.target) << "\n"; |
|
|
|
|
LOG(Debug) << "buf len: " << bv.byteLength << "\n"; |
|
|
|
|
LOG(Debug) << "buf offset: " << bv.byteOffset << "\n"; |
|
|
|
|
LOG(Debug) << "buf stride: " << bv.byteStride << "\n"; |
|
|
|
|
LOG(Debug) << "acc component type: " |
|
|
|
|
<< getComponentType(acc.componentType) << "\n"; |
|
|
|
|
LOG(Debug) << "acc element type: " |
|
|
|
|
<< getElementType(acc.type) << "\n"; |
|
|
|
|
LOG(Info) << "Loading model: " << filename << "\n"; |
|
|
|
|
|
|
|
|
|
if (!gltf_ctx.LoadASCIIFromFile(&t_mdl, &err, &warn, filename)) { |
|
|
|
|
LOG(Error) << "Error loading file: " << filename |
|
|
|
|
<< " , msg: " << err << "\n"; |
|
|
|
|
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); |
|
|
|
|
// FIXME: also need to dump textures/materials
|
|
|
|
|
#if 0 |
|
|
|
|
dumpNodes(t_mdl); |
|
|
|
|
#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)) { |
|
|
|
|
LOG(Error) << "Error parsing node\n"; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return mdl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
model* |
|
|
|
|
assetGetCached(model_assets* assets, uint64_t path_hash) |
|
|
|
|
{ |
|
|
|
|
for (uint i = 0; i < assets->count; i++) { |
|
|
|
|
if (assets->models[i].filepath_hash == path_hash) |
|
|
|
|
return &assets->models[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LOG(Debug) << "asset not cached: " << path_hash << "\n"; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// internal
|
|
|
|
|
|
|
|
|
|
model* |
|
|
|
|
initModel(model_assets* assets, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
@ -112,35 +112,6 @@ initModel(model_assets* assets,
|
|
|
|
|
return mdl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
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) { |
|
|
|
|
tinygltf::Mesh t_mesh = t_mdl.meshes[node.mesh]; |
|
|
|
|
LOG(Debug) << "node mesh name: " << t_mesh.name << "\n"; |
|
|
|
|
// NOTE: assume only 1 primitive object per mesh
|
|
|
|
|
assert(t_mdl.meshes[node.mesh].primitives.size() == 1); |
|
|
|
|
tinygltf::Primitive prim = t_mesh.primitives[0]; |
|
|
|
|
LOG(Debug) << "node draw mode: " << getDrawMode(prim.mode) << "\n"; |
|
|
|
|
|
|
|
|
|
for (auto& att : prim.attributes) { |
|
|
|
|
LOG(Debug) << "dumping buffer: " << att.first << "\n"; |
|
|
|
|
dumpBuffer(t_mdl, t_mdl.accessors[att.second]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LOG(Debug) << "dumping index buffer\n"; |
|
|
|
|
dumpBuffer(t_mdl, t_mdl.accessors[prim.indices]); |
|
|
|
|
} else { |
|
|
|
|
LOG(Debug) << "Not a mesh node\n"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
copyBuffer(uint8_t*& buffer_ref, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
@ -170,6 +141,7 @@ copyBuffer(uint8_t*& buffer_ref,
|
|
|
|
|
return buffer_ref != nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// FIXME: need to implement tree structure for blender models to work properly
|
|
|
|
|
glm::mat4* |
|
|
|
|
parseNodeTransform(memory_arena* arena, const tinygltf::Node* node) |
|
|
|
|
{ |
|
|
|
|
@ -251,54 +223,101 @@ parseMeshNode(mesh& m,
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
model* |
|
|
|
|
assetLoadFromFile(model_assets* assets, |
|
|
|
|
memory_arena* arena, |
|
|
|
|
const char* filename) |
|
|
|
|
const char* |
|
|
|
|
getTargetStr(int target) |
|
|
|
|
{ |
|
|
|
|
tinygltf::Model t_mdl; |
|
|
|
|
tinygltf::TinyGLTF gltf_ctx; |
|
|
|
|
std::string err; |
|
|
|
|
std::string warn; |
|
|
|
|
switch (target) { |
|
|
|
|
case 34962: return "GL_ARRAY_BUFFER"; |
|
|
|
|
case 34963: return "GL_ELEMENT_ARRAY_BUFFER"; |
|
|
|
|
default: return "UNKNOWN"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LOG(Info) << "Loading model: " << filename << "\n"; |
|
|
|
|
const char* |
|
|
|
|
getElementType(int type) |
|
|
|
|
{ |
|
|
|
|
switch (type) { |
|
|
|
|
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"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!gltf_ctx.LoadASCIIFromFile(&t_mdl, &err, &warn, filename)) { |
|
|
|
|
LOG(Error) << "Error loading file: " << filename |
|
|
|
|
<< " , msg: " << err << "\n"; |
|
|
|
|
return nullptr; |
|
|
|
|
const char* |
|
|
|
|
getComponentType(int componentType) |
|
|
|
|
{ |
|
|
|
|
switch (componentType) { |
|
|
|
|
case 5123: return "TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT"; |
|
|
|
|
case 5124: return "TINYGLTF_COMPONENT_TYPE_INT"; |
|
|
|
|
case 5125: return "TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT"; |
|
|
|
|
case 5126: return "TINYGLTF_COMPONENT_TYPE_FLOAT"; |
|
|
|
|
case 5130: return "TINYGLTF_COMPONENT_TYPE_DOUBLE"; |
|
|
|
|
default: return "UNKOWN"; } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char* |
|
|
|
|
getDrawMode(int drawMode) |
|
|
|
|
{ |
|
|
|
|
switch (drawMode) { |
|
|
|
|
case 0: return "TINYGLTF_MODE_POINTS"; |
|
|
|
|
case 1: return "TINYGLTF_MODE_LINE"; |
|
|
|
|
case 2: return "TINYGLTF_MODE_LINE_LOOP"; |
|
|
|
|
case 3: return "TINYGLTF_MODE_LINE_STRIP"; |
|
|
|
|
case 4: return "TINYGLTF_MODE_TRIANGLES"; |
|
|
|
|
case 5: return "TINYGLTF_MODE_TRIANGLE_STRIP"; |
|
|
|
|
case 6: return "TINYGLTF_MODE_TRIANGLE_FAN"; |
|
|
|
|
default: return "UNKOWN MODE"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 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 get each node xform
|
|
|
|
|
// FIXME: also need to dump textures/materials
|
|
|
|
|
//dumpNodes(t_mdl);
|
|
|
|
|
void |
|
|
|
|
dumpBuffer(tinygltf::Model model, tinygltf::Accessor acc) |
|
|
|
|
{ |
|
|
|
|
size_t bv_idx = acc.bufferView; |
|
|
|
|
assert(bv_idx >= 0 && bv_idx < model.bufferViews.size()); |
|
|
|
|
tinygltf::BufferView bv = model.bufferViews[bv_idx]; |
|
|
|
|
|
|
|
|
|
uint mesh_idx = 0; |
|
|
|
|
LOG(Debug) << "-----------------------\n"; |
|
|
|
|
LOG(Debug) << "buf idx: " << bv_idx << "\n"; |
|
|
|
|
LOG(Debug) << "buf target: " << getTargetStr(bv.target) << "\n"; |
|
|
|
|
LOG(Debug) << "buf len: " << bv.byteLength << "\n"; |
|
|
|
|
LOG(Debug) << "buf offset: " << bv.byteOffset << "\n"; |
|
|
|
|
LOG(Debug) << "buf stride: " << bv.byteStride << "\n"; |
|
|
|
|
LOG(Debug) << "acc component type: " |
|
|
|
|
<< getComponentType(acc.componentType) << "\n"; |
|
|
|
|
LOG(Debug) << "acc element type: " |
|
|
|
|
<< getElementType(acc.type) << "\n"; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
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) { |
|
|
|
|
if (!parseMeshNode(mdl->meshes[mesh_idx++], arena, node, t_mdl)) { |
|
|
|
|
LOG(Error) << "Error parsing node\n"; |
|
|
|
|
return nullptr; |
|
|
|
|
tinygltf::Mesh t_mesh = t_mdl.meshes[node.mesh]; |
|
|
|
|
LOG(Debug) << "node mesh name: " << t_mesh.name << "\n"; |
|
|
|
|
// NOTE: assume only 1 primitive object per mesh
|
|
|
|
|
assert(t_mdl.meshes[node.mesh].primitives.size() == 1); |
|
|
|
|
tinygltf::Primitive prim = t_mesh.primitives[0]; |
|
|
|
|
LOG(Debug) << "node draw mode: " << getDrawMode(prim.mode) << "\n"; |
|
|
|
|
|
|
|
|
|
for (auto& att : prim.attributes) { |
|
|
|
|
LOG(Debug) << "dumping buffer: " << att.first << "\n"; |
|
|
|
|
dumpBuffer(t_mdl, t_mdl.accessors[att.second]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LOG(Debug) << "dumping index buffer\n"; |
|
|
|
|
dumpBuffer(t_mdl, t_mdl.accessors[prim.indices]); |
|
|
|
|
} else { |
|
|
|
|
LOG(Debug) << "Not a mesh node\n"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return mdl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// FIXME: reorganize asset.cpp, put interface at the top
|
|
|
|
|
model* |
|
|
|
|
assetGetCached(model_assets* assets, uint64_t path_hash) |
|
|
|
|
{ |
|
|
|
|
for (uint i = 0; i < assets->count; i++) { |
|
|
|
|
if (assets->models[i].filepath_hash == path_hash) |
|
|
|
|
return &assets->models[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
LOG(Debug) << "asset not cached: " << path_hash << "\n"; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|