X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fsceneload.cc;h=b491cf0c3129b8f16200f649b61698a3c14e692c;hb=d06c9fde2a545b95322f2566a366944e27f323b0;hp=b2b00ebedeaddb7a919b28fcfea51988580c381f;hpb=b7c92831285013b2a0783bccaf3d900545ebb5ba;p=laserbrain_demo diff --git a/src/sceneload.cc b/src/sceneload.cc index b2b00eb..b491cf0 100644 --- a/src/sceneload.cc +++ b/src/sceneload.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -13,14 +14,21 @@ #include #include "scene.h" #include "objmesh.h" +#include "datamap.h" +#include "logger.h" -static bool load_material(Material *mat, const aiMaterial *aimat); -static SceneNode *load_node(const aiScene *aiscn, const aiNode *ainode); -static Mesh *load_mesh(const aiScene *aiscn, const aiMesh *aimesh); +static bool load_material(Scene *scn, Material *mat, const aiMaterial *aimat); +static SceneNode *load_node(Scene *scn, const aiScene *aiscn, unsigned int flags, const aiNode *ainode); +static Mesh *load_mesh(Scene *scn, const aiScene *aiscn, unsigned int flags, const aiMesh *aimesh); +/*static const char *mprop_semantic(int x); +static int count_textures(const aiMaterial *aimat);*/ +static int assimp_textype(aiTextureType type); +static const char *assimp_textypestr(aiTextureType type); + +static Mat4 assimp_matrix(const aiMatrix4x4 &aim); /*static Vec3 assimp_vector(const aiVector3D &v); static Quat assimp_quat(const aiQuaternion &q); -static Mat4 assimp_matrix(const aiMatrix4x4 &aim); static long assimp_time(const aiAnimation *anim, double aitime); static void print_hierarchy(const aiNode *node); */ @@ -28,31 +36,39 @@ static void print_hierarchy(const aiNode *node); static std::map node_by_name; static std::map mesh_by_aimesh; -bool Scene::load(const char *fname) +bool Scene::load(const char *fname, unsigned int flags) { unsigned int ppflags = aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType | + aiProcess_GenUVCoords | + //aiProcess_PreTransformVertices | aiProcess_TransformUVCoords; + if(flags & SCNLOAD_FLIPTEX) { + ppflags |= aiProcess_FlipUVs; + } + + info_log("Loading scene file: %s\n", fname); + const aiScene *aiscn = aiImportFile(fname, ppflags); if(!aiscn) { - fprintf(stderr, "failed to load scene file: %s\n", fname); + error_log("failed to load scene file: %s\n", fname); return false; } - /* + // assimp adds its own root node, which might have transformations Vec3 root_pos, root_scaling(1.0, 1.0, 1.0); Quat root_rot; if(aiscn->mRootNode) { Mat4 root_matrix = assimp_matrix(aiscn->mRootNode->mTransformation); root_pos = root_matrix.get_translation(); - root_rot = root_matrix.get_rotation_quat(); + root_rot = root_matrix.get_rotation(); root_scaling = root_matrix.get_scaling(); - }*/ + } // load all meshes for(unsigned int i=0; imNumMeshes; i++) { @@ -61,52 +77,57 @@ bool Scene::load(const char *fname) switch(aimesh->mPrimitiveTypes) { case aiPrimitiveType_TRIANGLE: - if((mesh = load_mesh(aiscn, aimesh))) { + if((mesh = load_mesh(this, aiscn, flags, aimesh))) { mesh_by_aimesh[aimesh] = mesh; meshes.push_back(mesh); } break; default: - fprintf(stderr, "unsupported primitive type: %u\n", aimesh->mPrimitiveTypes); + error_log("unsupported primitive type: %u\n", aimesh->mPrimitiveTypes); break; } } - SceneNode *root = new SceneNode; + if(!nodes) { + nodes = new SceneNode; + nodes->scene = this; + nodes->set_name("root"); + nodes->set_position(root_pos); + nodes->set_rotation(root_rot); + nodes->set_scaling(root_scaling); + } // load all the nodes recursively for(unsigned int i=0; imRootNode->mNumChildren; i++) { - SceneNode *node = load_node(aiscn, aiscn->mRootNode->mChildren[i]); + SceneNode *node = load_node(this, aiscn, flags, aiscn->mRootNode->mChildren[i]); if(node) { - root->add_child(node); + nodes->add_child(node); } } - int nnodes = root->get_num_children(); - if(nnodes <= 0) { - delete root; - } else if(nnodes == 1) { - nodes = root->get_child(0); - root->remove_child(nodes); - delete root; - } else { - nodes = root; - } - node_by_name.clear(); mesh_by_aimesh.clear(); aiReleaseImport(aiscn); - printf("loaded scene file: %s, %d meshes\n", fname, (int)meshes.size()); + info_log("loaded scene file: %s, %d meshes\n", fname, (int)meshes.size()); + nodes->update(0); return true; } -static bool load_material(Material *mat, const aiMaterial *aimat) +static bool load_material(Scene *scn, Material *mat, const aiMaterial *aimat) { + aiString name; aiColor4D aicol; float shin, shin_str; + if(aiGetMaterialString(aimat, AI_MATKEY_NAME, &name) == 0) { + mat->name = name.data; + } else { + mat->name = "unknown"; + } + //info_log("load_material: %s\n", mat->name.c_str()); + if(aiGetMaterialColor(aimat, AI_MATKEY_COLOR_DIFFUSE, &aicol) == 0) { mat->diffuse = Vec3(aicol[0], aicol[1], aicol[2]); } @@ -123,59 +144,85 @@ static bool load_material(Material *mat, const aiMaterial *aimat) mat->shininess = shin * shin_str * 0.0001 * 128.0; } - /* // load textures - struct { int type; aiTextureType aitype; } textypes[] = { - {TEX_DIFFUSE, aiTextureType_DIFFUSE}, - {TEX_NORMAL, aiTextureType_NORMALS}, - {TEX_SPECULAR, aiTextureType_SPECULAR} - }; - - for(size_t i=0; itex[textypes[i].type] = texset.get(fname); + int textype = assimp_textype(aitype); + info_log("loading %s texture: %s\n", assimp_textypestr(aitype), fname); + + Texture *tex = scn->texset->get_texture(fname, TEX_2D); + assert(tex); + mat->textures.push_back(tex); + + if(textype != MTL_TEX_UNKNOWN && !mat->stdtex[textype]) { + mat->stdtex[textype] = tex; } } } - */ return true; } -static SceneNode *load_node(const aiScene *aiscn, const aiNode *ainode) +static SceneNode *load_node(Scene *scn, const aiScene *aiscn, unsigned int flags, const aiNode *ainode) { SceneNode *node = new SceneNode; node->set_name(ainode->mName.data); + // transformation + Mat4 matrix = assimp_matrix(ainode->mTransformation); + Vec3 pos = matrix.get_translation(); + Quat rot = matrix.get_rotation(); + Vec3 scale = matrix.get_scaling(); + + node->set_position(pos); + node->set_rotation(rot); + node->set_scaling(scale); + node->dbg_xform = matrix; + + // meshes for(unsigned int i=0; imNumMeshes; i++) { - aiMesh *aimesh = aiscn->mMeshes[ainode->mMeshes[0]]; + aiMesh *aimesh = aiscn->mMeshes[ainode->mMeshes[i]]; Mesh *mesh = mesh_by_aimesh[aimesh]; if(mesh) { ObjMesh *obj = new ObjMesh; + obj->set_name(mesh->get_name()); obj->mesh = mesh; // also grab the material of this mesh - load_material(&obj->mtl, aiscn->mMaterials[aimesh->mMaterialIndex]); + load_material(scn, &obj->mtl, aiscn->mMaterials[aimesh->mMaterialIndex]); node->add_object(obj); + scn->objects.push_back(obj); } } /* recurse to all children */ for(unsigned int i=0; imNumChildren; i++) { - SceneNode *child = load_node(aiscn, ainode->mChildren[i]); + SceneNode *child = load_node(scn, aiscn, flags, ainode->mChildren[i]); if(child) { node->add_child(child); } @@ -185,9 +232,10 @@ static SceneNode *load_node(const aiScene *aiscn, const aiNode *ainode) return node; } -static Mesh *load_mesh(const aiScene *aiscn, const aiMesh *aimesh) +static Mesh *load_mesh(Scene *scn, const aiScene *aiscn, unsigned int flags, const aiMesh *aimesh) { Mesh *mesh = new Mesh; + mesh->set_name(aimesh->mName.data); int num_verts = aimesh->mNumVertices; int num_faces = aimesh->mNumFaces; @@ -203,73 +251,83 @@ static Mesh *load_mesh(const aiScene *aiscn, const aiMesh *aimesh) if(aimesh->mTextureCoords[0]) { mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 3, num_verts, (float*)aimesh->mTextureCoords[0]); } + if(aimesh->mTextureCoords[1]) { + mesh->set_attrib_data(MESH_ATTR_TEXCOORD2, 3, num_verts, (float*)aimesh->mTextureCoords[1]); + } - unsigned int *iptr = mesh->set_index_data(num_faces * 3); - for(int i=0; imFaces[i].mIndices[j]; + if(flags & SCNLOAD_FLIPYZ) { + Vec3 *vptr = (Vec3*)mesh->get_attrib_data(MESH_ATTR_VERTEX); + for(int i=0; ixzy(); + ++vptr; + } + + Vec3 *nptr = (Vec3*)mesh->get_attrib_data(MESH_ATTR_NORMAL); + for(int i=0; ixzy(); + ++nptr; + } + + Vec3 *tptr = (Vec3*)mesh->get_attrib_data(MESH_ATTR_TANGENT); + for(int i=0; ixzy(); + ++tptr; } } + unsigned int *iptr = mesh->set_index_data(num_faces * 3); + for(int i=0; imFaces[i].mIndices[0]; + iptr[1] = aimesh->mFaces[i].mIndices[flags & SCNLOAD_FLIPYZ ? 2 : 1]; + iptr[2] = aimesh->mFaces[i].mIndices[flags & SCNLOAD_FLIPYZ ? 1 : 2]; + iptr += 3; + } return mesh; } -#if 0 -static Vec3 assimp_vector(const aiVector3D &v) +static int assimp_textype(aiTextureType type) { - return Vec3(v[0], v[1], v[2]); + switch(type) { + case aiTextureType_DIFFUSE: + return MTL_TEX_DIFFUSE; + case aiTextureType_SPECULAR: + return MTL_TEX_SPECULAR; + case aiTextureType_NORMALS: + return MTL_TEX_NORMALMAP; + case aiTextureType_LIGHTMAP: + case aiTextureType_EMISSIVE: + return MTL_TEX_LIGHTMAP; + case aiTextureType_REFLECTION: + return MTL_TEX_ENVMAP; + default: + break; + } + return MTL_TEX_UNKNOWN; } -static Quat assimp_quat(const aiQuaternion &q) +static const char *assimp_textypestr(aiTextureType type) { - return Quat(q.x, q.y, q.z, q.w); + switch(type) { + case aiTextureType_DIFFUSE: + return "diffuse"; + case aiTextureType_SPECULAR: + return "specular"; + case aiTextureType_NORMALS: + return "normalmap"; + case aiTextureType_LIGHTMAP: + case aiTextureType_EMISSIVE: + return "lightmap"; + case aiTextureType_REFLECTION: + return "envmap"; + default: + break; + } + return "unknown"; } static Mat4 assimp_matrix(const aiMatrix4x4 &aim) { Mat4 m; memcpy(m[0], &aim, 16 * sizeof(float)); - m.transpose(); - return m; -} - -/* convert an assimp keyframe time (ticks) into milliseconds */ -static long assimp_time(const aiAnimation *anim, double aitime) -{ - double sec; - if(anim->mTicksPerSecond < 1e-6) { - // assume time is in frames? - sec = aitime / 30.0; - } else { - sec = aitime / anim->mTicksPerSecond; - } - return (long)(sec * 1000.0); -} - -static void print_hierarchy(const aiNode *node) -{ - static int lvl; - static int lvlopen[256]; - - for(int i=0; i= lvl - 1 ? '+' : '|'); - } else { - putchar(i >= lvl - 1 ? '+' : ' '); - } - } - printf("- \"%s\"\n", node->mName.data); - - lvlopen[lvl] = 1; - - lvl++; - for(unsigned int i=0; imNumChildren; i++) { - if(i == node->mNumChildren - 1) { - lvlopen[lvl - 1] = 0; - } - print_hierarchy(node->mChildren[i]); - } - lvl--; + return transpose(m); } -#endif /* 0 */