//------------------------------------------- void ofxAssimpModelLoader::getBoundingBoxForNode(const struct aiNode* nd, struct aiVector3D* min, struct aiVector3D* max, struct aiMatrix4x4* trafo) { struct aiMatrix4x4 prev; unsigned int n = 0, t; prev = *trafo; aiMultiplyMatrix4(trafo,&nd->mTransformation); for (; n < nd->mNumMeshes; ++n){ const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; for (t = 0; t < mesh->mNumVertices; ++t){ struct aiVector3D tmp = mesh->mVertices[t]; aiTransformVecByMatrix4(&tmp,trafo); min->x = aisgl_min(min->x,tmp.x); min->y = aisgl_min(min->y,tmp.y); min->z = aisgl_min(min->z,tmp.z); max->x = aisgl_max(max->x,tmp.x); max->y = aisgl_max(max->y,tmp.y); max->z = aisgl_max(max->z,tmp.z); } } for (n = 0; n < nd->mNumChildren; ++n){ this->getBoundingBoxForNode(nd->mChildren[n], min, max, trafo); } *trafo = prev; }
void get_bounding_box_for_node (const struct aiScene *sc, const struct aiNode* nd, struct aiVector3D* min, struct aiVector3D* max, struct aiMatrix4x4* trafo) { struct aiMatrix4x4 prev; unsigned int n = 0, t; prev = *trafo; aiMultiplyMatrix4(trafo,&nd->mTransformation); for (; n < nd->mNumMeshes; ++n) { const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[n]]; for (t = 0; t < mesh->mNumVertices; ++t) { struct aiVector3D tmp = mesh->mVertices[t]; aiTransformVecByMatrix4(&tmp,trafo); min->x = aisgl_min(min->x,tmp.x); min->y = aisgl_min(min->y,tmp.y); min->z = aisgl_min(min->z,tmp.z); max->x = aisgl_max(max->x,tmp.x); max->y = aisgl_max(max->y,tmp.y); max->z = aisgl_max(max->z,tmp.z); } } for (n = 0; n < nd->mNumChildren; ++n) { get_bounding_box_for_node(sc, nd->mChildren[n],min,max,trafo); } *trafo = prev; }
void Model3D::get_bounding_box_for_node(const struct aiNode* nd, struct aiVector3D* min, struct aiVector3D* max, struct aiMatrix4x4* trafo) { struct aiMatrix4x4 prev; // Use struct keyword to show you want struct version of this, not normal typedef? unsigned int n = 0, t; prev = *trafo; aiMultiplyMatrix4(trafo, &nd->mTransformation); for (; n < nd->mNumMeshes; ++n) { const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; for (t = 0; t < mesh->mNumVertices; ++t) { struct aiVector3D tmp = mesh->mVertices[t]; aiTransformVecByMatrix4(&tmp, trafo); min->x = aisgl_min(min->x,tmp.x); min->y = aisgl_min(min->y,tmp.y); min->z = aisgl_min(min->z,tmp.z); max->x = aisgl_max(max->x,tmp.x); max->y = aisgl_max(max->y,tmp.y); max->z = aisgl_max(max->z,tmp.z); } } for (n = 0; n < nd->mNumChildren; ++n) get_bounding_box_for_node(nd->mChildren[n], min, max, trafo); *trafo = prev; }
void get_bounding_box_for_node (const aiNode* nd, aiVector3D* min, aiVector3D* max) { aiMatrix4x4 prev; unsigned int n = 0, t; for (; n < nd->mNumMeshes; ++n) { const aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; for (t = 0; t < mesh->mNumVertices; ++t) { aiVector3D tmp = mesh->mVertices[t]; min->x = aisgl_min(min->x,tmp.x); min->y = aisgl_min(min->y,tmp.y); min->z = aisgl_min(min->z,tmp.z); max->x = aisgl_max(max->x,tmp.x); max->y = aisgl_max(max->y,tmp.y); max->z = aisgl_max(max->z,tmp.z); } } for (n = 0; n < nd->mNumChildren; ++n) { get_bounding_box_for_node(nd->mChildren[n],min,max); } }
//------------------------------------------ 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"); } } }
void VSResModelLib::get_bounding_box_for_node (const struct aiNode* nd, struct aiVector3D* min, struct aiVector3D* max) { unsigned int n = 0; mVSML->pushMatrix(VSMathLib::AUX0); if (nd->mNumMeshes) { // Get node transformation matrix struct aiMatrix4x4 m = nd->mTransformation; // OpenGL matrices are column major m.Transpose(); // apply node transformation float aux[16]; memcpy(aux,&m,sizeof(float) * 16); mVSML->multMatrix(VSMathLib::AUX0, aux); for (; n < nd->mNumMeshes; ++n) { const struct aiMesh* mesh = pScene->mMeshes[nd->mMeshes[n]]; for (unsigned int t = 0; t < mesh->mNumVertices; ++t) { struct aiVector3D tmp = mesh->mVertices[t]; float a[4], res[4]; a[0] = tmp.x; a[1] = tmp.y; a[2] = tmp.z; a[3] = 1.0f; mVSML->multMatrixPoint(VSMathLib::AUX0, a, res); min->x = aisgl_min(min->x,res[0]); min->y = aisgl_min(min->y,res[1]); min->z = aisgl_min(min->z,res[2]); max->x = aisgl_max(max->x,res[0]); max->y = aisgl_max(max->y,res[1]); max->z = aisgl_max(max->z,res[2]); } } } for (n = 0; n < nd->mNumChildren; ++n) { get_bounding_box_for_node(nd->mChildren[n],min,max); } mVSML->popMatrix(VSMathLib::AUX0); }
/* ---------------------------------------------------------------------------- */ void display(void) { float tmp; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f); /* rotate it around the y axis */ glRotatef(angle,0.f,1.f,0.f); /* scale the whole asset to fit into our view frustum */ tmp = scene_max.x-scene_min.x; tmp = aisgl_max(scene_max.y - scene_min.y,tmp); tmp = aisgl_max(scene_max.z - scene_min.z,tmp); tmp = 1.f / tmp; glScalef(tmp, tmp, tmp); /* center the model */ glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z ); /* if the display list has not been made yet, create a new one and fill it with scene contents */ if(scene_list == 0) { scene_list = glGenLists(1); glNewList(scene_list, GL_COMPILE); /* now begin at the root node of the imported data and traverse the scenegraph by multiplying subsequent local transforms together on GL's matrix stack. */ recursive_render(scene, scene->mRootNode); glEndList(); } glCallList(scene_list); glutSwapBuffers(); do_motion(); }
ModelAndTextureLoader::ModelAndTextureLoader(const char* TextureDirectory,const char* fullPathToModel) { m_nbTotalMesh = 0; m_allMeshes = NULL; //force to recompute normal tangent and bitangent //Assimp::Importer::SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_NORMALS); //aiSetImportPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_NORMALS); //aiSetImportPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_TANGENTS_AND_BITANGENTS); m_assimpScene = aiImportFile(fullPathToModel, aiProcessPreset_TargetRealtime_MaxQuality|aiProcess_PreTransformVertices); // | aiProcess_RemoveComponent | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals //force to recompute normal tangent and bitangent // ); if ( m_assimpScene ) { struct aiVector3D scene_min, scene_max, scene_center; get_bounding_box(&scene_min,&scene_max); m_vCenter.x = (scene_min.x + scene_max.x) / 2.0f; m_vCenter.y = (scene_min.y + scene_max.y) / 2.0f; m_vCenter.z = (scene_min.z + scene_max.z) / 2.0f; m_fSize = scene_max.x-scene_min.x; m_fSize = aisgl_max(scene_max.y - scene_min.y,m_fSize); m_fSize = aisgl_max(scene_max.z - scene_min.z,m_fSize); RecursiveMesh_CountTotalMesh(m_assimpScene,m_assimpScene->mRootNode); m_allMeshes = (MESH*)malloc(sizeof(MESH) * m_nbTotalMesh); unsigned int iMesh = 0; RecursiveMesh_Loading(m_assimpScene,m_assimpScene->mRootNode,&iMesh); //load textures m_textureOfEachMaterial = new MATERIAL_TEXTUREID[m_assimpScene->mNumMaterials]; for (unsigned int m=0; m<m_assimpScene->mNumMaterials; m++) { int texIndex; texIndex = 0; while (true) { aiString path; aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path); if ( texFound == AI_SUCCESS ) { m_textureIdMap[path.data] = NULL; texIndex++; } else{break;} } texIndex = 0; texIndex = 0; while (true) { aiString path; aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_SPECULAR, texIndex, &path); if ( texFound == AI_SUCCESS ) { m_textureIdMap[path.data] = NULL; texIndex++; } else{break;} } texIndex = 0; while (true) { aiString path; aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_AMBIENT, texIndex, &path); if ( texFound == AI_SUCCESS ) { m_textureIdMap[path.data] = NULL; texIndex++; } else{break;} } texIndex = 0; while (true) { aiString path; aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_EMISSIVE, texIndex, &path); if ( texFound == AI_SUCCESS ) { m_textureIdMap[path.data] = NULL; texIndex++; } else{break;} } texIndex = 0; while (true) { aiString path; aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_NORMALS, texIndex, &path); if ( texFound == AI_SUCCESS ) { m_textureIdMap[path.data] = NULL; texIndex++; } else{break;} } texIndex = 0; while (true) { aiString path; aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_HEIGHT, texIndex, &path); if ( texFound == AI_SUCCESS ) { m_textureIdMap[path.data] = NULL; texIndex++; } else{break;} } } int numTextures = int(m_textureIdMap.size()); std::map<std::string, GLuint*>::iterator itr = m_textureIdMap.begin(); m_textureIds = new GLuint[numTextures]; glGenTextures(numTextures, m_textureIds); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (int i=0; i<numTextures; i++) { std::string filename = (*itr).first; (*itr).second = &m_textureIds[i]; gli::texture2D textureFileLoaded = gli::load(std::string(TextureDirectory) + filename); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gli::texture2D::format_type formatImage = textureFileLoaded.format(); if ( formatImage == gli::RGB8U ) { glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,textureFileLoaded[0].dimensions().x,textureFileLoaded[0].dimensions().y,0,GL_RGB,GL_UNSIGNED_BYTE,textureFileLoaded[0].data()); } else if ( formatImage == gli::RGBA8U ) { glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,textureFileLoaded[0].dimensions().x,textureFileLoaded[0].dimensions().y,0,GL_RGBA,GL_UNSIGNED_BYTE,textureFileLoaded[0].data()); } glBindTexture(GL_TEXTURE_2D, 0); itr++; } glPixelStorei(GL_UNPACK_ALIGNMENT, 4); for (unsigned int m=0; m<m_assimpScene->mNumMaterials; m++) { aiString path; aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, 0, &path); if ( texFound == AI_SUCCESS ) { m_textureOfEachMaterial[m].idDiffuse = *m_textureIdMap[path.data] ; } else{ m_textureOfEachMaterial[m].idDiffuse = 0;} texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_SPECULAR, 0, &path); if ( texFound == AI_SUCCESS ) { m_textureOfEachMaterial[m].idSpecular = *m_textureIdMap[path.data] ; } else{ m_textureOfEachMaterial[m].idSpecular = 0;} texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_AMBIENT, 0, &path); if ( texFound == AI_SUCCESS ) { m_textureOfEachMaterial[m].idAmbiant = *m_textureIdMap[path.data] ; } else{ m_textureOfEachMaterial[m].idAmbiant = 0;} texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_EMISSIVE, 0, &path); if ( texFound == AI_SUCCESS ) { m_textureOfEachMaterial[m].idEmissive = *m_textureIdMap[path.data] ; } else{ m_textureOfEachMaterial[m].idEmissive = 0;} texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_NORMALS, 0, &path); if ( texFound == AI_SUCCESS ) { m_textureOfEachMaterial[m].idNormal = *m_textureIdMap[path.data] ; } else { //height could be considered as normals texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_HEIGHT, 0, &path); if ( texFound == AI_SUCCESS ) { m_textureOfEachMaterial[m].idNormal = *m_textureIdMap[path.data] ; } else { m_textureOfEachMaterial[m].idNormal = 0; } } } } }
/* ---------------------------------------------------------------------------- */ void display(void) { float Ambient[] = {0,0,0,1}; float Diffuse[] = {1,1,1,1}; float Specular[] = {1.0,1.0,1.0,1}; float white[] = {1,1,1,1}; float tmp; glPushMatrix(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f); /* rotate it around the y axis */ //glRotatef(angle,0.f,1.f,0.f); glRotatef(180,0.f,1.f,0.f); glEnable(GL_LIGHTING); /* scale the whole asset to fit into our view frustum */ tmp = scene_max.x-scene_min.x; tmp = aisgl_max(scene_max.y - scene_min.y,tmp); tmp = aisgl_max(scene_max.z - scene_min.z,tmp); double len = tmp; tmp = 1.f / tmp; float Position[] = {len*3.5,len/2,0,1}; glScalef(tmp, tmp, tmp); /* center the model */ glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z ); /* if the display list has not been made yet, create a new one and fill it with scene contents */ // Place this in the mode switching function if(scene_list == 0) { scene_list = glGenLists(1); glNewList(scene_list, GL_COMPILE); /* now begin at the root node of the imported data and traverse the scenegraph by multiplying subsequent local transforms together on GL's matrix stack. */ recursive_render(scene, scene->mRootNode); glEndList(); } // move ship to mouse cursor glTranslatef(mouseWorldCoord[0],mouseWorldCoord[1],0); // add some slight sway to make ship seem more 'alive' glTranslatef(infinitySymbol[0],infinitySymbol[1],0); glCallList(scene_list); glPopMatrix(); ball(Position[0],Position[1],Position[2],10); glPushMatrix(); glRotatef(angle,0.0,1.0,0.0); Sky(len*3.5); glPopMatrix(); glLightfv(GL_LIGHT0,GL_AMBIENT ,Ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE ,Diffuse); glLightfv(GL_LIGHT0,GL_SPECULAR,Specular); glLightfv(GL_LIGHT0,GL_POSITION,Position); glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,32.0f); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,white); // Draw axes - no lighting from here on if(axes){ glDisable(GL_LIGHTING); glColor3f(1, 1, 1); glBegin(GL_LINES); glVertex3d(0.0, 0.0, 0.0); glVertex3d(len, 0.0, 0.0); glVertex3d(0.0, 0.0, 0.0); glVertex3d(0.0, len, 0.0); glVertex3d(0.0, 0.0, 0.0); glVertex3d(0.0, 0.0, len); glEnd(); } glutSwapBuffers(); do_motion(); }