From 7a8a3e835aa4fefb930b843466db1566621e1fbe Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Tue, 11 Jul 2017 10:20:12 +0300 Subject: [PATCH] quick backup of the finished scene loader before I submit other parts changes *Note: I made a change to simplify the recursive create_object function. Since most nodes contain only one mesh, there's no point to iterate through meshes, we just choose the first one available. Also: despite the fact that our 3d model is flat (no node hierarchy) we calculate its modelling transformation recursively (as a product of its local transform with the accumulative transformation of its parent nodes), this way we can safely replace the models anytime. --- src/main.cc | 17 +++++++++++++++ src/object.cc | 1 - src/object.h | 1 + src/scene.cc | 68 +++++++++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/main.cc b/src/main.cc index 2926420..dc3440d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -3,6 +3,10 @@ #include #include +#include "object.h" +#include "mesh.h" +#include "scene.h" + #include "opengl/opengl.h" #include "vulkan/vk.h" @@ -20,6 +24,7 @@ bool use_vulkan; GLFWwindow *win; /* variables */ +static Scene scene; int main(int argc, char **argv) { @@ -66,6 +71,18 @@ static bool init() return false; } + if(!scene.load("data/spot/spot_control_mesh.obj")) { + fprintf(stderr, "Failed to load scene.\n"); + return false; + } + + for(size_t i=0; imesh->name.c_str()); + printf("material: %s\n", scene.objects[i]->material->name.c_str()); + printf("transform:\n"); + scene.objects[i]->transform.print(); + } return true; } diff --git a/src/object.cc b/src/object.cc index 7b6292d..acb5240 100644 --- a/src/object.cc +++ b/src/object.cc @@ -10,5 +10,4 @@ Object::Object() Object::~Object() { - delete mesh; } \ No newline at end of file diff --git a/src/object.h b/src/object.h index 220e1d7..57aef84 100644 --- a/src/object.h +++ b/src/object.h @@ -21,6 +21,7 @@ struct Material { float shininess; Texture *dtex; // diffuse + std::string name; }; class Object { diff --git a/src/scene.cc b/src/scene.cc index 7f9a879..2dc20bc 100644 --- a/src/scene.cc +++ b/src/scene.cc @@ -25,6 +25,9 @@ extern bool use_vulkan; static Mesh *load_mesh(const aiScene *scene, unsigned int index); static Material *load_material(const aiScene *ascene, Scene *scene, unsigned int index); +static Mat4 aiMatrix2Mat(aiMatrix4x4 t); +static void create_object(aiNode *node, Mat4 transform, Scene *scene, const aiScene *ascene); + Scene::Scene() {} Scene::~Scene() @@ -56,7 +59,7 @@ bool Scene::load(const char *fname) return false; } - /* loading scene meshes */ + /* load meshes */ for(unsigned int i=0; imNumMeshes; ++i) { Mesh *mesh = load_mesh(scene, i); if(!mesh) { @@ -66,7 +69,7 @@ bool Scene::load(const char *fname) meshes.push_back(mesh); } - /* loading materials */ + /* load materials */ for(unsigned int i=0; imNumMaterials; ++i) { Material *material = load_material(scene, this, i); if(!material) { @@ -77,16 +80,51 @@ bool Scene::load(const char *fname) } /* create objects */ - for(unsigned int i=0; imNumMeshes; ++i) { - Object *object = new Object(); - object->mesh = meshes[i]; - int idx = meshes[i]->mat_idx; - object->material = materials[idx]; - objects.push_back(object); + aiNode *node = scene->mRootNode; + Mat4 transform = Mat4::identity; + create_object(node, transform, this, scene); + return true; +} + +static Mat4 aiMatrix2Mat(aiMatrix4x4 t) +{ + return Mat4(t.a1, t.a2, t.a3, t.a4, + t.b1, t.b2, t.b3, t.b4, + t.c1, t.c2, t.c3, t.c4, + t.d1, t.d2, t.d3, t.d4); +} + +static void create_object(aiNode *node, Mat4 parent_transform, Scene *scene, const aiScene *ascene) +{ + /* Note: + The 99% of the scenes have 1 mesh per node => for simplicity we only check the 1st one. + Also: the 3D models we are going to use for this demo, have flat structure (no hierarchy) + but just in case we need to replace them later, we calculate the transform by assuming that we + have a node hierarchy. This => that each object's modelling transformation is the + product of its local transformation (mTransformation) with the acc parent nodes transformations + (parent_transform) + */ + Mat4 modelling_transform = parent_transform * aiMatrix2Mat(node->mTransformation); + + if(node->mNumMeshes > 0) { + Object *object = new Object; + + // get the mesh index from node + int mesh_idx = node->mMeshes[0]; + object->mesh = scene->meshes[mesh_idx]; + + // get the material index from the mesh that is assigned to this node + aiMesh *amesh = ascene->mMeshes[mesh_idx]; + object->material = scene->materials[amesh->mMaterialIndex]; + + // set the object's transformation + object->transform = modelling_transform; + scene->objects.push_back(object); } - aiReleaseImport(scene); - return true; + for(unsigned int i=0; imNumChildren; ++i) { + create_object(node->mChildren[i], modelling_transform, scene, ascene); + } } static Mesh *load_mesh(const aiScene *scene, unsigned int index) @@ -140,8 +178,7 @@ static Mesh *load_mesh(const aiScene *scene, unsigned int index) /* texture coordinates */ if(amesh->mTextureCoords[0]) { mesh->which_mask |= MESH_TEXTURE; - Vec2 tex_coord = - Vec2(amesh->mTextureCoords[0][i].x, amesh->mTextureCoords[0][i].y); + Vec2 tex_coord = Vec2(amesh->mTextureCoords[0][i].x, amesh->mTextureCoords[0][i].y); mesh->tex_coords.push_back(tex_coord); } else { @@ -172,7 +209,6 @@ static Mesh *load_mesh(const aiScene *scene, unsigned int index) fprintf(stderr, "No faces found.\n"); mesh->mat_idx = amesh->mMaterialIndex; - printf("material idx:%u", mesh->mat_idx); return mesh; } @@ -188,9 +224,9 @@ static Material *load_material(const aiScene *ascene, Scene *scene, unsigned int mat->dtex = 0; mat->shininess = 40; - // aiString name; - // amat->Get(AI_MATKEY_NAME, name); - // mat->name = std::string(name.data); + aiString name; + amat->Get(AI_MATKEY_NAME, name); + mat->name = std::string(name.data); aiColor4D color; aiGetMaterialColor(amat, AI_MATKEY_COLOR_DIFFUSE, &color); -- 1.7.10.4