From 7dc732cd42c88fa16accdbc606f10bcd6815d478 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Thu, 1 Dec 2016 05:01:48 +0200 Subject: [PATCH] separated scene loading into IO and GL parts in preparation for resman --- src/scene.h | 6 ++- src/sceneload.cc | 159 ++++++++++++++++++++++++++++++++---------------------- 2 files changed, 100 insertions(+), 65 deletions(-) diff --git a/src/scene.h b/src/scene.h index a8c8e6a..ece454e 100644 --- a/src/scene.h +++ b/src/scene.h @@ -9,7 +9,10 @@ enum { SCNLOAD_FLIPYZ = 1, - SCNLOAD_FLIPTEX = 2 + SCNLOAD_FLIPTEX = 2, + + SCNLOAD_STAGE_IO = 0x4000, + SCNLOAD_STAGE_GL = 0x8000 }; class Scene { @@ -25,6 +28,7 @@ public: Mesh *walk_mesh; TextureSet *texset; // only owned by Scene if own_texset is true + void *loader_data; explicit Scene(TextureSet *tset = 0); ~Scene(); diff --git a/src/sceneload.cc b/src/sceneload.cc index 6e959b2..7fdc004 100644 --- a/src/sceneload.cc +++ b/src/sceneload.cc @@ -33,85 +33,114 @@ static long assimp_time(const aiAnimation *anim, double aitime); static void print_hierarchy(const aiNode *node); */ -static std::map node_by_name; -static std::map mesh_by_aimesh; +struct LoaderData { + const aiScene *aiscn; + std::map node_by_name; + std::map mesh_by_aimesh; +}; + +#define LD_STAGE_MASK 0xf000 bool Scene::load(const char *fname, unsigned int flags) { - unsigned int ppflags = aiProcess_CalcTangentSpace | - aiProcess_GenNormals | - aiProcess_JoinIdenticalVertices | - aiProcess_Triangulate | - aiProcess_SortByPType | - aiProcess_GenUVCoords | - //aiProcess_PreTransformVertices | - aiProcess_TransformUVCoords; - - if(flags & SCNLOAD_FLIPTEX) { - ppflags |= aiProcess_FlipUVs; + if((flags & LD_STAGE_MASK) == 0) { + // not passing either of the stage specifiers, means do the whole job + flags |= LD_STAGE_MASK; } - info_log("Loading scene file: %s\n", fname); - - const aiScene *aiscn = aiImportFile(fname, ppflags); - if(!aiscn) { - error_log("failed to load scene file: %s\n", fname); - return false; - } + // first perform I/O and all operations not requiring access to an OpenGL context + if(flags & SCNLOAD_STAGE_IO) { + unsigned int ppflags = aiProcess_CalcTangentSpace | + aiProcess_GenNormals | + aiProcess_JoinIdenticalVertices | + aiProcess_Triangulate | + aiProcess_SortByPType | + aiProcess_GenUVCoords | + //aiProcess_PreTransformVertices | + aiProcess_TransformUVCoords; + + if(flags & SCNLOAD_FLIPTEX) { + ppflags |= aiProcess_FlipUVs; + } - // assimp adds its own root node, which might have transformations - Vec3 root_pos, root_scaling(1.0, 1.0, 1.0); - Quat root_rot; + info_log("Loading scene file: %s\n", fname); - if(aiscn->mRootNode) { - Mat4 root_matrix = assimp_matrix(aiscn->mRootNode->mTransformation); - root_pos = root_matrix.get_translation(); - root_rot = root_matrix.get_rotation(); - root_scaling = root_matrix.get_scaling(); - } + const aiScene *aiscn = aiImportFile(fname, ppflags); + if(!aiscn) { + error_log("failed to load scene file: %s\n", fname); + return false; + } - // load all meshes - for(unsigned int i=0; imNumMeshes; i++) { - aiMesh *aimesh = aiscn->mMeshes[i]; - Mesh *mesh; + // assimp adds its own root node, which might have transformations + Vec3 root_pos, root_scaling(1.0, 1.0, 1.0); + Quat root_rot; - switch(aimesh->mPrimitiveTypes) { - case aiPrimitiveType_TRIANGLE: - if((mesh = load_mesh(this, aiscn, flags, aimesh))) { - mesh_by_aimesh[aimesh] = mesh; - meshes.push_back(mesh); - } - break; + if(aiscn->mRootNode) { + Mat4 root_matrix = assimp_matrix(aiscn->mRootNode->mTransformation); + root_pos = root_matrix.get_translation(); + root_rot = root_matrix.get_rotation(); + root_scaling = root_matrix.get_scaling(); + } - default: - error_log("unsupported primitive type: %u\n", aimesh->mPrimitiveTypes); - break; + if(!nodes) { + nodes = new SceneNode; + nodes->scene = this; + nodes->set_name("root"); + nodes->set_position(root_pos); + nodes->set_rotation(root_rot); + nodes->set_scaling(root_scaling); } - } - if(!nodes) { - nodes = new SceneNode; - nodes->scene = this; - nodes->set_name("root"); - nodes->set_position(root_pos); - nodes->set_rotation(root_rot); - nodes->set_scaling(root_scaling); + LoaderData *ldata = new LoaderData; + ldata->aiscn = aiscn; + loader_data = (void*)ldata; } - // load all the nodes recursively - for(unsigned int i=0; imRootNode->mNumChildren; i++) { - SceneNode *node = load_node(this, aiscn, flags, aiscn->mRootNode->mChildren[i]); - if(node) { - nodes->add_child(node); + /* 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]; + Mesh *mesh; + + switch(aimesh->mPrimitiveTypes) { + case aiPrimitiveType_TRIANGLE: + if((mesh = load_mesh(this, aiscn, flags, aimesh))) { + ldata->mesh_by_aimesh[aimesh] = mesh; + meshes.push_back(mesh); + } + break; + + default: + error_log("unsupported primitive type: %u\n", aimesh->mPrimitiveTypes); + break; + } } - } - node_by_name.clear(); - mesh_by_aimesh.clear(); + // load all the nodes recursively + for(unsigned int i=0; imRootNode->mNumChildren; i++) { + SceneNode *node = load_node(this, aiscn, flags, aiscn->mRootNode->mChildren[i]); + if(node) { + nodes->add_child(node); + } + } - aiReleaseImport(aiscn); - info_log("loaded scene file: %s, %d meshes\n", fname, (int)meshes.size()); - nodes->update(0); + 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; } @@ -182,6 +211,8 @@ 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) { + LoaderData *ldata = (LoaderData*)scn->loader_data; + SceneNode *node = new SceneNode; node->set_name(ainode->mName.data); @@ -200,7 +231,7 @@ static SceneNode *load_node(Scene *scn, const aiScene *aiscn, unsigned int flags for(unsigned int i=0; imNumMeshes; i++) { aiMesh *aimesh = aiscn->mMeshes[ainode->mMeshes[i]]; - Mesh *mesh = mesh_by_aimesh[aimesh]; + Mesh *mesh = ldata->mesh_by_aimesh[aimesh]; if(mesh) { ObjMesh *obj = new ObjMesh; obj->set_name(mesh->get_name()); @@ -221,7 +252,7 @@ static SceneNode *load_node(Scene *scn, const aiScene *aiscn, unsigned int flags } } - node_by_name[node->get_name()] = node; + ldata->node_by_name[node->get_name()] = node; return node; } -- 1.7.10.4