X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fsceneload.cc;h=a48838563a93de30add938b509ef64afbcd97d2f;hp=7fdc0041430505d9178764dabe39c193daa9e633;hb=2a5c3d461a983818c82424eef9eeb14761f8b07e;hpb=7dc732cd42c88fa16accdbc606f10bcd6815d478 diff --git a/src/sceneload.cc b/src/sceneload.cc index 7fdc004..a488385 100644 --- a/src/sceneload.cc +++ b/src/sceneload.cc @@ -1,9 +1,11 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -12,10 +14,13 @@ #include #include #include +#include "assfile.h" +#include "app.h" #include "scene.h" #include "objmesh.h" #include "datamap.h" #include "logger.h" +#include "metascene.h" static bool load_material(Scene *scn, Material *mat, const aiMaterial *aimat); static SceneNode *load_node(Scene *scn, const aiScene *aiscn, unsigned int flags, const aiNode *ainode); @@ -23,7 +28,7 @@ static Mesh *load_mesh(Scene *scn, const aiScene *aiscn, unsigned int flags, con /*static const char *mprop_semantic(int x); static int count_textures(const aiMaterial *aimat);*/ static int assimp_textype(aiTextureType type); -static const char *assimp_textypestr(aiTextureType type); +//static const char *assimp_textypestr(aiTextureType type); static Mat4 assimp_matrix(const aiMatrix4x4 &aim); @@ -33,8 +38,16 @@ static long assimp_time(const aiAnimation *anim, double aitime); static void print_hierarchy(const aiNode *node); */ +static aiFile *io_open(aiFileIO *io, const char *fname, const char *mode); +static void io_close(aiFileIO *io, aiFile *aifp); +static size_t io_read(aiFile *aifp, char *buf, size_t size, size_t count); +static size_t io_tell(aiFile *aifp); +static size_t io_filesize(aiFile *aifp); +static aiReturn io_seek(aiFile *aifp, size_t offs, aiOrigin whence); + struct LoaderData { const aiScene *aiscn; + std::string fname; std::map node_by_name; std::map mesh_by_aimesh; }; @@ -64,13 +77,41 @@ bool Scene::load(const char *fname, unsigned int flags) } info_log("Loading scene file: %s\n", fname); + if(this->name.empty()) { + this->name = std::string(fname); + } + + aiFileIO io; + io.OpenProc = io_open; + io.CloseProc = io_close; - const aiScene *aiscn = aiImportFile(fname, ppflags); + const aiScene *aiscn = aiImportFileEx(fname, ppflags, &io); if(!aiscn) { error_log("failed to load scene file: %s\n", fname); return false; } + LoaderData *ldata = new LoaderData; + ldata->aiscn = aiscn; + ldata->fname = std::string(fname); + loader_data = (void*)ldata; + } + + /* then, assuming we have successfully loaded everything, proceed to construct + * all the engine objects, which require access to the OpenGL context + */ + if(flags & SCNLOAD_STAGE_GL) { + if(!loader_data) { + error_log("second stage scene loader failed to find valid I/O data\n"); + return false; + } + + LoaderData *ldata = (LoaderData*)loader_data; + const aiScene *aiscn = ldata->aiscn; + fname = ldata->fname.c_str(); + + clear(); // clear any previous data (TODO: add flag for not clearing) + // assimp adds its own root node, which might have transformations Vec3 root_pos, root_scaling(1.0, 1.0, 1.0); Quat root_rot; @@ -91,23 +132,6 @@ bool Scene::load(const char *fname, unsigned int flags) nodes->set_scaling(root_scaling); } - LoaderData *ldata = new LoaderData; - ldata->aiscn = aiscn; - loader_data = (void*)ldata; - } - - /* then, assuming we have successfully loaded everything, proceed to construct - * all the engine objects, which require access to the OpenGL context - */ - if(flags & SCNLOAD_STAGE_GL) { - if(!loader_data) { - error_log("second stage scene loader failed to find valid I/O data\n"); - return false; - } - - LoaderData *ldata = (LoaderData*)loader_data; - const aiScene *aiscn = ldata->aiscn; - // load all meshes for(unsigned int i=0; imNumMeshes; i++) { aiMesh *aimesh = aiscn->mMeshes[i]; @@ -135,10 +159,11 @@ bool Scene::load(const char *fname, unsigned int flags) } } + info_log("loaded scene file: %s, %d meshes\n", fname, (int)meshes.size()); + aiReleaseImport(aiscn); delete ldata; loader_data = 0; - info_log("loaded scene file: %s, %d meshes\n", fname, (int)meshes.size()); nodes->update(0); } return true; @@ -193,10 +218,11 @@ static bool load_material(Scene *scn, Material *mat, const aiMaterial *aimat) *dptr++ = *sptr == '\\' ? '/' : *sptr; } while(*sptr++); + if(!fname || !*fname) continue; + int textype = assimp_textype(aitype); - info_log("loading %s texture: %s\n", assimp_textypestr(aitype), fname); - Texture *tex = scn->texset->get_texture(fname, TEX_2D); + Texture *tex = texman.get_texture(fname, TEX_2D, &scn->datamap); assert(tex); mat->textures.push_back(tex); @@ -322,14 +348,14 @@ static int assimp_textype(aiTextureType type) case aiTextureType_EMISSIVE: return MTL_TEX_LIGHTMAP; case aiTextureType_REFLECTION: - return MTL_TEX_ENVMAP; + return MTL_TEX_REFLECT; default: break; } return MTL_TEX_UNKNOWN; } -static const char *assimp_textypestr(aiTextureType type) +/*static const char *assimp_textypestr(aiTextureType type) { switch(type) { case aiTextureType_DIFFUSE: @@ -347,7 +373,7 @@ static const char *assimp_textypestr(aiTextureType type) break; } return "unknown"; -} +}*/ static Mat4 assimp_matrix(const aiMatrix4x4 &aim) { @@ -355,3 +381,91 @@ static Mat4 assimp_matrix(const aiMatrix4x4 &aim) memcpy(m[0], &aim, 16 * sizeof(float)); return transpose(m); } + + +// --- SceneSet --- + +SceneSet::SceneSet() + : DataSet(create_scene, load_scene, done_scene, free_scene) +{ +} + +Scene *SceneSet::create_scene() +{ + return new Scene; +} + +bool SceneSet::load_scene(Scene *scn, const char *fname) +{ + return scn->load(fname, SCNLOAD_FLIPTEX | SCNLOAD_STAGE_IO); +} + +bool SceneSet::done_scene(Scene *scn) +{ + bool res = scn->load(0, SCNLOAD_STAGE_GL); + if(scn->metascn) { + scn->metascn->scene_loaded(scn); + } + return res; +} + +void SceneSet::free_scene(Scene *scn) +{ + delete scn; +} + + +// ------ custom file I/O for assimp ------- + +static aiFile *io_open(aiFileIO *io, const char *fname, const char *mode) +{ + ass_file *fp; + if(!(fp = ass_fopen(fname, mode))) { + error_log("failed to open scene file: %s: %s\n", fname, strerror(ass_errno)); + return 0; + } + + aiFile *aifp = new aiFile; + aifp->ReadProc = io_read; + aifp->WriteProc = 0; + aifp->TellProc = io_tell; + aifp->FileSizeProc = io_filesize; + aifp->SeekProc = io_seek; + aifp->FlushProc = 0; + aifp->UserData = (aiUserData)fp; + return aifp; +} + +static void io_close(aiFileIO *io, aiFile *aifp) +{ + ass_fclose(aifp->UserData); + delete aifp; +} + +static size_t io_read(aiFile *aifp, char *buf, size_t size, size_t count) +{ + return ass_fread(buf, size, count, aifp->UserData); +} + +static size_t io_tell(aiFile *aifp) +{ + return ass_ftell(aifp->UserData); +} + +static size_t io_filesize(aiFile *aifp) +{ + ass_file *fp = aifp->UserData; + long cur = ass_ftell(fp); + ass_fseek(fp, 0, SEEK_END); + long off = ass_ftell(fp); + ass_fseek(fp, cur, SEEK_SET); + return off; +} + +static aiReturn io_seek(aiFile *aifp, size_t offs, aiOrigin whence) +{ + if(ass_fseek(aifp->UserData, offs, (int)whence) == -1) { + return aiReturn_FAILURE; + } + return aiReturn_SUCCESS; +}