|
|
|
@ -10,26 +10,105 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// forward declarations
|
|
|
|
// forward declarations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: move to GLDebug.h?
|
|
|
|
void dumpNodes(tinygltf::Model t_mdl); |
|
|
|
void dumpNodes(tinygltf::Model t_mdl); |
|
|
|
model* initModel(Assets* assets, |
|
|
|
|
|
|
|
MemoryArena* arena, |
|
|
|
|
|
|
|
tinygltf::Model t_mdl, |
|
|
|
|
|
|
|
const char* filename); |
|
|
|
|
|
|
|
util_image* copyDiffuseTexture(Assets* assets, |
|
|
|
|
|
|
|
MemoryArena* arena, |
|
|
|
|
|
|
|
const tinygltf::Model& t_mdl); |
|
|
|
|
|
|
|
bool parseMeshNode(mesh* m, |
|
|
|
bool parseMeshNode(mesh* m, |
|
|
|
MemoryArena* arena, |
|
|
|
MemoryArena* arena, |
|
|
|
const tinygltf::Node& node, |
|
|
|
const tinygltf::Node& node, |
|
|
|
const tinygltf::Model& t_mdl); |
|
|
|
const tinygltf::Model& t_mdl); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
model* getCachedModel(Assets* assets, u64 path_hash); |
|
|
|
|
|
|
|
model* loadModelFile(Assets* assets, const char* filename); |
|
|
|
|
|
|
|
util_image* getCachedTexture(Assets* assets, u64 path_hash); |
|
|
|
|
|
|
|
util_image* loadTextureFile(Assets* assets, const char* filename); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// interface
|
|
|
|
// interface
|
|
|
|
|
|
|
|
|
|
|
|
model* |
|
|
|
model* |
|
|
|
assetLoadFromFile(Assets* assets, |
|
|
|
getModelByPath(Assets* assets, const char* filepath) |
|
|
|
MemoryArena* arena, |
|
|
|
{ |
|
|
|
|
|
|
|
model* mdl = getCachedModel(assets, utilFNV64a_str(filepath)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!mdl) |
|
|
|
|
|
|
|
mdl = loadModelFile(assets, filepath); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return mdl; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
util_image* |
|
|
|
|
|
|
|
getTextureByPath(Assets* assets, const char* filepath) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
util_image* texture = |
|
|
|
|
|
|
|
getCachedTexture(assets, utilFNV64a_str(filepath)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!texture) |
|
|
|
|
|
|
|
texture = loadTextureFile(assets, filepath); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return texture; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// internal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
model* |
|
|
|
|
|
|
|
initModel(Assets* assets, |
|
|
|
|
|
|
|
tinygltf::Model t_mdl, |
|
|
|
const char* filename) |
|
|
|
const char* filename) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// TODO: re-alloc array when out of space
|
|
|
|
|
|
|
|
assert(assets->num_models < assets->max_models && assets->arena != nullptr); |
|
|
|
|
|
|
|
model* mdl = &assets->models[assets->num_models]; |
|
|
|
|
|
|
|
assets->num_models++; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint buf_count = t_mdl.bufferViews.size(); |
|
|
|
|
|
|
|
mdl->meshes = ARENA_ALLOC(assets->arena, mesh, buf_count); |
|
|
|
|
|
|
|
mdl->num_meshes = t_mdl.meshes.size(); |
|
|
|
|
|
|
|
mdl->filepath = arenaCopyCStr(assets->arena, filename, MAX_PATH_SIZE); |
|
|
|
|
|
|
|
mdl->filepath_hash = utilFNV64a_str(mdl->filepath); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return mdl; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
util_image* |
|
|
|
|
|
|
|
getFreeTexture(Assets* assets) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (assets->num_textures < assets->max_textures) |
|
|
|
|
|
|
|
return &assets->textures[assets->num_textures++]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("%s(), no free textures\n", __FUNCTION__); |
|
|
|
|
|
|
|
return nullptr; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
util_image* |
|
|
|
|
|
|
|
copyDiffuseTexture(Assets* assets, 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]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
util_image* dtex = getFreeTexture(assets); |
|
|
|
|
|
|
|
if (!dtex) return nullptr; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 = ARENA_ALLOC(assets->arena, u8, dtex->data_len); |
|
|
|
|
|
|
|
std::strncpy(dtex->file_path, t_img.uri.c_str(), sizeof(dtex->file_path)); |
|
|
|
|
|
|
|
dtex->filepath_hash = utilFNV64a_str(t_img.uri.c_str()); |
|
|
|
|
|
|
|
std::memcpy(dtex->pixels, t_img.image.data(), dtex->data_len); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return dtex; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
model* |
|
|
|
|
|
|
|
loadModelFile(Assets* assets, const char* filename) |
|
|
|
{ |
|
|
|
{ |
|
|
|
tinygltf::Model t_mdl; |
|
|
|
tinygltf::Model t_mdl; |
|
|
|
tinygltf::TinyGLTF gltf_ctx; |
|
|
|
tinygltf::TinyGLTF gltf_ctx; |
|
|
|
@ -48,8 +127,8 @@ assetLoadFromFile(Assets* assets, |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
// NOTE: assume we're working with a single buffer
|
|
|
|
// NOTE: assume we're working with a single buffer
|
|
|
|
assert(t_mdl.buffers.size() == 1); |
|
|
|
assert(t_mdl.buffers.size() == 1); |
|
|
|
model* mdl = initModel(assets, arena, t_mdl, filename); |
|
|
|
model* mdl = initModel(assets, t_mdl, filename); |
|
|
|
mdl->diffuse_texture = copyDiffuseTexture(assets, arena, t_mdl); |
|
|
|
mdl->diffuse_texture = copyDiffuseTexture(assets, t_mdl); |
|
|
|
|
|
|
|
|
|
|
|
if (mdl->diffuse_texture == nullptr) { |
|
|
|
if (mdl->diffuse_texture == nullptr) { |
|
|
|
LOG(Error) << "Error Loading diffuse texture\n"; |
|
|
|
LOG(Error) << "Error Loading diffuse texture\n"; |
|
|
|
@ -61,7 +140,11 @@ assetLoadFromFile(Assets* assets, |
|
|
|
|
|
|
|
|
|
|
|
for (tinygltf::Node node : t_mdl.nodes) { |
|
|
|
for (tinygltf::Node node : t_mdl.nodes) { |
|
|
|
if (node.mesh >= 0) { |
|
|
|
if (node.mesh >= 0) { |
|
|
|
if (!parseMeshNode(&mdl->meshes[mesh_idx++], arena, node, t_mdl)) { |
|
|
|
if (!parseMeshNode(&mdl->meshes[mesh_idx++], |
|
|
|
|
|
|
|
assets->arena, |
|
|
|
|
|
|
|
node, |
|
|
|
|
|
|
|
t_mdl)) |
|
|
|
|
|
|
|
{ |
|
|
|
LOG(Error) << "Error parsing node\n"; |
|
|
|
LOG(Error) << "Error parsing node\n"; |
|
|
|
return nullptr; |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -72,38 +155,33 @@ assetLoadFromFile(Assets* assets, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
model* |
|
|
|
model* |
|
|
|
assetGetCachedModel(Assets* assets, uint64_t path_hash) |
|
|
|
getCachedModel(Assets* assets, u64 path_hash) |
|
|
|
{ |
|
|
|
{ |
|
|
|
for (uint i = 0; i < assets->num_models; i++) { |
|
|
|
for (u32 i = 0; i < assets->num_models; i++) { |
|
|
|
if (assets->models[i].filepath_hash == path_hash) |
|
|
|
if (assets->models[i].filepath_hash == path_hash) |
|
|
|
return &assets->models[i]; |
|
|
|
return &assets->models[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LOG(Debug) << "asset not cached: " << path_hash << "\n"; |
|
|
|
LOG(Debug) << "asset not cached, hash: " << path_hash << "\n"; |
|
|
|
return nullptr; |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
util_image* |
|
|
|
// internal
|
|
|
|
loadTextureFile(Assets* assets, const char* filename) |
|
|
|
|
|
|
|
|
|
|
|
model* |
|
|
|
|
|
|
|
initModel(Assets* assets, |
|
|
|
|
|
|
|
MemoryArena* arena, |
|
|
|
|
|
|
|
tinygltf::Model t_mdl, |
|
|
|
|
|
|
|
const char* filename) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
// TODO: re-alloc array when out of space
|
|
|
|
return nullptr; |
|
|
|
assert(assets->num_models < assets->max_models && arena != nullptr); |
|
|
|
} |
|
|
|
model* mdl = &assets->models[assets->num_models]; |
|
|
|
|
|
|
|
assets->num_models++; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint buf_count = t_mdl.bufferViews.size(); |
|
|
|
util_image* |
|
|
|
mdl->meshes = ARENA_ALLOC(arena, mesh, buf_count); |
|
|
|
getCachedTexture(Assets* assets, u64 path_hash) |
|
|
|
mdl->num_meshes = t_mdl.meshes.size(); |
|
|
|
{ |
|
|
|
mdl->filepath = arenaCopyCStr(arena, filename, MAX_PATH_SIZE); |
|
|
|
for (u32 i = 0; i < assets->num_textures; i++) { |
|
|
|
mdl->filepath_hash = utilFNV64a_str(mdl->filepath); |
|
|
|
if (assets->textures[i].filepath_hash == path_hash) |
|
|
|
|
|
|
|
return &assets->textures[i]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return mdl; |
|
|
|
LOG(Debug) << "asset not cached, hash: " << path_hash << "\n"; |
|
|
|
|
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
bool |
|
|
|
@ -215,44 +293,6 @@ parseMeshNode(mesh* m, |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
util_image* |
|
|
|
|
|
|
|
getFreeTexture(Assets* assets) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (assets->num_textures < assets->max_textures) |
|
|
|
|
|
|
|
return &assets->textures[assets->num_textures++]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("%s(), no free textures\n", __FUNCTION__); |
|
|
|
|
|
|
|
return nullptr; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
util_image* |
|
|
|
|
|
|
|
copyDiffuseTexture(Assets* assets, |
|
|
|
|
|
|
|
MemoryArena* 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]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
util_image* dtex = getFreeTexture(assets); |
|
|
|
|
|
|
|
if (!dtex) return nullptr; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 = ARENA_ALLOC(arena, u8, dtex->data_len); |
|
|
|
|
|
|
|
std::strncpy(dtex->file_path, t_img.uri.c_str(), sizeof(dtex->file_path)); |
|
|
|
|
|
|
|
dtex->filepath_hash = utilFNV64a_str(t_img.uri.c_str()); |
|
|
|
|
|
|
|
std::memcpy(dtex->pixels, t_img.image.data(), dtex->data_len); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return dtex; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char* |
|
|
|
const char* |
|
|
|
getTargetStr(int target) |
|
|
|
getTargetStr(int target) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|