X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fsceneload.cc;h=d173538407188325231d11f922ae0141801346b4;hb=572bf1ef8d54ef5a7cba7cdf38515cb16c4c312c;hp=5179e4ac616b646af291ae37fe551aadb5159a45;hpb=ab9fd0ac34f8107ff8067607fad229d08b1c3935;p=laserbrain_demo diff --git a/src/sceneload.cc b/src/sceneload.cc index 5179e4a..d173538 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" -static bool load_material(Material *mat, const aiMaterial *aimat); -static SceneNode *load_node(const aiScene *aiscn, unsigned int flags, const aiNode *ainode); -static Mesh *load_mesh(const aiScene *aiscn, unsigned int flags, 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 void print_nodes(SceneNode *node, int lvl = 0); +/*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); */ @@ -35,28 +43,37 @@ bool Scene::load(const char *fname, unsigned int flags) aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType | - aiProcess_TransformUVCoords | aiProcess_PreTransformVertices; + aiProcess_GenUVCoords | + //aiProcess_PreTransformVertices | + aiProcess_TransformUVCoords; if(flags & SCNLOAD_FLIPTEX) { ppflags |= aiProcess_FlipUVs; } + printf("Loading scene file: %s\n", fname); + const aiScene *aiscn = aiImportFile(fname, ppflags); if(!aiscn) { fprintf(stderr, "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(); - }*/ + + printf("assimp root node: %s\n", aiscn->mRootNode->mName.data); + printf(" pos: %f %f %f\n", root_pos.x, root_pos.y, root_pos.z); + printf(" rot: %f %+f %+f %+f\n", root_rot.w, root_rot.x, root_rot.y, root_rot.z); + printf(" scaling: %f %f %f\n", root_scaling.x, root_scaling.y, root_scaling.z); + } // load all meshes for(unsigned int i=0; imNumMeshes; i++) { @@ -65,7 +82,7 @@ bool Scene::load(const char *fname, unsigned int flags) switch(aimesh->mPrimitiveTypes) { case aiPrimitiveType_TRIANGLE: - if((mesh = load_mesh(aiscn, flags, aimesh))) { + if((mesh = load_mesh(this, aiscn, flags, aimesh))) { mesh_by_aimesh[aimesh] = mesh; meshes.push_back(mesh); } @@ -77,40 +94,45 @@ bool Scene::load(const char *fname, unsigned int flags) } } - SceneNode *root = new SceneNode; + if(!nodes) { + nodes = new SceneNode; + 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, flags, 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()); + nodes->update(0); + print_nodes(nodes); 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"; + } + printf("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]); } @@ -127,59 +149,86 @@ 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); + printf("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); + + printf(" DBG(%p)\n", (void*)tex); + + if(textype != MTL_TEX_UNKNOWN && !mat->stdtex[textype]) { + mat->stdtex[textype] = tex; } } } - */ return true; } -static SceneNode *load_node(const aiScene *aiscn, unsigned int flags, 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->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, flags, ainode->mChildren[i]); + SceneNode *child = load_node(scn, aiscn, flags, ainode->mChildren[i]); if(child) { node->add_child(child); } @@ -189,7 +238,7 @@ static SceneNode *load_node(const aiScene *aiscn, unsigned int flags, const aiNo return node; } -static Mesh *load_mesh(const aiScene *aiscn, unsigned int flags, const aiMesh *aimesh) +static Mesh *load_mesh(Scene *scn, const aiScene *aiscn, unsigned int flags, const aiMesh *aimesh) { Mesh *mesh = new Mesh; @@ -207,6 +256,9 @@ static Mesh *load_mesh(const aiScene *aiscn, unsigned int flags, const aiMesh *a 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]); + } if(flags & SCNLOAD_FLIPYZ) { Vec3 *vptr = (Vec3*)mesh->get_attrib_data(MESH_ATTR_VERTEX); @@ -236,65 +288,81 @@ static Mesh *load_mesh(const aiScene *aiscn, unsigned int flags, const aiMesh *a iptr += 3; } + AABox bbox = mesh->get_aabbox(); + printf("mesh bounding box: %f %f %f -> %f %f %f\n", bbox.min.x, bbox.min.y, bbox.min.z, + bbox.max.x, bbox.max.y, bbox.max.z); + return mesh; } -#if 0 -static Vec3 assimp_vector(const aiVector3D &v) +static void print_nodes(SceneNode *node, int lvl) { - return Vec3(v[0], v[1], v[2]); -} + Vec3 pos = node->get_node_position(); + Quat rot = node->get_node_rotation(); + Vec3 scale = node->get_node_scaling(); -static Quat assimp_quat(const aiQuaternion &q) -{ - return Quat(q.x, q.y, q.z, q.w); -} + const char *type = node->get_num_objects() > 0 ? "mesh node" : "null node"; -static Mat4 assimp_matrix(const aiMatrix4x4 &aim) -{ - Mat4 m; - memcpy(m[0], &aim, 16 * sizeof(float)); - m.transpose(); - return m; + for(int i=0; iget_name(), + pos.x, pos.y, pos.z, rot.w, rot.x, rot.y, rot.z, scale.x, scale.y, scale.z); + + if(node->get_num_objects()) { + Mat4 xform = node->get_matrix(); + xform.print(stdout); + } + + int nchld = node->get_num_children(); + for(int i=0; iget_child(i), lvl + 1); + } } -/* convert an assimp keyframe time (ticks) into milliseconds */ -static long assimp_time(const aiAnimation *anim, double aitime) +static int assimp_textype(aiTextureType type) { - double sec; - if(anim->mTicksPerSecond < 1e-6) { - // assume time is in frames? - sec = aitime / 30.0; - } else { - sec = aitime / anim->mTicksPerSecond; + 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 (long)(sec * 1000.0); + return MTL_TEX_UNKNOWN; } -static void print_hierarchy(const aiNode *node) +static const char *assimp_textypestr(aiTextureType type) { - static int lvl; - static int lvlopen[256]; - - for(int i=0; i= lvl - 1 ? '+' : '|'); - } else { - putchar(i >= lvl - 1 ? '+' : ' '); - } + 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; } - printf("- \"%s\"\n", node->mName.data); - - lvlopen[lvl] = 1; + return "unknown"; +} - lvl++; - for(unsigned int i=0; imNumChildren; i++) { - if(i == node->mNumChildren - 1) { - lvlopen[lvl - 1] = 0; - } - print_hierarchy(node->mChildren[i]); - } - lvl--; +static Mat4 assimp_matrix(const aiMatrix4x4 &aim) +{ + Mat4 m; + memcpy(m[0], &aim, 16 * sizeof(float)); + return transpose(m); } -#endif /* 0 */