//----------------------------------------------------------------------------- // ctmLoad() //----------------------------------------------------------------------------- CTMEXPORT void CTMCALL ctmLoad(CTMcontext aContext, const char * aFileName) { _CTMcontext * self = (_CTMcontext *) aContext; FILE * f; if(!self) return; // You are only allowed to load data in import mode if(self->mMode != CTM_IMPORT) { self->mError = CTM_INVALID_OPERATION; return; } // Open file stream f = fopen(aFileName, "rb"); if(!f) { self->mError = CTM_FILE_ERROR; return; } // Load the file ctmLoadCustom(self, _ctmDefaultRead, (void *) f); // Close file stream fclose(f); }
/* Import OpenCTM file */ int dlImportOCTM( dlObject* object, const char *file, int bAnimated ) { FILE *f; CTMcontext context; CTMuint vertCount, triCount, uvCount, attribCount; const CTMuint *indices; const CTMfloat *vertices, *normals, *coords, *attribs; CTMenum error; unsigned int i, i2; /* the god of iterators, and his child */ const char *textureFilename, *comment, *attribName; char *texturePath = NULL; LOGINFOP("Attempt to load: %s", file); /* obiviously we need a import context * HEY! Maybe CTM_EXPORT would work!? */ context = ctmNewContext( CTM_IMPORT ); /* check if we fail at context creation */ if(!context) { LOGERR("I suck at context creation"); RET("%d", RETURN_FAIL); return( RETURN_FAIL ); } /* Yush! Open the file */ f = fopen( (char*)file, "rb" ); if(!f) { LOGERRP("File: %s, could not open", file); RET("%d", RETURN_FAIL); return( RETURN_FAIL ); } /* I think, i fell love with this API */ ctmLoadCustom( context, (CTMreadfn)readOCTMFile, f ); /* What's the magic word to close it? */ fclose(f); /* lets just hope that it does not have any errors */ if((error = ctmGetError(context)) != CTM_NONE) { /* Go! Pikachu! Use the printf! */ LOGERRP("%s", ctmErrorString( error )); ctmFreeContext(context); RET("%d", RETURN_FAIL); return( RETURN_FAIL ); } /* so far all good, lets do this! */ vertCount = ctmGetInteger( context, CTM_VERTEX_COUNT ); vertices = ctmGetFloatArray( context, CTM_VERTICES ); triCount = ctmGetInteger( context, CTM_TRIANGLE_COUNT ); indices = ctmGetIntegerArray( context, CTM_INDICES ); uvCount = ctmGetInteger( context, CTM_UV_MAP_COUNT ); attribCount = ctmGetInteger( context, CTM_ATTRIB_MAP_COUNT ); comment = ctmGetString( context, CTM_FILE_COMMENT ); if( comment ) dlPuts(comment); /* ok, we go the info.. * now.. how to deal with it? */ dlResetVertexBuffer( object->vbo, vertCount ); dlResetIndexBuffer( object->ibo, triCount * 3 ); /* indices */ i = 0; for(; i != triCount * 3; ++i) dlInsertIndex( object->ibo, indices[i] ); /* vertices */ i = 0; for(; i != vertCount; ++i) dlInsertVertex( object->vbo, vertices[ i * 3 ], vertices[ i * 3 + 1 ], vertices[ i * 3 + 2 ] ); /* texture coords */ i = 0; while( i != uvCount ) { coords = ctmGetFloatArray( context, CTM_UV_MAP_1 + i ); dlResetCoordBuffer( object->vbo, i, vertCount ); /* get texture filename */ textureFilename = ctmGetUVMapString( context, CTM_UV_MAP_1 + i, CTM_FILE_NAME ); if(!textureFilename) textureFilename = ctmGetUVMapString( context, CTM_UV_MAP_1 + i, CTM_NAME ); /* check path */ if(textureFilename) texturePath = dlImportTexturePath( textureFilename, file ); /* load if exists */ if(texturePath) { if(object->material) dlFreeMaterial(object->material); object->material = dlNewMaterialFromImage( texturePath, SOIL_FLAG_DEFAULTS ); free( texturePath ); } i2 = 0; for(; i2 != vertCount; ++i2) { dlInsertCoord( object->vbo, i, coords[ i2 * 2 ], coords[ i2 * 2 + 1 ] ); } ++i; } /* normals */ if(ctmGetInteger(context, CTM_HAS_NORMALS) == CTM_TRUE) { dlResetNormalBuffer( object->vbo, vertCount ); normals = ctmGetFloatArray( context, CTM_NORMALS ); i = 0; for(; i != vertCount; ++i) dlInsertNormal( object->vbo, normals[ i * 3 ], normals[ i * 3 + 1 ], normals[ i * 3 + 2 ] ); } /* custom attribs, only for vertex colors atm */ i = 0; for(; i != attribCount; ++i) { attribName = ctmGetAttribMapString( context, CTM_ATTRIB_MAP_1 + i, CTM_NAME ); attribs = ctmGetFloatArray( context, CTM_ATTRIB_MAP_1 + i ); if(attribName) LOGINFO(attribName); #if VERTEX_COLOR if( strcmp( attribName, COLOR_ATTRIB ) == 0 ) { dlResetColorBuffer( object->vbo, vertCount ); i2 = 0; for(; i2 != vertCount; ++i2) dlInsertColor( object->vbo, attribs[ i2 * 4 ], attribs[ i2 * 4 + 1 ], attribs[ i2 * 4 + 2 ], attribs[ i2 * 4 + 3 ] ); } #endif } /* this is now GL_TRIANGLES object * maybe add tristripper option? */ object->primitive_type = GL_TRIANGLES; /* free the bird */ ctmFreeContext(context); RET("%d", RETURN_OK); return( RETURN_OK ); }
int main(int argc, const char *argv[]) { if(argc != 3) { std::cout << "Usage: #> ./osg_openctm_sqlite inputdb row\n"; std::cout << "* draw an openctm mesh stored as a row in an sqlite db with osg\n"; return 0; } Kompex::SQLiteDatabase *pDatabase = new Kompex::SQLiteDatabase(argv[1],SQLITE_OPEN_READWRITE,0); Kompex::SQLiteStatement *pStmt = new Kompex::SQLiteStatement(pDatabase); int cRow = 0; int rowId = 0; int dbRow = 2; bool isEmpty = false; std::string rowFileKey; pStmt->Sql("SELECT rowid,filekey,empty FROM grid_mesh;"); while(pStmt->FetchRow()) { if(cRow == dbRow) { // row file key rowId = pStmt->GetColumnInt(0); rowFileKey = pStmt->GetColumnString(1); isEmpty = pStmt->GetColumnBool(2); } cRow++; } pStmt->FreeQuery(); Kompex::SQLiteBlob *pKompexBlob; if(!isEmpty) { // read in ctm blob to memory pKompexBlob=new Kompex::SQLiteBlob(pDatabase,"main","grid_mesh","mesh",1); size = pKompexBlob->GetBlobSize(); memblock = new char[size]; pKompexBlob->ReadBlob(memblock,size); delete pKompexBlob; std::cout << "# Read in " << rowFileKey << " (" << size << " bytes)\n"; // uncompress ctm CTMcontext context; CTMuint vertCount, triCount; CTMuint const* indices; CTMfloat const * vertices; context = ctmNewContext(CTM_IMPORT); g_pos = 0; ctmLoadCustom(context,ctmReadBlob,(void*)memblock); if(ctmGetError(context) == CTM_NONE) { // access the mesh data vertCount = ctmGetInteger(context, CTM_VERTEX_COUNT); vertices = ctmGetFloatArray(context, CTM_VERTICES); triCount = ctmGetInteger(context, CTM_TRIANGLE_COUNT); indices = ctmGetIntegerArray(context, CTM_INDICES); std::cout << "# Mesh has " << vertCount << " vertices\n"; std::cout << "# Mesh has " << triCount << " triangles\n"; // build up openscenegraph geometry osg::ref_ptr<osg::Vec3Array> listVxArray = new osg::Vec3Array(vertCount); unsigned int vxIdx=0; for(int i=0; i < listVxArray->size(); i++) { osg::Vec3 vertex; vertex.x() = vertices[vxIdx]; vxIdx++; vertex.y() = vertices[vxIdx]; vxIdx++; vertex.z() = vertices[vxIdx]; vxIdx++; listVxArray->at(i) = vertex; } osg::ref_ptr<osg::DrawElementsUInt> listIdxs = new osg::DrawElementsUInt(GL_TRIANGLES,triCount*3); for(int i=0; i < listIdxs->size(); i++) { listIdxs->at(i) = indices[i]; } osg::ref_ptr<osg::Geometry> geomMesh = new osg::Geometry; geomMesh->setVertexArray(listVxArray.get()); geomMesh->setNormalArray(listVxArray.get()); geomMesh->addPrimitiveSet(listIdxs.get()); osg::ref_ptr<osg::Geode> geodeMesh = new osg::Geode; geodeMesh->addDrawable(geomMesh.get()); osg::ref_ptr<osg::Group> groupRoot = new osg::Group; groupRoot->addChild(geodeMesh.get()); // free ctm memory ctmFreeContext(context); // start viewer osgViewer::Viewer viewer; viewer.setThreadingModel(osgViewer::ViewerBase::SingleThreaded); viewer.setUpViewInWindow(100,100,800,480); viewer.setSceneData(groupRoot.get()); return viewer.run(); } else { std::cout << "# Fatal error reading in mesh file! Exiting...\n"; ctmFreeContext(context); return 0; } // // stuff delete[] memblock; // delete pStmt; // delete pDatabase; return 0; } else { std::cout << "# Row " << rowId << " was empty! Exiting...\n"; delete pStmt; delete pDatabase; return 0; } }