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()
return false;
}
- /* loading scene meshes */
+ /* load meshes */
for(unsigned int i=0; i<scene->mNumMeshes; ++i) {
Mesh *mesh = load_mesh(scene, i);
if(!mesh) {
meshes.push_back(mesh);
}
- /* loading materials */
+ /* load materials */
for(unsigned int i=0; i<scene->mNumMaterials; ++i) {
Material *material = load_material(scene, this, i);
if(!material) {
}
/* create objects */
- for(unsigned int i=0; i<scene->mNumMeshes; ++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; i<node->mNumChildren; ++i) {
+ create_object(node->mChildren[i], modelling_transform, scene, ascene);
+ }
}
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 {
fprintf(stderr, "No faces found.\n");
mesh->mat_idx = amesh->mMaterialIndex;
- printf("material idx:%u", mesh->mat_idx);
return mesh;
}
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);