aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp52
1 files changed, 42 insertions, 10 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 87260cb..6fcd2a3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,6 @@
#include <assert.h>
#include <stdio.h>
+#include <sys/stat.h>
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
@@ -10,7 +11,7 @@
static void usage();
static void file_write_error_check(FILE *file, const void *data, size_t size);
static void file_write_uint_error_check(FILE *file, unsigned int value);
-static void process_node(const aiScene *scene, const aiNode *node, FILE *output_file);
+static void process_node(const aiScene *scene, const aiNode *node, FILE *output_file, const std::string &source_dir);
int main(int argc, char **argv) {
if(argc != 3)
@@ -37,7 +38,10 @@ int main(int argc, char **argv) {
file_write_uint_error_check(destination_file, 0x036144AF); // magic number
file_write_uint_error_check(destination_file, 0x00000001); // version
- process_node(scene, scene->mRootNode, destination_file);
+ std::string source_dir = source_filepath;
+ source_dir = source_dir.substr(0, source_dir.find_last_of("/"));
+
+ process_node(scene, scene->mRootNode, destination_file, source_dir);
fclose(destination_file);
Assimp::DefaultLogger::kill();
return 0;
@@ -63,7 +67,12 @@ void file_write_uint_error_check(FILE *file, unsigned int value) {
}
}
-static void process_mesh(const aiScene *scene, const aiMesh *mesh, FILE *output_file) {
+static bool is_file(const char *filename) {
+ struct stat filestat;
+ return stat(filename, &filestat) == 0 && S_ISREG(filestat.st_mode);
+}
+
+static void process_mesh(const aiScene *scene, const aiMesh *mesh, FILE *output_file, const std::string &source_dir) {
// TODO: It seems like sometimes the vertice count doesn't match triangles.. excluding the last vertices in the list
unsigned int vertice_overflow = mesh->mNumVertices % 3;
unsigned int num_vertices = mesh->mNumVertices - vertice_overflow;
@@ -101,23 +110,46 @@ static void process_mesh(const aiScene *scene, const aiMesh *mesh, FILE *output_
unsigned int num_textures_for_type = material->GetTextureCount(texture_types[i]);
file_write_uint_error_check(output_file, num_textures_for_type);
for(unsigned int j = 0; j < num_textures_for_type; ++j) {
- aiString str;
- if(material->GetTexture(texture_types[i], j, &str) == aiReturn_SUCCESS)
- file_write_error_check(output_file, str.data, str.length + 1); // +1 to include null-terminate character
- else
+ aiString texture_name;
+ if(material->GetTexture(texture_types[i], j, &texture_name) == aiReturn_SUCCESS) {
+ std::string texture_path = source_dir + "/";
+ texture_path.append(texture_name.data, texture_name.length);
+ // This is needed because it's common for models to use a directory called textures or Textures
+ // and not specify it in the model file
+ if(!is_file(texture_path.c_str())) {
+ //fprintf(stderr, "Warning: texture not found: %s\n", texture_path.c_str());
+ texture_path = source_dir + "/Textures/";
+ texture_path.append(texture_name.data, texture_name.length);
+ if(!is_file(texture_path.c_str())) {
+ //fprintf(stderr, "Warning: texture not found: %s\n", texture_path.c_str());
+ texture_path = source_dir + "/textures/";
+ texture_path.append(texture_name.data, texture_name.length);
+ if(!is_file(texture_path.c_str())) {
+ fprintf(stderr, "Warning: texture not found: %s\n", texture_name.C_Str());
+ file_write_error_check(output_file, "\0", 1);
+ continue;
+ }
+ }
+ }
+
+ size_t dir_prefix_size = source_dir.size() + 1;
+ // +1 to include null-terminate character
+ file_write_error_check(output_file, texture_path.data() + dir_prefix_size, texture_path.size() + 1 - dir_prefix_size);
+ } else {
file_write_error_check(output_file, "\0", 1);
+ }
}
}
}
}
-void process_node(const aiScene *scene, const aiNode *node, FILE *output_file) {
+void process_node(const aiScene *scene, const aiNode *node, FILE *output_file, const std::string &source_dir) {
for(unsigned int i = 0; i < node->mNumMeshes; ++i) {
const aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
- process_mesh(scene, mesh, output_file);
+ process_mesh(scene, mesh, output_file, source_dir);
}
for(unsigned int i = 0; i < node->mNumChildren; ++i) {
- process_node(scene, node->mChildren[i], output_file);
+ process_node(scene, node->mChildren[i], output_file, source_dir);
}
} \ No newline at end of file