quick backup
[demo] / src / scene.cc
index 2dc20bc..8adb7df 100644 (file)
@@ -23,7 +23,7 @@
 
 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 Material *load_material(const aiScene *ascene, Scene *scene, unsigned int index, const char *tex_fname);
 
 static Mat4 aiMatrix2Mat(aiMatrix4x4 t);
 static void create_object(aiNode *node, Mat4 transform, Scene *scene, const aiScene *ascene);
@@ -32,19 +32,19 @@ Scene::Scene() {}
 
 Scene::~Scene()
 {
-       for(size_t i=0; i<meshes.size(); ++i)
+       for(size_t i=0; i<meshes.size(); i++)
                delete meshes[i];
        meshes.clear();
 
-       for(size_t i=0; i<materials.size(); ++i)
+       for(size_t i=0; i<materials.size(); i++)
                delete materials[i];
        materials.clear();
 
-       for(size_t i=0; i<textures.size(); ++i)
+       for(size_t i=0; i<textures.size(); i++)
                delete textures[i];
        textures.clear();
 
-       for(size_t i=0; i<objects.size(); ++i)
+       for(size_t i=0; i<objects.size(); i++)
                delete objects[i];
        objects.clear();
 }
@@ -52,7 +52,8 @@ Scene::~Scene()
 bool Scene::load(const char *fname)
 {
        /* loading scene */
-       unsigned int ai_flags = aiProcessPreset_TargetRealtime_Quality;
+       /* TODO !!!!!!!!!!!!!!!! flipuvs might need to be removed + fix the cow */
+       unsigned int ai_flags = aiProcessPreset_TargetRealtime_Quality | aiProcess_FlipUVs;
        const aiScene *scene = aiImportFile(fname, ai_flags);
        if(!scene) {
                fprintf(stderr, "Failed to import scene: %s\n", fname);
@@ -60,18 +61,30 @@ bool Scene::load(const char *fname)
        }
 
        /* load meshes */
-       for(unsigned int i=0; i<scene->mNumMeshes; ++i) {
+       for(unsigned int i=0; i<scene->mNumMeshes; i++) {
                Mesh *mesh = load_mesh(scene, i);
                if(!mesh) {
                        fprintf(stderr, "Failed to load mesh no: %d.\n", i);
                        return false;
                }
+               mesh->update_vertex_data();
                meshes.push_back(mesh);
        }
 
        /* load materials */
-       for(unsigned int i=0; i<scene->mNumMaterials; ++i) {
-               Material *material = load_material(scene, this, i);
+       char *tex_path = new char[strlen(fname) + 1];
+       strcpy(tex_path, fname);
+       char *last_slash = strrchr(tex_path, '/');
+       if(last_slash) {
+               *last_slash = '\0';
+       }
+       else {
+               delete [] tex_path;
+               tex_path = 0;
+       }
+
+       for(unsigned int i=0; i<scene->mNumMaterials; i++) {
+               Material *material = load_material(scene, this, i, tex_path);
                if(!material) {
                        fprintf(stderr, "Failed to load material no: %d", i);
                        return false;
@@ -100,7 +113,7 @@ static void create_object(aiNode *node, Mat4 parent_transform, Scene *scene, con
           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 
+          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)
        */
@@ -122,7 +135,7 @@ static void create_object(aiNode *node, Mat4 parent_transform, Scene *scene, con
                scene->objects.push_back(object);
        }
 
-       for(unsigned int i=0; i<node->mNumChildren; ++i) {
+       for(unsigned int i=0; i<node->mNumChildren; i++) {
                create_object(node->mChildren[i], modelling_transform, scene, ascene);
        }
 }
@@ -145,12 +158,10 @@ static Mesh *load_mesh(const aiScene *scene, unsigned int index)
        }
 
        mesh->name = std::string(amesh->mName.data);
-       mesh->which_mask = 0;
 
-       for(unsigned int i=0; i<amesh->mNumVertices; ++i) {
+       for(unsigned int i=0; i<amesh->mNumVertices; i++) {
                /* vertices */
                if(amesh->HasPositions()) {
-                       mesh->which_mask |= MESH_VERTEX;
                        Vec3 vertex = Vec3(amesh->mVertices[i].x, amesh->mVertices[i].y,
                                           amesh->mVertices[i].z);
 
@@ -164,7 +175,6 @@ static Mesh *load_mesh(const aiScene *scene, unsigned int index)
 
                /* normals */
                if(amesh->HasNormals()) {
-                       mesh->which_mask |= MESH_NORMAL;
                        Vec3 normal = Vec3(amesh->mNormals[i].x, amesh->mNormals[i].y,
                                           amesh->mNormals[i].z);
                        mesh->normals.push_back(normal);
@@ -177,29 +187,28 @@ 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);
                        mesh->tex_coords.push_back(tex_coord);
                }
                else {
+                       printf("mesh has no texture coordinates.\n");
                        mesh->tex_coords.push_back(Vec2(0, 0));
                }
 
                /* tangents */
-               if(amesh->mTangents) {
-                       mesh->which_mask |= MESH_TANGENT;
-                       Vec3 tangent = Vec3(amesh->mTangents[i].x, amesh->mTangents[i].y,
-                                           amesh->mTangents[i].z);
-                       mesh->tangents.push_back(tangent);
-               }
-               else {
-                       mesh->tangents.push_back(Vec3(1, 0, 0));
-               }
+               // if(amesh->mTangents) {
+               //      mesh->which_mask |= MESH_TANGENT;
+               //      Vec3 tangent = Vec3(amesh->mTangents[i].x, amesh->mTangents[i].y,
+               //                          amesh->mTangents[i].z);
+               //      mesh->tangents.push_back(tangent);
+               // }
+               // else {
+               //      mesh->tangents.push_back(Vec3(1, 0, 0));
+               // }
        }
        /* indices (called faces in assimp) */
        if(amesh->HasFaces()) {
-               mesh->which_mask |= MESH_INDEX;
-               for(unsigned int i=0; i<amesh->mNumFaces; ++i) {
+               for(unsigned int i=0; i<amesh->mNumFaces; i++) {
                        mesh->indices.push_back(amesh->mFaces[i].mIndices[0]);
                        mesh->indices.push_back(amesh->mFaces[i].mIndices[1]);
                        mesh->indices.push_back(amesh->mFaces[i].mIndices[2]);
@@ -212,7 +221,7 @@ static Mesh *load_mesh(const aiScene *scene, unsigned int index)
        return mesh;
 }
 
-static Material *load_material(const aiScene *ascene, Scene *scene, unsigned int index)
+static Material *load_material(const aiScene *ascene, Scene *scene, unsigned int index, const char *tex_path)
 {
        aiMaterial *amat = ascene->mMaterials[index];
        if(!amat) {
@@ -233,31 +242,74 @@ static Material *load_material(const aiScene *ascene, Scene *scene, unsigned int
        mat->diffuse = Vec3(color.r, color.g, color.b);
 
        aiGetMaterialColor(amat, AI_MATKEY_COLOR_SPECULAR, &color);
-       float spstr;
-       aiGetMaterialFloat(amat, AI_MATKEY_SHININESS_STRENGTH, &spstr);
-       mat->specular = spstr * Vec3(color.r, color.g, color.b);
+       // float spstr;
+       // aiGetMaterialFloat(amat, AI_MATKEY_SHININESS_STRENGTH, &spstr);
+       // mat->specular = spstr * Vec3(color.r, color.g, color.b);
+       mat->specular = Vec3(color.r, color.g, color.b);
 
        aiGetMaterialFloat(amat, AI_MATKEY_SHININESS, &mat->shininess);
+       mat->shininess /= 128.0;
 
+       printf("shininess: %f\n", mat->shininess);
        aiString tex_name;
        if(aiGetMaterialString(amat, AI_MATKEY_TEXTURE_DIFFUSE(0), &tex_name) == aiReturn_SUCCESS) {
                /* different scene objects might use the same texture, we shouldn't store it twice*/
-               //mat->dtex = scene->find_texture(tex_name.data);
+
+               std::string tex_fname = tex_path ? std::string(tex_path) + "/" + tex_name.data : tex_name.data;
+
+               mat->dtex = scene->find_texture(tex_fname.c_str());
                if(!mat->dtex) {
+                       printf("!mat->dtex\n");
                        if(use_vulkan) {
                                mat->dtex = new TextureVK;
                        }
                        else {
                                mat->dtex = new TextureGL;
                        }
-                       if(!mat->dtex->load(tex_name.data)) {
-                               fprintf(stderr, "Failed to load texture data: %s.\n", tex_name.data);
+                       if(!mat->dtex->load(tex_fname.c_str())) {
+                               fprintf(stderr, "Failed to load texture data: %s.\n", tex_fname.c_str());
                                delete mat->dtex;
                                mat->dtex = 0;
                        }
+                       else {
+                               mat->dtex->name = std::string(tex_fname.c_str());
+                       }
+                       printf("Successfully loaded texture: %s\n", tex_fname.c_str());
                        scene->textures.push_back(mat->dtex);
                }
        }
 
        return mat;
 }
+
+Mesh *Scene::find_mesh(const char *name)
+{
+       for(size_t i=0; i<meshes.size(); i++) {
+               if(meshes[i]->name == name) {
+                       return meshes[i];
+               }
+       }
+       fprintf(stderr, "Mesh %s not found.\n", name);
+       return 0;
+}
+
+Material *Scene::find_material(const char *name)
+{
+       for(size_t i=0; i<materials.size(); i++) {
+               if(materials[i]->name == name) {
+                       return materials[i];
+               }
+       }
+       fprintf(stderr, "Material %s not found.\n", name);
+       return 0;
+}
+
+Texture *Scene::find_texture(const char *name) {
+       for(size_t i=0; i<textures.size(); i++) {
+               if(textures[i]->name == name) {
+                       return textures[i];
+               }
+       }
+       fprintf(stderr, "Texture %s not found.\n", name);
+       return 0;
+}
\ No newline at end of file