You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

150 lines
3.8 KiB

#include <cassert>
#include <string>
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <glm/glm.hpp>
#include <glm/geometric.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "aixlog.hpp"
#include "mesh.h"
inline glm::vec3 copyVector(aiVector3D v_in, glm::vec3& v_out);
meMeshInfo* copyMeshInfo(const char* data_dir, const aiScene* scene, aiMesh* mesh);
void freeMesh(meMeshInfo* mesh);
bool
meInitAssimp()
{
LOG(INFO) << "Initializing Assimp\n";
/* get a handle to the predefined STDOUT log stream and attach
* it to the logging system. It remains active for all further
* calls to aiImportFile(Ex) and aiApplyPostProcessing. */
aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
aiAttachLogStream(&stream);
return true;
}
bool
meLoadFromFile(const char* data_dir, const char* filename, meMeshGroup& mesh_group)
{
LOG(INFO) << "Loading file: " << filename << "\n";
const aiScene* scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_MaxQuality);
if (!scene) {
LOG(ERROR) << "Error loading file: " << filename << "\n";
return false;
}
if (scene->mNumMeshes < 1) {
LOG(ERROR) << "Scene contains no meshes\n";
return false;
}
mesh_group.num_meshes = scene->mNumMeshes;
mesh_group.meshes = UTIL_ALLOC(mesh_group.num_meshes, meMeshInfo*);
mesh_group.use_normals = scene->mMeshes[0]->HasNormals();
for (uint i = 0; i < scene->mNumMeshes; i++) {
mesh_group.meshes[i] = copyMeshInfo(data_dir, scene, scene->mMeshes[i]);
}
// free memeory from assimp
aiReleaseImport(scene);
return true;
}
void
meFreeMeshGroup(meMeshGroup& mesh_group)
{
for (uint i = 0; i < mesh_group.num_meshes; i++)
freeMesh(mesh_group.meshes[i]);
utilSafeFree(mesh_group.meshes);
}
void
meShutdownAssimp()
{
aiDetachAllLogStreams();
}
inline glm::vec3
copyVector(aiVector3D v_in, glm::vec3& v_out)
{
v_out.x = v_in.x;
v_out.y = v_in.y;
v_out.z = v_in.z;
return v_out;
}
meMeshInfo*
copyMeshInfo(const char* data_dir, const aiScene* scene, aiMesh* mesh)
{
meMeshInfo* mi = UTIL_ALLOC(1, meMeshInfo);
mi->model_transform = glm::mat4(1);
// allocate buffers for vertex and index data from mesh
mi->num_vertices = mesh->mNumVertices;
mi->vertices = UTIL_ALLOC(mi->num_vertices, glm::vec3);
mi->normals = UTIL_ALLOC(mi->num_vertices, glm::vec3);
mi->num_indices = mesh->mNumFaces * 3; // NOTE: assume 3 vertices per face
mi->indices = UTIL_ALLOC(mi->num_indices, uint);
// copy vertices and normals
for (uint i = 0; i < mi->num_vertices; i++) {
copyVector(mesh->mVertices[i], mi->vertices[i]);
if (mesh->HasNormals())
copyVector(mesh->mNormals[i], mi->normals[i]);
}
// copy indices
for (uint i = 0; i < mesh->mNumFaces; i++)
for (uint j = 0; j < 3; j++)
mi->indices[i * 3 + j] = mesh->mFaces[i].mIndices[j];
// material
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
aiColor3D color(0.f, 0.f, 0.f);
if (AI_SUCCESS != mat->Get(AI_MATKEY_COLOR_DIFFUSE, color)) {
LOG(ERROR) << "Some Assimp-type-error\n";
} else {
mi->diffuse_color.r = color.r;
mi->diffuse_color.g = color.g;
mi->diffuse_color.b = color.b;
}
if (mat->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
aiString file_name;
if (AI_SUCCESS != mat->GetTexture(aiTextureType_DIFFUSE, 0, &file_name, NULL, NULL, NULL, NULL, NULL)) {
LOG(ERROR) << "Some Assimp-type-error\n";
} else {
std::string file_path;
file_path.append(data_dir).append("/").append(file_name.C_Str());
LOG(INFO) << "Loading texture file: " << file_name.C_Str() << "\n";
mi->diffuse_texture = utilLoadImage(file_path.c_str());
}
}
return mi;
}
void
freeMesh(meMeshInfo* mesh)
{
if (mesh->diffuse_texture.pixels != 0)
utilFreeImage(mesh->diffuse_texture);
utilSafeFree(mesh->vertices);
utilSafeFree(mesh->normals);
utilSafeFree(mesh->indices);
utilSafeFree(mesh);
}