#include <map>
#include <gmath/gmath.h>
#include <assimp/cimport.h>
+#include <assimp/cfileio.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <assimp/mesh.h>
#include <assimp/vector3.h>
#include <assimp/matrix4x4.h>
#include <assimp/quaternion.h>
+#include "assman.h"
#include "app.h"
#include "scene.h"
#include "objmesh.h"
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;
}
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;
nodes->set_scaling(root_scaling);
}
- 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();
-
// load all meshes
for(unsigned int i=0; i<aiscn->mNumMeshes; i++) {
aiMesh *aimesh = aiscn->mMeshes[i];
*dptr++ = *sptr == '\\' ? '/' : *sptr;
} while(*sptr++);
+ if(!fname || !*fname) continue;
+
int textype = assimp_textype(aitype);
Texture *tex = texman.get_texture(fname, TEX_2D, &scn->datamap);
case aiTextureType_EMISSIVE:
return MTL_TEX_LIGHTMAP;
case aiTextureType_REFLECTION:
- return MTL_TEX_ENVMAP;
+ return MTL_TEX_REFLECT;
default:
break;
}
{
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;
+}