diff --git a/README.md b/README.md index d30af0c..1b0a516 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ if (!ret) { * `TINYGLTF_NO_STB_IMAGE` : Do not load images with stb_image. Instead use `TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)` to set a callback for loading images. * `TINYGLTF_NO_STB_IMAGE_WRITE` : Do not write images with stb_image_write. Instead use `TinyGLTF::SetImageWriter(WriteimageDataFunction WriteImageData, void *user_data)` to set a callback for writing images. * `TINYGLTF_NO_EXTERNAL_IMAGE` : Do not try to load external image file. This option woulde be helpful if you do not want load image file during glTF parsing. +* `TINYGLTF_ANDROID_LOAD_FROM_ASSETS`: Load all files from packaged app assets instead of the regular file system. **Note:** You must pass a valid asset manager from your android app to `tinygltf::asset_manager` beforehand. ### Saving gltTF 2.0 model * [ ] Buffers. diff --git a/tiny_gltf.h b/tiny_gltf.h index d70060b..ad32ee4 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -47,6 +47,12 @@ #include #include +#ifdef __ANDROID__ +#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS +#include +#endif +#endif + namespace tinygltf { #define TINYGLTF_MODE_POINTS (0) @@ -139,6 +145,12 @@ namespace tinygltf { #define TINYGLTF_DOUBLE_EPS (1.e-12) #define TINYGLTF_DOUBLE_EQUAL(a, b) (std::fabs((b) - (a)) < TINYGLTF_DOUBLE_EPS) +#ifdef __ANDROID__ +#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS + AAssetManager* asset_manager = nullptr; +#endif +#endif + typedef enum { NULL_TYPE = 0, NUMBER_TYPE = 1, @@ -1729,6 +1741,18 @@ void TinyGLTF::SetFsCallbacks(FsCallbacks callbacks) { fs = callbacks; } bool FileExists(const std::string &abs_filename, void *) { bool ret; +#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS + if (asset_manager) { + AAsset* asset = AAssetManager_open(asset_manager, abs_filename.c_str(), AASSET_MODE_STREAMING); + if (!asset) { + return false; + } + AAsset_close(asset); + ret = true; + } else { + return false; + } +#else #ifdef _WIN32 FILE *fp; errno_t err = fopen_s(&fp, abs_filename.c_str(), "rb"); @@ -1744,6 +1768,7 @@ bool FileExists(const std::string &abs_filename, void *) { } else { ret = false; } +#endif return ret; } @@ -1797,6 +1822,33 @@ std::string ExpandFilePath(const std::string &filepath, void *) { bool ReadWholeFile(std::vector *out, std::string *err, const std::string &filepath, void *) { +#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS + if (asset_manager) { + AAsset* asset = AAssetManager_open(asset_manager, filepath.c_str(), AASSET_MODE_STREAMING); + if (!asset) { + if (err) { + (*err) += "File open error : " + filepath + "\n"; + } + return false; + } + size_t size = AAsset_getLength(asset); + if (size <= 0) { + if (err) { + (*err) += "Invalid file size : " + filepath + + " (does the path point to a directory?)"; + } + } + out->resize(size); + AAsset_read(asset, reinterpret_cast(&out->at(0)), size); + AAsset_close(asset); + return true; + } else { + if (err) { + (*err) += "No asset manager specified : " + filepath + "\n"; + } + return false; + } +#else std::ifstream f(filepath.c_str(), std::ifstream::binary); if (!f) { if (err) { @@ -1828,6 +1880,7 @@ bool ReadWholeFile(std::vector *out, std::string *err, f.close(); return true; +#endif } bool WriteWholeFile(std::string *err, const std::string &filepath,