textures, lightmaps, hardcoded texture hack for testing
[laserbrain_demo] / src / sceneload.cc
index 5179e4a..865a4c8 100644 (file)
 #include <assimp/quaternion.h>
 #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 const char *mprop_semantic(int x);
+static int count_textures(const aiMaterial *aimat);*/
+static int assimp_textype(aiTextureType type);
 
 /*static Vec3 assimp_vector(const aiVector3D &v);
 static Quat assimp_quat(const aiQuaternion &q);
@@ -65,7 +69,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);
                        }
@@ -81,7 +85,7 @@ bool Scene::load(const char *fname, unsigned int flags)
 
        // load all the nodes recursively
        for(unsigned int i=0; i<aiscn->mRootNode->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);
                }
@@ -106,11 +110,19 @@ bool Scene::load(const char *fname, unsigned int flags)
        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,14 +139,51 @@ 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}
-       };
 
+       const int num_tex_types = aiTextureType_UNKNOWN + 1;
+       for(int i=0; i<num_tex_types; i++) {
+               aiTextureType aitype = (aiTextureType)i;
+               int count = aiGetMaterialTextureCount(aimat, aitype);
+
+               for(int j=0; j<count; j++) {
+                       aiString aipath;
+                       if(aiGetMaterialTexture(aimat, aitype, j, &aipath) != 0) {
+                               continue;
+                       }
+
+                       char *fname;
+                       int nsize = datamap_path_size(aipath.data);
+                       if(nsize) {
+                               fname = new char[nsize];
+                               datamap_lookup(aipath.data, fname, nsize);
+                       } else {
+                               fname = new char[strlen(aipath.data) + 1];
+                               char *dptr = fname;
+                               char *sptr = aipath.data;
+                               do {
+                                       *dptr++ = *sptr == '\\' ? '/' : *sptr;
+                               } while(*sptr++);
+                       }
+
+                       Texture *tex = scn->texset->get(fname);
+                       if(!tex) {
+                               fprintf(stderr, "failed to load texture: %s\n", fname);
+                               delete [] fname;
+                               continue;
+                       }
+                       delete [] fname;
+
+                       mat->textures.push_back(tex);
+
+                       int textype = assimp_textype(aitype);
+                       if(textype != MTL_TEX_UNKNOWN && !mat->stdtex[textype]) {
+                               mat->stdtex[textype] = tex;
+                       }
+               }
+       }
+
+       /*
        for(size_t i=0; i<sizeof textypes / sizeof *textypes; i++) {
                aiString aipath;
 
@@ -158,7 +207,7 @@ static bool load_material(Material *mat, const aiMaterial *aimat)
        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);
@@ -171,15 +220,16 @@ static SceneNode *load_node(const aiScene *aiscn, unsigned int flags, const aiNo
                        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; i<ainode->mNumChildren; 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 +239,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 +257,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);
@@ -239,62 +292,21 @@ static Mesh *load_mesh(const aiScene *aiscn, unsigned int flags, const aiMesh *a
        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]);
-}
-
-static Quat assimp_quat(const aiQuaternion &q)
-{
-       return Quat(q.x, q.y, q.z, q.w);
-}
-
-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; i++) {
-               putchar(' ');
-               if(lvlopen[i]) {
-                       putchar(i >= lvl - 1 ? '+' : '|');
-               } else {
-                       putchar(i >= lvl - 1 ? '+' : ' ');
-               }
-       }
-       printf("- \"%s\"\n", node->mName.data);
-
-       lvlopen[lvl] = 1;
-
-       lvl++;
-       for(unsigned int i=0; i<node->mNumChildren; i++) {
-               if(i == node->mNumChildren - 1) {
-                       lvlopen[lvl - 1] = 0;
-               }
-               print_hierarchy(node->mChildren[i]);
+       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:
+               return MTL_TEX_LIGHTMAP;
+       case aiTextureType_REFLECTION:
+               return MTL_TEX_ENVMAP;
+       default:
+               break;
        }
-       lvl--;
+       return MTL_TEX_UNKNOWN;
 }
-#endif /* 0 */