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);
 
 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);
 
 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()
 {
 
 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();
 
                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();
 
                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();
 
                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();
 }
                delete objects[i];
        objects.clear();
 }
@@ -52,7 +52,8 @@ Scene::~Scene()
 bool Scene::load(const char *fname)
 {
        /* loading 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);
        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 */
        }
 
        /* 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 *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 */
                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;
                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
           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)
        */
           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);
        }
 
                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);
        }
 }
                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->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()) {
                /* vertices */
                if(amesh->HasPositions()) {
-                       mesh->which_mask |= MESH_VERTEX;
                        Vec3 vertex = Vec3(amesh->mVertices[i].x, amesh->mVertices[i].y,
                                           amesh->mVertices[i].z);
 
                        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()) {
 
                /* 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);
                        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]) {
 
                /* 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 {
                        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 */
                        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()) {
        }
        /* 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]);
                        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;
 }
 
        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) {
 {
        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);
        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);
 
        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*/
        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) {
                if(!mat->dtex) {
+                       printf("!mat->dtex\n");
                        if(use_vulkan) {
                                mat->dtex = new TextureVK;
                        }
                        else {
                                mat->dtex = new TextureGL;
                        }
                        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;
                        }
                                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;
 }
                        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