Commits

Anonymous committed d9f9de7

new scene builder (with real scene graph)

  • Participants
  • Parent commits 1ea1483

Comments (0)

Files changed (3)

File media/gray.material

         {
 			//cull_hardware none
             lightning on
-			shading phong
+			shading gouraud
             ambient 0.5 0.5 0.5
             diffuse 0.5 0.5 0.5
         }

File ogre-lib3ds/Test3DSViewerApp.cpp

 
 static int  log_level = LIB3DS_LOG_INFO;
 
-static long
-fileio_seek_func(void *self, long offset, Lib3dsIoSeek origin) {
-    FILE *f = (FILE*)self;
-    int o;
-    switch (origin) {
-        case LIB3DS_SEEK_SET:
-            o = SEEK_SET;
-            break;
-
-        case LIB3DS_SEEK_CUR:
-            o = SEEK_CUR;
-            break;
-
-        case LIB3DS_SEEK_END:
-            o = SEEK_END;
-            break;
-    }
-    return (fseek(f, offset, o));
-}
-
-
-static long
-fileio_tell_func(void *self) {
-    FILE *f = (FILE*)self;
-    return(ftell(f));
-}
-
-
-static size_t
-fileio_read_func(void *self, void *buffer, size_t size) {
-    FILE *f = (FILE*)self;
-    return (fread(buffer, 1, size, f));
-}
-
-
-static size_t
-fileio_write_func(void *self, const void *buffer, size_t size) {
-    FILE *f = (FILE*)self;
-    return (fwrite(buffer, 1, size, f));
-}
-
-
-static void 
-fileio_log_func(void *self, Lib3dsLogLevel level, int indent, const char *msg)
-{
-    static const char * level_str[] = {
-        "ERROR", "WARN", "INFO", "DEBUG"
-    };
-    if (log_level >=  level) {
-        int i;
-        printf("%5s : ", level_str[level]);
-        for (i = 1; i < indent; ++i) printf("\t");
-        printf("%s\n", msg);
-    }
-}
-
-
-
-
-
 
 Test3DSViewerApp::Test3DSViewerApp(void)
 :mDummyCnt(0)
 void Test3DSViewerApp::_build3dsModel()
 {
     SceneNode *modelNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("3ds model");
-   
-    m3dsFile =  lib3ds_file_open("../media/3ds/indochine.3DS");
+ 
+    //m3dsFile =  lib3ds_file_open("../media/3ds/test3.3DS");
+    //m3dsFile =  lib3ds_file_open("../media/3ds/indochine.3DS");
     //m3dsFile =  lib3ds_file_open("../media/3ds/monaco.3DS");
-    //m3dsFile =  lib3ds_file_open("../media/3ds/amphimath2.3DS");
+    m3dsFile =  lib3ds_file_open("../media/3ds/amphimath2.3DS");
     //m3dsFile =  lib3ds_file_open("../media/3ds/Modern-home-interior1.3DS");
     if (!m3dsFile->nodes)
         lib3ds_file_create_nodes_for_meshes(m3dsFile);
 
     lib3ds_file_eval(m3dsFile, 0);
 
-    _buildSubtree( m3dsFile->nodes, "/", modelNode);
+    _createMeshesFrom3dsFile(m3dsFile);
+    _buildSceneFromNode(m3dsFile->nodes, modelNode, "/");
+   
+    //_buildSubtree( m3dsFile->nodes, "/", modelNode);
 
-    //modelNode->scale(0.1, 0.1, 0.1);
+    modelNode->scale(0.1, 0.1, 0.1);
     modelNode->pitch(Degree(-90));
 
     lib3ds_file_free(m3dsFile);
 
             Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*) p;
 
+
+            //// node params
             m3dsBuildLog->logMessage(boost::str(boost::format("building new node (%d) : %s") % mNodeCnt % fullName));
 
             SceneNode *newNode = _parentNode->createChildSceneNode(fullName + " Node");
-            //newNode->setPosition(n->pivot[0], n->pivot[1], n->pivot[2]);
+
+
+            //m3dsBuildLog->logMessage("pivot : " + StringConverter::toString(Vector3(n->pivot[0], n->pivot[1], n->pivot[2])));
+            //
+            //Matrix4 M;
+            //for(int i=0 ; i<4 ; ++i)
+            //    for(int j=0 ; j<4 ; ++j)
+            //        M[i][j] = n->base.matrix[j][i];
+
+
+            //m3dsBuildLog->logMessage("base matrix: " + StringConverter::toString(M));
+            //
+            //Quaternion q(n->rot[0], n->rot[1], n->rot[2], n->rot[3]);
+
+            //m3dsBuildLog->logMessage("rotation : " + StringConverter::toString(q));
+
+            //Vector3 pos(n->pos);
+
+            //m3dsBuildLog->logMessage("position : " + StringConverter::toString(pos));
+
+
 
             Lib3dsMesh *mesh = lib3ds_file_mesh_for_node(m3dsFile, (Lib3dsNode*)n);
             
 
                     newNode->attachObject(ent);
                 }
-                
             }
             
             _buildSubtree(p->childs, fullName, newNode);
         //int i;
 
         lib3ds_matrix_copy(M, node->base.matrix);
-        lib3ds_matrix_translate(M, -node->pivot[0], -node->pivot[1], -node->pivot[2]);
+        //lib3ds_matrix_translate(M, -node->pivot[0], -node->pivot[1], -node->pivot[2]);
         lib3ds_matrix_copy(inv_matrix, mesh->matrix);
         lib3ds_matrix_inv(inv_matrix);
         lib3ds_matrix_mult(M, M, inv_matrix);
             }
         }
 
-
-
         newObject->end();
         free(normals); 
     //}
         newMesh.setNull();
 
     return newMesh;
-}
+}
+//------------------------------------------------------------------------------
+void Test3DSViewerApp::_createMeshesFrom3dsFile(Lib3dsFile *_3dsfile)
+{
+    for(int i=0 ; i<_3dsfile->nmeshes ; ++i)
+    {
+        Lib3dsMesh *mesh = _3dsfile->meshes[i];
+        ManualObject *newObject = mSceneMgr->createManualObject(mesh->name);
+
+
+
+        float (*orig_vertices)[3];
+        orig_vertices = (float(*)[3])malloc(sizeof(float) * 3 * mesh->nvertices);
+        memcpy(orig_vertices, mesh->vertices, sizeof(float) * 3 * mesh->nvertices);
+
+        // transform mesh back to origin
+        float inv_matrix[4][4], M[4][4];
+        float tmp[3];
+
+        lib3ds_matrix_copy(inv_matrix, mesh->matrix);
+        lib3ds_matrix_inv(inv_matrix);
+        lib3ds_matrix_copy(M, inv_matrix);
+
+        for (int i = 0; i < mesh->nvertices; ++i) {
+            lib3ds_vector_transform(tmp, M, mesh->vertices[i]);
+            lib3ds_vector_copy(mesh->vertices[i], tmp);
+        }
+
+        // normals
+        float (*normals)[3] = (float(*)[3])malloc(sizeof(float) * 9 * mesh->nfaces);
+        lib3ds_mesh_calculate_vertex_normals(mesh, normals);
+
+
+        // create an ogre object for easy OgreMesh conversion
+        // Gray = default material
+        // TODO: better default material
+        newObject->begin("Gray", RenderOperation::OT_TRIANGLE_LIST);
+
+        int idx = 0;
+        // foreach tri
+        for(int tri_idx = 0 ; tri_idx < mesh->nfaces ; ++tri_idx)
+        {
+
+            // foreach vertex in tri
+            for(int j=0 ; j<3 ; ++j)
+            {
+                Vector3 pos, norm;
+                Vector2 tc;
+
+                pos = Vector3(mesh->vertices[mesh->faces[tri_idx].index[j]]);
+                newObject->position(pos);
+
+                if(mesh->texcos)
+                    tc = Vector2(mesh->texcos[mesh->faces[tri_idx].index[j]]);
+                norm = Vector3(normals[idx]);
+
+
+                newObject->normal(norm);
+
+                newObject->index(idx++);
+            }
+        }
+
+        newObject->end();
+        free(normals); 
+        //}
+        //restore mesh for future use
+        memcpy(mesh->vertices, orig_vertices, sizeof(float) * 3 * mesh->nvertices);
+        free(orig_vertices);
+
+
+        MeshPtr newMesh;
+        if(idx)
+        {
+            // create ogre mesh from manualobject
+            newMesh = newObject->convertToMesh(mesh->name);
+            //newMesh->buildTangentVectors();
+            
+        }
+        else
+            newMesh.setNull();
+
+        mSceneMgr->destroyManualObject(newObject);
+        mCenteredMeshes[mesh->name] = newMesh;
+    }
+}
+//------------------------------------------------------------------------------
+void Test3DSViewerApp::_buildSceneFromNode(Lib3dsNode *_3dsNode, SceneNode *_parentNode, const std::string &_basename)
+{
+    boost::format fullNameFmt("%s/%06d%s");
+    Lib3dsNode *p;
+    for(p = _3dsNode ; p ; p=p->next)
+    {
+
+        if (p->type == LIB3DS_NODE_MESH_INSTANCE) 
+        {
+            mNodeCnt++;
+            fullNameFmt % _basename % p->node_id % p->name;
+            std::string fullName = fullNameFmt.str();
+
+            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*) p;
+
+            m3dsBuildLog->logMessage(boost::str(boost::format("building new node (%d) : %s") % mNodeCnt % fullName));
+
+            SceneNode *newNode = _parentNode->createChildSceneNode(fullName + " Node");
+            
+            newNode->translate(-n->pivot[0], -n->pivot[1], -n->pivot[2]);
+            
+            newNode->rotate(Quaternion(n->rot[3], n->rot[0], n->rot[1], n->rot[2]));
+            newNode->translate(n->pos[0], n->pos[1], n->pos[2]);
+            newNode->setScale(n->scl[0], n->scl[1], n->scl[2]);
+
+            
+            Lib3dsMesh *mesh = lib3ds_file_mesh_for_node(m3dsFile, (Lib3dsNode*)n);
+            if (mesh && mesh->name)
+            {
+                std::string meshName = mesh->name;
+
+                MeshPtr meshToAdd = mCenteredMeshes[meshName];
+                if(! meshToAdd.isNull())
+                {
+                    m3dsBuildLog->logMessage(boost::str(boost::format("attaching %s to node %s")% mCenteredMeshes[meshName]->getName() % fullName));
+                    Entity *ent = mSceneMgr->createEntity(fullName+" Ent", mCenteredMeshes[meshName]->getName());
+                    newNode->attachObject(ent);
+                }
+            }
+    
+            /*Matrix4 M;
+            M.makeTransform()*/
+            _buildSceneFromNode(p->childs, newNode, fullName);
+        }
+        //else if(p->type == LIB3DS_NODE_OMNILIGHT)
+        //{
+        //    //...
+        //}
+    }
+}
+//------------------------------------------------------------------------------

File ogre-lib3ds/Test3DSViewerApp.h

 #include <Ogre.h>
 #include "ExampleApplication.h"
 
-extern "C"{
-#include "lib3ds.h"
-};
-
+#include <lib3ds.h>
+    
 
 using namespace Ogre;
 
 
     void _dumpNode(Log*, Lib3dsNode*, int, std::string);
 
+    void _createMeshesFrom3dsFile(Lib3dsFile*);
+    void _buildSceneFromNode(Lib3dsNode*, SceneNode*
+                            ,const std::string&);
+
 protected:
     FILE *mFile;
     Lib3dsFile *m3dsFile;
 
     Log *m3dsBuildLog;
     int mDummyCnt, mNodeCnt;
+
+    std::map<std::string, MeshPtr> mCenteredMeshes;
+
 };