Created
April 23, 2014 02:28
-
-
Save iondune/11200947 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <string> | |
#include <iostream> | |
#include <map> | |
#include <sys/stat.h> | |
#include "glm/glm.hpp" | |
#include <assimp/Importer.hpp> | |
#include <assimp/scene.h> | |
#include <assimp/postprocess.h> | |
class SVertex | |
{ | |
public: | |
glm::vec3 Position; | |
glm::vec3 Normal; | |
glm::vec2 TextureCoordinates; | |
glm::vec4 Color; | |
}; | |
class SMaterial | |
{ | |
public: | |
glm::vec4 Ambient, Diffuse, Specular; | |
float Shininess; | |
}; | |
class CMesh | |
{ | |
public: | |
struct STriangle | |
{ | |
unsigned int Indices[3]; | |
glm::vec3 Normal; | |
}; | |
struct SMeshBuffer | |
{ | |
std::vector<SVertex> Vertices; | |
std::vector<STriangle> Triangles; | |
void updateBuffers(); | |
void writeObjMesh(std::string const & fileName); | |
SMaterial Material; | |
}; | |
std::vector<SMeshBuffer *> MeshBuffers; | |
}; | |
CMesh * TraverseMesh(CMesh * Result, aiScene const * Scene, aiNode * Node, glm::mat4 Transformation) | |
{ | |
glm::mat4 LocalTransformation = glm::mat4( | |
Node->mTransformation.a1, Node->mTransformation.b1, Node->mTransformation.c1, Node->mTransformation.d1, | |
Node->mTransformation.a2, Node->mTransformation.b2, Node->mTransformation.c2, Node->mTransformation.d2, | |
Node->mTransformation.a3, Node->mTransformation.b3, Node->mTransformation.c3, Node->mTransformation.d3, | |
Node->mTransformation.a4, Node->mTransformation.b4, Node->mTransformation.c4, Node->mTransformation.d4 | |
); | |
Transformation = Transformation * LocalTransformation; | |
for (uint i = 0; i < Node->mNumMeshes; ++ i) | |
{ | |
aiMesh * Mesh = Scene->mMeshes[Node->mMeshes[i]]; | |
CMesh::SMeshBuffer * Buffer = new CMesh::SMeshBuffer; | |
for (uint j = 0; j < Mesh->mNumVertices; ++ j) | |
{ | |
SVertex Vertex; | |
Vertex.Position = glm::vec3(Mesh->mVertices[j].x, Mesh->mVertices[j].y, Mesh->mVertices[j].z); | |
if (Mesh->HasNormals()) | |
Vertex.Normal = glm::vec3(Mesh->mNormals[j].x, Mesh->mNormals[j].y, Mesh->mNormals[j].z); | |
if (Mesh->HasTextureCoords(0)) | |
Vertex.TextureCoordinates = glm::vec2(Mesh->mTextureCoords[0][j].x, Mesh->mTextureCoords[0][j].y); | |
if (Mesh->HasVertexColors(0)) | |
Vertex.Color = glm::vec4(Mesh->mColors[0][j].r, Mesh->mColors[0][j].g, Mesh->mColors[0][j].b, Mesh->mColors[0][j].a); | |
glm::vec4 Pos = glm::vec4(Vertex.Position.x, Vertex.Position.y, Vertex.Position.z, 1); | |
Pos = Transformation * Pos; | |
Vertex.Position = glm::vec3(Pos.x, Pos.y, Pos.z); | |
Buffer->Vertices.push_back(Vertex); | |
} | |
for (uint j = 0; j < Mesh->mNumFaces; ++ j) | |
{ | |
CMesh::STriangle Triangle; | |
for (uint k = 0; k < 3; ++ k) | |
Triangle.Indices[k] = Mesh->mFaces[j].mIndices[k]; | |
Buffer->Triangles.push_back(Triangle); | |
} | |
aiMaterial * Material = Scene->mMaterials[Mesh->mMaterialIndex]; | |
aiColor4D Color; | |
Material->Get(AI_MATKEY_COLOR_DIFFUSE, Color); | |
Buffer->Material.Diffuse = glm::vec4(Color.r, Color.g, Color.b, Color.a); | |
Material->Get(AI_MATKEY_COLOR_AMBIENT, Color); | |
Buffer->Material.Ambient = glm::vec4(Color.r, Color.g, Color.b, Color.a); | |
Material->Get(AI_MATKEY_COLOR_SPECULAR, Color); | |
Buffer->Material.Specular = glm::vec4(Color.r, Color.g, Color.b, Color.a); | |
Result->MeshBuffers.push_back(Buffer); | |
} | |
for (uint i = 0; i < Node->mNumChildren; ++ i) | |
TraverseMesh(Result, Scene, Node->mChildren[i], Transformation); | |
return Result; | |
} | |
CMesh * LoadMesh(std::string const & FileName) | |
{ | |
Assimp::Importer Importer; | |
aiScene const * const Scene = Importer.ReadFile(FileName, | |
aiProcess_CalcTangentSpace | | |
aiProcess_Triangulate | | |
aiProcess_JoinIdenticalVertices | | |
aiProcess_SortByPType | |
); | |
if (! Scene) | |
{ | |
std::cerr << "Failed to import mesh file '" << FileName << "': " << Importer.GetErrorString() << std::endl; | |
return 0; | |
} | |
CMesh * Result = new CMesh; | |
TraverseMesh(Result, Scene, Scene->mRootNode, glm::mat4(1)); | |
return Result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment