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.
262 lines
5.7 KiB
262 lines
5.7 KiB
#include <cassert> |
|
|
|
#if 0 |
|
#include <assimp/cimport.h> |
|
#include <assimp/scene.h> |
|
#include <assimp/postprocess.h> |
|
#endif |
|
|
|
#include <glm/glm.hpp> |
|
#include <glm/geometric.hpp> |
|
#include <glm/gtc/matrix_transform.hpp> |
|
|
|
#include "dumbLog.h" |
|
|
|
#include "mesh.h" |
|
|
|
|
|
// WIP |
|
bool meInitAssimp() { return false; } |
|
|
|
bool meLoadFromFile(mesh_group& mesh_group, const char* filepath) |
|
{ |
|
return false; |
|
} |
|
|
|
simple_mesh* |
|
meInitMesh(uint num_vertices) { return nullptr; } |
|
|
|
void |
|
meFreeMeshGroup(mesh_group& mesh_group) {} |
|
|
|
void |
|
meFreeSimpleMesh(simple_mesh* mesh) {} |
|
|
|
void |
|
meShutdownAssimp() {} |
|
|
|
// WIP |
|
|
|
|
|
#if 0 |
|
// forward declarations |
|
|
|
mesh_info* allocateMeshInfo(uint num_vertices, uint num_indices); |
|
void assimpLogCB(const char* message, char* user); |
|
mesh_info* copyMeshInfo(const aiScene* scene, aiMesh* mesh); |
|
inline glm::vec3 copyVector(aiVector3D v_in, glm::vec3& v_out); |
|
void freeMesh(mesh_info* mesh); |
|
bool loadDiffuseTexture(const aiScene* scene, aiMesh* mesh, mesh_info* mi); |
|
bool validateScene(const aiScene* scene, const char* filepath); |
|
|
|
// interface |
|
|
|
bool |
|
meInitAssimp() |
|
{ |
|
LOG(Info) << "Initializing Assimp\n"; |
|
aiLogStream ls; |
|
ls.callback = assimpLogCB; |
|
aiAttachLogStream(&ls); |
|
|
|
return true; |
|
} |
|
|
|
bool |
|
meLoadFromFile(mesh_group& mesh_group, const char* filepath) |
|
{ |
|
LOG(Info) << "Loading file: " << filepath << "\n"; |
|
const aiScene* scene = aiImportFile(filepath, aiProcessPreset_TargetRealtime_MaxQuality); |
|
|
|
if (!validateScene(scene, filepath)) |
|
return false; |
|
|
|
mesh_group.num_meshes = scene->mNumMeshes; |
|
mesh_group.meshes = UTIL_ALLOC(mesh_group.num_meshes, mesh_info*); |
|
|
|
for (uint i = 0; i < scene->mNumMeshes; i++) { |
|
aiMesh* mesh = scene->mMeshes[i]; |
|
mesh_info* mi = copyMeshInfo(scene, mesh); |
|
|
|
if (!mesh->HasTextureCoords(0) || |
|
!loadDiffuseTexture(scene, mesh, mi)) |
|
{ |
|
LOG(Error) << "Error loading texture, cleaning up import\n"; |
|
freeMesh(mi); |
|
aiReleaseImport(scene); |
|
return false; |
|
} |
|
|
|
mesh_group.meshes[i] = mi; |
|
} |
|
|
|
aiReleaseImport(scene); |
|
return true; |
|
} |
|
|
|
simple_mesh* |
|
meInitMesh(uint num_vertices) |
|
{ |
|
assert(num_vertices > 0); |
|
simple_mesh* sm = UTIL_ALLOC(1, simple_mesh); |
|
sm->model_transform = glm::mat4(1.0); |
|
sm->num_vertices = num_vertices; |
|
sm->vertices = UTIL_ALLOC(num_vertices, glm::vec3); |
|
sm->vert_colors = UTIL_ALLOC(num_vertices, glm::vec3); |
|
return sm; |
|
} |
|
|
|
void |
|
meFreeMeshGroup(mesh_group& mesh_group) |
|
{ |
|
for (uint i = 0; i < mesh_group.num_meshes; i++) |
|
freeMesh(mesh_group.meshes[i]); |
|
|
|
utilSafeFree(mesh_group.meshes); |
|
mesh_group.num_meshes = 0; |
|
mesh_group.meshes = nullptr; |
|
} |
|
|
|
void |
|
meFreeSimpleMesh(simple_mesh* mesh) |
|
{ |
|
assert(mesh != nullptr); |
|
utilSafeFree(mesh->vertices); |
|
mesh->vertices = nullptr; |
|
utilSafeFree(mesh->vert_colors); |
|
mesh->vert_colors = nullptr; |
|
mesh->num_vertices = 0; |
|
} |
|
|
|
void |
|
meShutdownAssimp() |
|
{ |
|
aiDetachAllLogStreams(); |
|
} |
|
|
|
|
|
// internal |
|
|
|
mesh_info* |
|
allocateMeshInfo(uint num_vertices, uint num_indices) |
|
{ |
|
mesh_info* mi = UTIL_ALLOC(1, mesh_info); |
|
mi->model_transform = glm::mat4(1); |
|
|
|
// allocate buffers for vertex and index data from mesh |
|
mi->num_vertices = num_vertices; |
|
mi->vertices = UTIL_ALLOC(mi->num_vertices, glm::vec3); |
|
mi->num_indices = num_indices; |
|
mi->indices = UTIL_ALLOC(num_indices, uint); |
|
mi->normals = UTIL_ALLOC(mi->num_vertices, glm::vec3); |
|
mi->texture_coords = UTIL_ALLOC(mi->num_vertices, glm::vec3); |
|
|
|
return mi; |
|
} |
|
|
|
void |
|
assimpLogCB(const char* message, char* user) |
|
{ |
|
// NOTE: filter 'info' messages from assimp |
|
if (!utilMatchPrefix(message, "Info,", 5)) |
|
LOG(Info) << message << "\n"; |
|
} |
|
|
|
mesh_info* |
|
copyMeshInfo(const aiScene* scene, aiMesh* mesh) |
|
{ |
|
mesh_info* mi = allocateMeshInfo(mesh->mNumVertices, mesh->mNumFaces * 3); |
|
|
|
// copy vertices, normals, and texture coords |
|
for (uint i = 0; i < mi->num_vertices; i++) { |
|
copyVector(mesh->mVertices[i], mi->vertices[i]); |
|
copyVector(mesh->mNormals[i], mi->normals[i]); |
|
mi->texture_coords[i].x = mesh->mTextureCoords[0][i].x; |
|
mi->texture_coords[i].y = mesh->mTextureCoords[0][i].y; |
|
mi->texture_coords[i].z = 0; |
|
} |
|
|
|
// 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]; |
|
|
|
return mi; |
|
} |
|
|
|
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; |
|
} |
|
|
|
void |
|
freeMesh(mesh_info* mesh) |
|
{ |
|
utilFreeImage(mesh->diffuse_texture); |
|
utilSafeFree(mesh->vertices); |
|
utilSafeFree(mesh->normals); |
|
utilSafeFree(mesh->texture_coords); |
|
utilSafeFree(mesh->indices); |
|
utilSafeFree(mesh); |
|
} |
|
|
|
bool |
|
loadDiffuseTexture(const aiScene* scene, aiMesh* mesh, mesh_info* mi) |
|
{ |
|
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex]; |
|
aiString file_name; |
|
|
|
if (mat->GetTextureCount(aiTextureType_DIFFUSE) < 1) |
|
return false; |
|
|
|
if (AI_SUCCESS != mat->GetTexture( |
|
aiTextureType_DIFFUSE, 0, &file_name, NULL, NULL, NULL, NULL, NULL)) |
|
{ |
|
LOG(Error) << "No diffuse texture from assimp\n"; |
|
return false; |
|
} else { |
|
const aiTexture* tex = scene->GetEmbeddedTexture(file_name.C_Str()); |
|
|
|
if (tex != nullptr) { |
|
LOG(Info) << "has embedded texture\n"; |
|
mi->diffuse_texture = utilLoadImageBytes((const uint8*) tex->pcData, tex->mWidth); |
|
} else { |
|
LOG(Info) << "Loading texture file: " << file_name.C_Str() << "\n"; |
|
mi->diffuse_texture = utilLoadImagePath(file_name.C_Str()); |
|
} |
|
|
|
if (mi->diffuse_texture.pixels == nullptr) { |
|
LOG(Error) << "Error loading texture\n"; |
|
return false; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
bool |
|
validateScene(const aiScene* scene, const char* filepath) |
|
{ |
|
if (!scene) { |
|
LOG(Error) << "Error loading file: " << filepath << "\n"; |
|
return false; |
|
} |
|
|
|
if (scene->mNumMeshes < 1) { |
|
LOG(Error) << "Scene contains no meshes\n"; |
|
return false; |
|
} |
|
|
|
if (!scene->mMeshes[0]->HasNormals()) { |
|
LOG(Error) << "Mesh doesn't have normals\n"; |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
#endif |
|
|
|
|