LptaAssimpMesh::LptaAssimpMesh( VERTEX_TYPE vertexType, const std::string &filename, const LptaRenderDevice &device) { MANAGERS managers = { *device.GetMaterialManager(), *device.GetTextureManager(), *device.GetSkinManager() }; if (SUCCESSFUL assetImporter.ReadFile(filename, IMPORT_FLAGS)) { const aiScene *scene = assetImporter.GetOrphanedScene(); try { if (!scene || !IsValidScene(*scene)) { throw LptaMeshLoadFailure("Not a valid mesh file"); } vertices = CopyMesh(vertexType, indices, skinId, scene, managers); } catch (const LptaMeshLoadFailure &loadFailure) { if (scene) { aiReleaseImport(scene); } throw loadFailure; } aiReleaseImport(scene); } else { // log error throw LptaMeshLoadFailure(assetImporter.GetErrorString()); } }
void Model_Impl::Load(CL_GraphicContext &gc, const char *filename, bool we_do_not_want_texures_on_this_object) { generate_texture_coords = !we_do_not_want_texures_on_this_object; const struct aiScene* scene = aiImportFile(filename,aiProcessPreset_TargetRealtime_MaxQuality); if (!scene) throw CL_Exception("Cannot load a model"); try { vbo_size = count_vertices(scene, scene->mRootNode); if (!vbo_size) throw CL_Exception("No vertices found in the model"); vbo_positions = CL_VertexArrayBuffer(gc, vbo_size * sizeof(CL_Vec3f), cl_usage_static_draw); vbo_normals = CL_VertexArrayBuffer(gc, vbo_size * sizeof(CL_Vec3f), cl_usage_static_draw); if (generate_texture_coords) vbo_texcoords = CL_VertexArrayBuffer(gc, vbo_size * sizeof(CL_Vec2f), cl_usage_static_draw); insert_vbo(0, scene, scene->mRootNode); }catch(...) { aiReleaseImport(scene); throw; } aiReleaseImport(scene); }
Scene * AssimpSceneLoader::load(const std::string & filename, const reflectionzeug::Variant & options, std::function<void(int, int)> /*progress*/) const { bool smoothNormals = false; // Get options const reflectionzeug::VariantMap * map = options.asMap(); if (map) { if (map->count("smoothNormals") > 0) smoothNormals = map->at("smoothNormals").value<bool>(); } // Import scene auto assimpScene = aiImportFile( filename.c_str(), aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType | (smoothNormals ? aiProcess_GenSmoothNormals : aiProcess_GenNormals)); // Check for errors if (!assimpScene) { std::cout << aiGetErrorString(); return nullptr; } // Convert scene into gloperate scene Scene * scene = convertScene(assimpScene); // Release scene aiReleaseImport(assimpScene); // Return loaded scene return scene; }
//------------------------------------------- void ofxAssimpModelLoader::clear(){ ofLog(OF_LOG_VERBOSE, "deleting gl resources"); // clear out everything. modelMeshes.clear(); pos.set(0,0,0); scale.set(1,1,1); rotAngle.clear(); rotAxis.clear(); lights.clear(); lastAnimationTime = 0; currentAnimation = 0; animationTime = 0; scale = ofPoint(1, 1, 1); if(scene){ aiReleaseImport(scene); scene = NULL; } normalizeScale = true; bUsingMaterials = true; bUsingNormals = true; bUsingTextures = true; bUsingColors = true; }
static int Delete(lua_State *L) { unsigned int i; scene_t *scene = testscene(L, 1); if(!scene) return 0; /* already deleted */ /* first, release all userdata */ #define Free(what, freefunc) do { \ if(scene->mNum##what > 0) \ { \ for(i=0; i < scene->mNum##what; i++) \ freefunc(L, scene->m##what[i]); \ } \ } while(0) Free(Meshes, freemesh); Free(Materials, freematerial); Free(Lights, freelight); Free(Textures, freetexture); Free(Cameras, freecamera); Free(Animations, freeanimation); #undef Free if(scene->mRootNode) freenode(L, scene->mRootNode); TRACE_DELETE(scene, "scene"); freeuserdata(L, scene); /* finally, release the scene */ aiReleaseImport(scene); return 0; }
void RenderCleanup(Obj3d *assets) { // free assImp scene resources aiReleaseImport(assets->getScene()); // detach assImp log aiDetachAllLogStreams(); }
int convert_anim(const char *infname) { int i, bufsz; const struct aiScene *aiscn; struct goat3d *goat; char *outfname; bufsz = output_filename(0, 0, infname, "goatanim"); outfname = alloca(bufsz); output_filename(outfname, bufsz, infname, "goatanim"); printf("converting %s -> %s\n", infname, outfname); if(!(aiscn = aiImportFile(infname, ANM_PPFLAGS))) { fprintf(stderr, "failed to import %s\n", infname); return -1; } goat = goat3d_create(); for(i=0; i<(int)aiscn->mRootNode->mNumChildren; i++) { process_node(goat, 0, aiscn->mRootNode->mChildren[i]); } for(i=0; i<aiscn->mNumAnimations; i++) { if(process_anim(goat, aiscn->mAnimations[i]) == -1) { return -1; } } goat3d_save_anim(goat, outfname); goat3d_free(goat); aiReleaseImport(aiscn); return 0; }
int main(int argc, const char **argv) { if(argc == 1) { const char *params[] = {"-p", "win32", "../../../Raw/Level/level.dae", "./"}; parseArgs(4, params); } else parseArgs(argc, argv); printf("Outputting in %s format\n", g_Endianness == LittleEndian ? "LittleEndian" : "BigEndian"); aiSetImportPropertyInteger( AI_CONFIG_PP_RVC_FLAGS, aiComponent_TANGENTS_AND_BITANGENTS | aiComponent_COLORS ); // Remove degenerates; if we don't do this, tangents & bitangents // can't be calculated for meshes with degenerate tris aiSetImportPropertyInteger( AI_CONFIG_PP_FD_REMOVE, true ); const aiScene* scene = aiImportFile( filename.c_str(), aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_GenNormals | aiProcess_RemoveComponent ); if(!scene) printf("Failed to load %s\n", filename.c_str()); else { makeDirectories(); cJSON *root = cJSON_CreateObject(); cJSON *list = cJSON_CreateArray(); cJSON_AddItemToObject(root, "scene", list); aiMatrix4x4 identity; printf("Loaded %s\n", filename.c_str()); processSceneRecursive(scene, list, identity, scene->mRootNode); printf("Done\n"); outputFinalStep(); writeJsonToFile(root, outdir + "/scene.scene"); } aiReleaseImport(scene); getchar(); return 0; }
//------------------------------------------ void ofxAssimpModelLoader::loadModel(string modelName){ // if we have a model loaded, unload the f****r. if(scene != NULL) { aiReleaseImport(scene); scene = NULL; deleteGLResources(); } // Load our new path. string filepath = ofToDataPath(modelName); ofLog(OF_LOG_VERBOSE, "loading model %s", filepath.c_str()); // only ever give us triangles. aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT ); aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, true); // aiProcess_FlipUVs is for VAR code. Not needed otherwise. Not sure why. scene = (aiScene*) aiImportFile(filepath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_OptimizeGraph | aiProcess_Triangulate | aiProcess_FlipUVs | 0 ); if(scene){ ofLog(OF_LOG_VERBOSE, "initted scene with %i meshes & %i animations", scene->mNumMeshes, scene->mNumAnimations); getBoundingBoxWithMinVector(&scene_min, &scene_max); scene_center.x = (scene_min.x + scene_max.x) / 2.0f; scene_center.y = (scene_min.y + scene_max.y) / 2.0f; scene_center.z = (scene_min.z + scene_max.z) / 2.0f; // optional normalized scaling normalizedScale = scene_max.x-scene_min.x; normalizedScale = aisgl_max(scene_max.y - scene_min.y,normalizedScale); normalizedScale = aisgl_max(scene_max.z - scene_min.z,normalizedScale); normalizedScale = 1.f / normalizedScale; normalizedScale *= ofGetWidth() / 2.0; glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); loadGLResources(); glPopClientAttrib(); glPopAttrib(); if(getAnimationCount()) ofLog(OF_LOG_VERBOSE, "scene has animations"); else { ofLog(OF_LOG_VERBOSE, "no animations"); } } }
std::shared_ptr< Mesh > MaterialFactory::createMesh( const char* meshXml ) { std::shared_ptr< Mesh > mesh = std::shared_ptr< Mesh >( new Mesh() ); m_material = std::shared_ptr< GLSLMaterial >( new GLSLMaterial() ); m_doc = new tinyxml2::XMLDocument(); if( m_doc->LoadFile( meshXml ) ) { printf("loading xml file error"); return NULL; } tinyxml2::XMLNode* child = m_doc->FirstChild(); const char* meshFile = child->ToElement()->Attribute( "file" ); int g_point_count = 0; GLuint vao; const aiScene* scene = aiImportFile (meshFile, aiProcess_Triangulate); // TRIANGLES! if (!scene) { fprintf (stderr, "ERROR: reading mesh %s\n", meshFile); return false; } glGenVertexArrays( 1, &vao ); glBindVertexArray( vao ); mesh->setVAO( vao ); g_point_count = scene->mMeshes[0]->mNumVertices; mesh->setSize( g_point_count ); for( tinyxml2::XMLElement* loopNode =child->FirstChildElement(); loopNode != NULL; loopNode=loopNode->NextSiblingElement() ) { if( strcmp( loopNode->Name() , "Material" ) == 0 ) { mesh->setMaterial( createMaterial( loopNode, scene ) ); } } aiReleaseImport( scene ); glBindVertexArray( 0 ); m_textureLocation = GL_TEXTURE0; return mesh; }
static int assimp_export_scene(lua_State *L) { luaX_checktype(L, 1, "scene", LUA_TTABLE); const char *format = luaX_checkstring(L, 2, "format"); const char *filename = luaX_checkstring(L, 3, "filename"); struct aiScene *scene = _convert_scene(L, 1); if (aiExportScene(scene, format, filename, 0)) { aiReleaseImport(scene); lua_pushboolean(L, true); // [-0,+1,-] } else { aiReleaseImport(scene); lua_pushboolean(L, false); // [-0,+1,-] lua_pushstring(L, aiGetErrorString()); // [-0,+1,e] return 2; } return 1; }
GLMesh::~GLMesh() { // Delete textures for (std::map<std::string, GLuint>::iterator i = m_mapPathToGLTex.begin(); i != m_mapPathToGLTex.end(); ++i) { glDeleteTextures(1, &i->second); } // Free scene if (m_pScene) { aiReleaseImport(m_pScene); } }
void Model_Impl::Load(GraphicContext &gc, GraphicStore *gs, const char *filename) { const struct aiScene* scene = aiImportFileExWithProperties(filename,aiProcessPreset_TargetRealtime_MaxQuality, NULL, gs->store); if (!scene) throw Exception("Cannot load a model"); try { vbo_size = count_vertices(scene, scene->mRootNode); if (!vbo_size) throw Exception("No vertices found in the model"); vbo_positions = VertexArrayVector<Vec3f>(gc, vbo_size); vbo_normals = VertexArrayVector<Vec3f>(gc, vbo_size); insert_vbo(gc, 0, scene, scene->mRootNode); }catch(...) { aiReleaseImport(scene); throw; } aiReleaseImport(scene); }
AssimpScene::~AssimpScene(void) { if (this->m_pScene != NULL) { for (int i = 0; i < this->m_pScene->mNumMeshes;i++) { delete this->m_meshes[i]; } aiReleaseImport(this->m_pScene); //delete this->m_pScene; } //this->m_pScene->mMeshes[0]->mBones[0]->mWeights[0]. }
void Scene::unload() { nodes.clear(); nodeNames.clear(); resource.reset(); root_node.reset(); duration = 0; play_head = 0; file = ofFile(); if (scene) { aiReleaseImport(scene); scene = NULL; } }
bool load_mesh (const char* file_name, int & g_point_count) { const aiScene* scene = aiImportFile (file_name, aiProcess_MakeLeftHanded); // TRIANGLES! if (!scene) { fprintf (stderr, "ERROR: reading mesh %s\n", file_name); return false; } printf (" %i animations\n", scene->mNumAnimations); printf (" %i cameras\n", scene->mNumCameras); printf (" %i lights\n", scene->mNumLights); printf (" %i materials\n", scene->mNumMaterials); printf (" %i meshes\n", scene->mNumMeshes); printf (" %i textures\n", scene->mNumTextures); for (unsigned int m_i = 0; m_i < scene->mNumMeshes; m_i++) { const aiMesh* mesh = scene->mMeshes[m_i]; printf (" %i vertices in mesh\n", mesh->mNumVertices); g_point_count = mesh->mNumVertices; for (unsigned int v_i = 0; v_i < mesh->mNumVertices; v_i++) { if (mesh->HasPositions ()) { const aiVector3D* vp = &(mesh->mVertices[v_i]); //printf (" vp %i (%f,%f,%f)\n", v_i, vp->x, vp->y, vp->z); g_vp.push_back (vp->x); g_vp.push_back (vp->y); g_vp.push_back (vp->z); } if (mesh->HasNormals ()) { const aiVector3D* vn = &(mesh->mNormals[v_i]); //printf (" vn %i (%f,%f,%f)\n", v_i, vn->x, vn->y, vn->z); g_vn.push_back (vn->x); g_vn.push_back (vn->y); g_vn.push_back (vn->z); } if (mesh->HasTextureCoords (0)) { const aiVector3D* vt = &(mesh->mTextureCoords[0][v_i]); //printf (" vt %i (%f,%f)\n", v_i, vt->x, vt->y); g_vt.push_back (vt->x); g_vt.push_back (vt->y); } if (mesh->HasTangentsAndBitangents ()) { // NB: could store/print tangents here } } } aiReleaseImport (scene); return true; }
void load_mesh(char* fname, state_t* state, transform_data_t t, int bsdf_index, char* matname) { printf("Loading mesh %s\n",fname); //parse file const aiScene* scene = aiImportFile(fname, aiProcess_Triangulate | aiProcess_JoinIdenticalVertices); qr_assert(scene, "parser", "Could not open mesh file: %s (%s)",fname, aiGetErrorString()); for(int i=0; i<scene->mNumMeshes; i++) { bool contin = false; if(matname == NULL) { contin = true; } else { aiString name; aiGetMaterialString(scene->mMaterials[scene->mMeshes[i]->mMaterialIndex], AI_MATKEY_NAME, &name); contin = strcmp(matname, &name.data[0]) == 0; } if(contin) { int pind = state->n_primitives; state->n_primitives += scene->mMeshes[i]->mNumFaces; state->primitives = (primitive_t*)realloc(state->primitives, sizeof(primitive_t)*(state->n_primitives)); int vind = state->n_verts; int vstart = state->n_verts; state->n_verts += scene->mMeshes[i]->mNumVertices; state->verts = (vec3*)realloc(state->verts, sizeof(vec3)*(state->n_verts)); for(int j=0; j<scene->mMeshes[i]->mNumVertices; j++) { state->verts[vind++] = transform_point(make_vec3(scene->mMeshes[i]->mVertices[j].x, scene->mMeshes[i]->mVertices[j].y, scene->mMeshes[i]->mVertices[j].z), state->transforms[t.index], false); } for(int j=0; j<scene->mMeshes[i]->mNumFaces; j++) { qr_assert(scene->mMeshes[i]->mFaces[j].mNumIndices==3, "parser", "Only triangles are supported (%s)",fname); state->primitives[pind].type = PRIMITIVE_TRIANGLE; state->primitives[pind].t = 0; state->primitives[pind].bsdf = bsdf_index; state->primitives[pind++].data = make_primitive_triangle(vstart+scene->mMeshes[i]->mFaces[j].mIndices[0], vstart+scene->mMeshes[i]->mFaces[j].mIndices[1], vstart+scene->mMeshes[i]->mFaces[j].mIndices[2]); } } } aiReleaseImport(scene); }
ModelAndTextureLoader::~ModelAndTextureLoader() { glDeleteTextures(int(m_textureIdMap.size()), m_textureIds); if (m_textureIds) { delete[] m_textureIds; m_textureIds = NULL; } if ( m_textureOfEachMaterial ) { delete[] m_textureOfEachMaterial; m_textureOfEachMaterial = NULL; } m_textureIdMap.clear(); if ( m_assimpScene ) { unsigned int iMesh = 0; RecursiveMesh_Delete(m_assimpScene,m_assimpScene->mRootNode,&iMesh); aiReleaseImport(m_assimpScene); } if ( m_allMeshes ) { free(m_allMeshes); m_allMeshes = NULL; } }
int convert(const char *infname) { int i, bufsz; const struct aiScene *aiscn; struct goat3d *goat; char *outfname; bufsz = output_filename(0, 0, infname, "goat3d"); outfname = alloca(bufsz); output_filename(outfname, bufsz, infname, "goat3d"); printf("converting %s -> %s\n", infname, outfname); if(!(aiscn = aiImportFile(infname, SCE_PPFLAGS))) { fprintf(stderr, "failed to import %s\n", infname); return -1; } goat = goat3d_create(); for(i=0; i<(int)aiscn->mNumMaterials; i++) { struct aiMaterial *aimat = aiscn->mMaterials[i]; struct goat3d_material *mat = goat3d_create_mtl(); process_material(mat, aimat); goat3d_add_mtl(goat, mat); } for(i=0; i<(int)aiscn->mNumMeshes; i++) { struct aiMesh *aimesh = aiscn->mMeshes[i]; struct goat3d_mesh *mesh = goat3d_create_mesh(); process_mesh(goat, mesh, aimesh); goat3d_add_mesh(goat, mesh); } for(i=0; i<(int)aiscn->mRootNode->mNumChildren; i++) { process_node(goat, 0, aiscn->mRootNode->mChildren[i]); } goat3d_save(goat, outfname); goat3d_free(goat); aiReleaseImport(aiscn); return 0; }
static int assimp_import_file(lua_State *L) { const char *filename = luaX_checkstring(L, 1, "filename"); unsigned int flags = luaX_checkinteger(L, 2, "flags"); struct aiScene *scene = (struct aiScene*)aiImportFile(filename, flags); if (scene == NULL) { lua_pushnil(L); // [-0,+1,-] lua_pushstring(L, aiGetErrorString()); // [-0,+1,e] return 2; } _make_scene(L, scene); // [-0,+1,e] aiReleaseImport(scene); return 1; }
void cleanUp() { // cleanup - calling 'aiReleaseImport' is important, as the library // keeps internal resources until the scene is freed again. Not // doing so can cause severe resource leaking. aiReleaseImport(gun0.pistola.scene); aiReleaseImport(gun0.proiettile.scene); aiReleaseImport(level1_scene.scene); aiReleaseImport(level2_scene.scene); aiReleaseImport(level3_scene.scene); aiReleaseImport(target_scene.scene); aiReleaseImport(terreno_scene.scene); t3dCleanup(); return; }
/** * Destructor. Releases model data if necessary. */ IconModelManager::~IconModelManager() //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ { mInstance = NULL; int i = 0; //release icon/image data for (i = 0; i < mIconList.size(); i++) { delete mIconList[i].image; } mIconList.clear(); #ifdef USING_ASSIMP //release model data for (i = 0; i < mModelList.size(); i++) { const struct aiScene* scene = (const struct aiScene*)mModelList[i].modelData; aiReleaseImport(scene); } mModelList.clear(); #endif }
PolygonalGeometry * AssimpMeshLoader::load(const std::string & filename, const reflectionzeug::Variant & options, std::function<void(int, int)> /*progress*/) const { bool smoothNormals = false; // Get options const reflectionzeug::VariantMap * map = options.asMap(); if (map) { if (map->count("smoothNormals") > 0) smoothNormals = map->at("smoothNormals").value<bool>(); } // Import scene auto scene = aiImportFile( filename.c_str(), aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType | (smoothNormals ? aiProcess_GenSmoothNormals : aiProcess_GenNormals)); // Check for errors if (!scene) { std::cout << aiGetErrorString(); return nullptr; } // Convert first mesh found in the scene PolygonalGeometry * geometry = nullptr; if (scene->mNumMeshes > 0) { geometry = convertGeometry(scene->mMeshes[0]); } // Release scene aiReleaseImport(scene); // Return loaded mesh return geometry; }
//------------------------------------------- void ofxAssimpModelLoader::clear(){ ofLogVerbose("ofxAssimpModelLoader") << "clear(): deleting GL resources"; // clear out everything. modelMeshes.clear(); animations.clear(); pos.set(0,0,0); scale.set(1,1,1); rotAngle.clear(); rotAxis.clear(); lights.clear(); scale = ofPoint(1, 1, 1); if(scene){ aiReleaseImport(scene); scene = NULL; } normalizeScale = true; bUsingMaterials = true; bUsingNormals = true; bUsingTextures = true; bUsingColors = true; currentAnimation = -1; for(int i=0; i<textures.size(); i++) { if(textures[i]->hasTexture()) { ofTexture * tex = textures[i]->getTexturePtr(); delete tex; } } textures.clear(); updateModelMatrix(); ofRemoveListener(ofEvents().exit,this,&ofxAssimpModelLoader::onAppExit); }
/* load a mesh using the assimp library */ bool load_mesh (const char* file_name, GLuint* vao, int* point_count) { const aiScene* scene = aiImportFile (file_name, aiProcess_Triangulate); if (!scene) { fprintf (stderr, "ERROR: reading mesh %s\n", file_name); return false; } printf (" %i animations\n", scene->mNumAnimations); printf (" %i cameras\n", scene->mNumCameras); printf (" %i lights\n", scene->mNumLights); printf (" %i materials\n", scene->mNumMaterials); printf (" %i meshes\n", scene->mNumMeshes); printf (" %i textures\n", scene->mNumTextures); /* get first mesh in file only */ const aiMesh* mesh = scene->mMeshes[0]; printf (" %i vertices in mesh[0]\n", mesh->mNumVertices); /* pass back number of vertex points in mesh */ *point_count = mesh->mNumVertices; /* generate a VAO, using the pass-by-reference parameter that we give to the function */ glGenVertexArrays (1, vao); glBindVertexArray (*vao); /* we really need to copy out all the data from AssImp's funny little data structures into pure contiguous arrays before we copy it into data buffers because assimp's texture coordinates are not really contiguous in memory. i allocate some dynamic memory to do this. */ GLfloat* points = NULL; // array of vertex points GLfloat* normals = NULL; // array of vertex normals GLfloat* texcoords = NULL; // array of texture coordinates if (mesh->HasPositions ()) { points = (GLfloat*)malloc (*point_count * 3 * sizeof (GLfloat)); for (int i = 0; i < *point_count; i++) { const aiVector3D* vp = &(mesh->mVertices[i]); points[i * 3] = (GLfloat)vp->x; points[i * 3 + 1] = (GLfloat)vp->y; points[i * 3 + 2] = (GLfloat)vp->z; } } if (mesh->HasNormals ()) { normals = (GLfloat*)malloc (*point_count * 3 * sizeof (GLfloat)); for (int i = 0; i < *point_count; i++) { const aiVector3D* vn = &(mesh->mNormals[i]); normals[i * 3] = (GLfloat)vn->x; normals[i * 3 + 1] = (GLfloat)vn->y; normals[i * 3 + 2] = (GLfloat)vn->z; } } if (mesh->HasTextureCoords (0)) { texcoords = (GLfloat*)malloc (*point_count * 2 * sizeof (GLfloat)); for (int i = 0; i < *point_count; i++) { const aiVector3D* vt = &(mesh->mTextureCoords[0][i]); texcoords[i * 2] = (GLfloat)vt->x; texcoords[i * 2 + 1] = (GLfloat)vt->y; } } /* copy mesh data into VBOs */ if (mesh->HasPositions ()) { GLuint vbo; glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData ( GL_ARRAY_BUFFER, 3 * *point_count * sizeof (GLfloat), points, GL_STATIC_DRAW ); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); free (points); } if (mesh->HasNormals ()) { GLuint vbo; glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData ( GL_ARRAY_BUFFER, 3 * *point_count * sizeof (GLfloat), normals, GL_STATIC_DRAW ); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); free (normals); } if (mesh->HasTextureCoords (0)) { GLuint vbo; glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData ( GL_ARRAY_BUFFER, 2 * *point_count * sizeof (GLfloat), texcoords, GL_STATIC_DRAW ); glVertexAttribPointer (2, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); free (texcoords); } if (mesh->HasTangentsAndBitangents ()) { // NB: could store/print tangents here } aiReleaseImport (scene); printf ("mesh loaded\n"); return true; }
////////////////////////////////////////////////////////////////////////// // import BcBool ScnAnimationImport::import( const Json::Value& ) { #if PSY_IMPORT_PIPELINE if( Source_.empty() ) { PSY_LOG( "ERROR: Missing 'source' field.\n" ); return BcFalse; } CsResourceImporter::addDependency( Source_.c_str() ); auto PropertyStore = aiCreatePropertyStore(); aiLogStream AssimpLogger = { AssimpLogStream, (char*)this }; aiAttachLogStream( &AssimpLogger ); Scene_ = aiImportFileExWithProperties( Source_.c_str(), 0, nullptr, PropertyStore ); aiReleasePropertyStore( PropertyStore ); if( Scene_ != nullptr ) { PSY_LOG( "Found %u animations:\n", Scene_->mNumAnimations ); for( int Idx = 0; Idx < (int)Scene_->mNumAnimations; ++Idx ) { PSY_LOG( " - %s\n", Scene_->mAnimations[ Idx ]->mName.C_Str() ); } // Build animated nodes list. Need this to calculate relative transforms later. recursiveParseAnimatedNodes( Scene_->mRootNode, BcErrorCode ); // Pack down animation into useful internal format. BcAssert( Scene_->mNumAnimations == 1 ); for( BcU32 AnimationIdx = 0; AnimationIdx < 1; ++AnimationIdx ) { auto* Animation = Scene_->mAnimations[ AnimationIdx ]; BcF32 Rate = 1.0f; BcU32 Duration = static_cast< BcU32 >( Animation->mDuration / Rate ); // Setup data streams. ScnAnimationHeader Header; Header.NoofNodes_ = Animation->mNumChannels; Header.NoofPoses_ = Duration; Header.Flags_ = scnAF_DEFAULT; Header.Packing_ = scnAP_R16S16T16; // TODO: Make this configurable when we factor out into another class. HeaderStream_ << Header; // Animation node file data. ScnAnimationNodeFileData NodeFileData; for( BcU32 NodeIdx = 0; NodeIdx < Animation->mNumChannels; ++NodeIdx ) { auto* Channel = Animation->mChannels[ NodeIdx ]; NodeFileData.Name_ = CsResourceImporter::addString( Channel->mNodeName.C_Str() ); NodeStream_ << NodeFileData; } // Calculate output pose. for( BcF32 Time = 0.0f; Time <= Animation->mDuration; Time += Rate ) { ScnAnimationPoseFileData Pose; Pose.Time_ = Time / FrameRate_; Pose.KeyDataOffset_ = static_cast< BcU32 >( KeyStream_.dataSize() ); // Iterate over all node channels to generate keys. for( BcU32 ChannelIdx = 0; ChannelIdx < Animation->mNumChannels; ++ChannelIdx ) { auto* Channel = Animation->mChannels[ ChannelIdx ]; auto& AnimatedNode = findAnimatedNode( Channel->mNodeName.C_Str() ); aiVector3D OutPositionKey; aiVector3D OutScaleKey; aiQuaternion OutRotationKey; // Extract position. GetKeyNodeAnim( Channel->mPositionKeys, Channel->mNumPositionKeys, Time, BcTrue, OutPositionKey ); // Extract scale. GetKeyNodeAnim( Channel->mScalingKeys, Channel->mNumScalingKeys, Time, BcTrue, OutScaleKey ); // Extract rotation. GetKeyNodeAnim( Channel->mRotationKeys, Channel->mNumRotationKeys, Time, BcTrue, OutRotationKey ); // Combine key into transform. ScnAnimationTransform Transform; Transform.R_ = MaQuat( OutRotationKey.x, OutRotationKey.y, OutRotationKey.z, OutRotationKey.w ); Transform.S_ = MaVec3d( OutScaleKey.x, OutScaleKey.y, OutScaleKey.z ); Transform.T_ = MaVec3d( OutPositionKey.x, OutPositionKey.y, OutPositionKey.z ); // Store as local matrix. Transform.toMatrix( AnimatedNode.LocalTransform_ ); } // Calculate local node matrices relative to their parents. for( auto& AnimatedNode : AnimatedNodes_ ) { if( AnimatedNode.ParentIdx_ != BcErrorCode ) { auto& ParentAnimatedNode( AnimatedNodes_[ AnimatedNode.ParentIdx_ ] ); MaMat4d ParentLocal = ParentAnimatedNode.LocalTransform_; AnimatedNode.WorldTransform_ = ParentLocal * AnimatedNode.LocalTransform_; } else { AnimatedNode.WorldTransform_ = AnimatedNode.LocalTransform_; } } // Write out pose keys. ScnAnimationTransformKey_R16S16T16 OutKey; for( BcU32 ChannelIdx = 0; ChannelIdx < Animation->mNumChannels; ++ChannelIdx ) { auto* Channel = Animation->mChannels[ ChannelIdx ]; const auto& AnimatedNode = findAnimatedNode( Channel->mNodeName.C_Str() ); // Extract individual transform elements. ScnAnimationTransform Transform; Transform.fromMatrix( AnimatedNode.LocalTransform_ ); // Pack into output key. OutKey.pack( Transform.R_, Transform.S_, Transform.T_ ); KeyStream_ << OutKey; } // Final size + CRC. Pose.KeyDataSize_ = static_cast< BcU32 >( KeyStream_.dataSize() - Pose.KeyDataOffset_ ); Pose.CRC_ = BcHash::GenerateCRC32( 0, KeyStream_.pData() + Pose.KeyDataOffset_, Pose.KeyDataSize_ ); // Write out pose. PoseStream_ << Pose; } // Write out chunks. CsResourceImporter::addChunk( BcHash( "header" ), HeaderStream_.pData(), HeaderStream_.dataSize(), 16, csPCF_IN_PLACE ); CsResourceImporter::addChunk( BcHash( "nodes" ), NodeStream_.pData(), NodeStream_.dataSize() ); CsResourceImporter::addChunk( BcHash( "poses" ), PoseStream_.pData(), PoseStream_.dataSize() ); CsResourceImporter::addChunk( BcHash( "keys" ), KeyStream_.pData(), KeyStream_.dataSize() ); } aiReleaseImport( Scene_ ); Scene_ = nullptr; // return BcTrue; } #endif // PSY_IMPORT_PIPELINE return BcFalse; }
void assimp_release_scene(const aiScene *scene) { assert(scene); aiReleaseImport(scene); }
ShapeAssimp::ShapeAssimp(const char* path): Shape(path) { _vertices = nullptr; _indices = nullptr; // the global Assimp scene object (mesh loader) const struct aiScene* scene; scene = aiImportFile(path,aiProcessPreset_TargetRealtime_MaxQuality /*| aiProcess_MakeLeftHanded | aiProcess_FlipUVs */ ); if(scene && scene->mRootNode) { //unsigned int i; unsigned int n = 0, t; struct aiNode* nd = scene->mRootNode; if(nd && nd->mNumChildren > 0) nd = nd->mChildren[0]; // struct aiMatrix4x4 m = nd->mTransformation; if(nd) { // draw all meshes assigned to this node for (; n < nd->mNumMeshes && n <= 1; ++n) { const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; _verticesCount = mesh->mNumVertices; _indicesCount = mesh->mNumFaces * 3; _vertices = new SimpleVertex[_verticesCount]; std::memset(_vertices, 0, sizeof(WORD) * _verticesCount); _indices = new WORD[_indicesCount]; std::memset(_indices, 0, sizeof(WORD) * _indicesCount); for (t = 0; t < mesh->mNumVertices; ++t) { const aiVector3D* vertice = &mesh->mVertices[t]; const aiVector3D* normal = &mesh->mNormals[t]; const aiVector3D* uvCoord = &mesh->mTextureCoords[0][t]; if(vertice && normal && uvCoord) _vertices[t] = SimpleVertex( XMFLOAT3( vertice->x, -vertice->z, vertice->y ), XMFLOAT3( normal->x, -normal->z, normal->y ) , XMFLOAT2( uvCoord->x, uvCoord->y ) ); else _vertices[t] = SimpleVertex( XMFLOAT3( 0, 0, 0 ), XMFLOAT3( 0, 0, 0), XMFLOAT2( 0, 0) ); } for (t = 0; t < mesh->mNumFaces; ++t) { const struct aiFace* face = &mesh->mFaces[t]; if(face->mNumIndices != 3) break; //only triangles supported _indices[3*t] = face->mIndices[0]; _indices[3*t+1] = face->mIndices[1]; _indices[3*t+2] = face->mIndices[2]; } } } } aiReleaseImport(scene); scene = nullptr; }
bool meshLoadMeshFile(const char *fileName, GLuint *vao, int *point_count){ const aiScene *scene = aiImportFile(fileName, aiProcess_Triangulate); if (!scene) { fprintf(stderr, "ERROR: reading mesh %s\n", fileName); return false; } printf(" %i animations\n", scene->mNumAnimations); printf(" %i Cameras\n", scene->mNumCameras); printf(" %i lights\n", scene->mNumLights); printf(" %i Materials\n", scene->mNumMaterials); printf(" %i Meshes\n", scene->mNumMeshes); printf(" %i textures\n", scene->mNumTextures); /*get the first mesh */ const aiMesh* mesh = scene->mMeshes[0]; printf(" %i vertices in mesh[0]\n", mesh->mNumVertices); /**pass back the mesh count */ *point_count = mesh->mNumVertices; /* generate */ glGenVertexArrays(1, vao); glBindVertexArray(*vao); /** make the data contiguous */ GLfloat * points = NULL; GLfloat * normals = NULL; GLfloat * texcoords = NULL; if (mesh->HasPositions()) { points = (GLfloat *) malloc(*point_count * 3 * sizeof(GLfloat)); for (int i = 0; i < *point_count; ++i) { const aiVector3D *vp = &(mesh->mVertices[i]); points[i * 3 + 0] = (GLfloat)vp->x; points[i * 3 + 1] = (GLfloat)vp->y; points[i * 3 + 2] = (GLfloat)vp->z; } } if (mesh->HasNormals()) { normals = (GLfloat *) malloc(*point_count * 3 * sizeof(GLfloat)); for (int i = 0; i < *point_count; ++i) { const aiVector3D *vp = &(mesh->mNormals[i]); normals[i * 3 + 0] = (GLfloat)vp->x; normals[i * 3 + 1] = (GLfloat)vp->y; normals[i * 3 + 2] = (GLfloat)vp->z; } } if (mesh->HasTextureCoords(0)) { texcoords = (GLfloat *) malloc(*point_count * 2 * sizeof(GLfloat)); for (int i = 0; i < *point_count; ++i) { const aiVector3D *vp = &(mesh->mTextureCoords[0][i]); texcoords[i * 2 + 0] = (GLfloat)vp->x; texcoords[i * 2 + 1] = (GLfloat)vp->y; } } /** make vbos*/ if (mesh->HasPositions()) { GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 3 * *point_count * sizeof(GLfloat), points, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); free(points); } if (mesh->HasNormals()) { GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 3 * *point_count * sizeof(GLfloat), normals, GL_STATIC_DRAW); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(1); free(normals); } if (mesh->HasTextureCoords(0)) { GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 2 * *point_count * sizeof(GLfloat), texcoords, GL_STATIC_DRAW); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(2); free(texcoords); } if (mesh->HasTangentsAndBitangents()) { } aiReleaseImport(scene); printf("Mesh loaded\n"); return true; }
bool load_mesh (const char* file_name) { const aiScene* scene = aiImportFile (file_name, aiProcess_Triangulate); if (!scene) { fprintf (stderr, "ERROR: reading mesh %s\n", file_name); return false; } printf (" %i animations\n", scene->mNumAnimations); printf (" %i cameras\n", scene->mNumCameras); printf (" %i lights\n", scene->mNumLights); printf (" %i materials\n", scene->mNumMaterials); printf (" %i meshes\n", scene->mNumMeshes); printf (" %i textures\n", scene->mNumTextures); // get first mesh only const aiMesh* mesh = scene->mMeshes[0]; printf (" %i vertices in mesh[0]\n", mesh->mNumVertices); g_point_count = mesh->mNumVertices; // allocate memory for vertex points if (mesh->HasPositions ()) { printf ("mesh has positions\n"); g_vp = (GLfloat*)malloc (g_point_count * 3 * sizeof (GLfloat)); } if (mesh->HasNormals ()) { printf ("mesh has normals\n"); g_vn = (GLfloat*)malloc (g_point_count * 3 * sizeof (GLfloat)); } if (mesh->HasTextureCoords (0)) { printf ("mesh has texture coords\n"); g_vt = (GLfloat*)malloc (g_point_count * 2 * sizeof (GLfloat)); } if (mesh->HasTangentsAndBitangents ()) { // NB: could allocate tangents here too } for (unsigned int v_i = 0; v_i < mesh->mNumVertices; v_i++) { if (mesh->HasPositions ()) { const aiVector3D* vp = &(mesh->mVertices[v_i]); g_vp[v_i * 3] = (GLfloat)vp->x; g_vp[v_i * 3 + 1] = (GLfloat)vp->y; g_vp[v_i * 3 + 2] = (GLfloat)vp->z; } if (mesh->HasNormals ()) { const aiVector3D* vn = &(mesh->mNormals[v_i]); g_vn[v_i * 3] = (GLfloat)vn->x; g_vn[v_i * 3 + 1] = (GLfloat)vn->y; g_vn[v_i * 3 + 2] = (GLfloat)vn->z; } if (mesh->HasTextureCoords (0)) { const aiVector3D* vt = &(mesh->mTextureCoords[0][v_i]); g_vt[v_i * 2] = (GLfloat)vt->x; g_vt[v_i * 2 + 1] = (GLfloat)vt->y; } if (mesh->HasTangentsAndBitangents ()) { // NB: could store/print tangents here } } aiReleaseImport (scene); printf ("mesh loaded\n"); return true; }