void CMapLoader::ReloadMaterials() { Ogre::MaterialManager::getSingleton().removeAll(); std::vector<LOADED_MAP>::iterator i; for(i = mapList.begin();i != mapList.end();i++) { LoadMaterials(i->map); LoadMaterials(i->patch); } }
void CMapLoader::mapAdd(LOADED_MAP& map) { mapList.push_back(map); if(map.patch) { LoadMaterials(map.patch); LoadScripts(map.patch); } LoadMaterials(map.map); LoadScripts(map.map); }
//------------------------------------------------------------ void PPC::AddParamsFrom(tixmlel_traits::in element) { defaultMaterialName = XI::GetString( element, PK::DEF_MAT_NAME ); defaultSceneName = XI::GetString( element, PK::DEF_SCENE_NAME ); if( defaultMaterialName.empty() )defaultMaterialName = PK::DEFAULT_NAME; if( defaultSceneName.empty() )defaultSceneName = PK::DEFAULT_NAME; OPC::torqueMechToPhysXMult = XI::GetReal( element, PK::TORQUE_MULT ); nxuFilename = XI::GetString( element, PK::NXU_FILE ); string_traits::str childName; const TiXmlElement* childElement(0); while( XI::IterateChildElements( element, childElement ) ) { childName = childElement->Value(); if( childName == PK::SDK ) { LoadSDK( childElement ); } else if( childName == PK::SCENES ) { LoadScenes( childElement ); } else if( childName == PK::MATERIALS ) { LoadMaterials( childElement ); } } }
bool Object3D::Load(std::string filename) { std::ifstream file; std::vector<Vertex> vertices; std::vector<D3DXVECTOR3> outPositions; std::vector<D3DXVECTOR2> outUVCoords; std::vector<D3DXVECTOR3> outNormals; Group currGroup; std::string currGroupName = ""; file.open(filename.c_str(), std::ios_base::binary); if(!file.is_open()) return false; while(!file.eof()) { // Read first line of file. std::string line; std::getline(file, line); // Copy line to a stringstream and copy first word into string key std::stringstream streamLine; streamLine.str(line); std::string key; streamLine >> key; if(key == "mtllib") { std::string matFileName; streamLine >> matFileName; LoadMaterials(matFileName); } else if(key == "v")
void AELoadedResourcesTreeView::LoadResources() { LoadModels(); LoadMaterials(); LoadTextures(); // LoadMeshes(); // LoadModelInstances(); // LoadMeshInstances(); }
bool Model::LoadFromFile(std::string filepath) { // Clear any previously loaded data. Clear(); // Create an instance of the ASSIMP importer. Assimp::Importer importer; // Have ASSIMP read the file. const aiScene* assimpScene = importer.ReadFile( filepath.c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices | aiProcess_RemoveRedundantMaterials | aiProcess_FlipUVs | aiProcess_OptimizeGraph | aiProcess_OptimizeMeshes ); // Check that the file was read successfully. if (assimpScene) { // Get the root node. const aiNode* assimpRootNode = assimpScene->mRootNode; if (assimpRootNode) { // Get the path to the parent directory. // This is used for determining the full path to textures. const std::string directoryPath = filepath.substr(0, filepath.find_last_of('/')); // Load the materials. LoadMaterials(assimpScene, directoryPath); // Load the nodes recursively. LoadNode(assimpRootNode, assimpScene, nullptr); // Load the node keyframes. LoadNodeKeyframes(assimpScene); // Success! m_name = filepath; return true; } else { std::cerr << "Failed loading model \"" << filepath << "\" due to missing root node" << std::endl; return false; } } else { std::cerr << "Failed loading model: \"" << filepath << "\" due to error: " << importer.GetErrorString() << std::endl; return false; } }
Import::Import(const char* pathName, Interface* ip, ImpInterface* impip) { // set the path for textures char* ptr = NULL; sprintf (m_path, "%s", pathName); for (int i = 0; m_path[i]; i ++) { if ((m_path[i] == '\\') || (m_path[i] == '/') ) { ptr = &m_path[i]; } } *ptr = 0; m_ip = ip; m_impip = impip; m_succes = TRUE; MaterialCache materialCache (NewDefaultMultiMtl()); SetSceneParameters(); dFloat scale; scale = float (GetMasterScale(UNITS_METERS)); dMatrix scaleMatrix (GetIdentityMatrix()); scaleMatrix[0][0] = 1.0f / scale; scaleMatrix[1][1] = 1.0f / scale; scaleMatrix[2][2] = 1.0f / scale; dMatrix globalRotation (scaleMatrix * dPitchMatrix(3.14159265f * 0.5f) * dRollMatrix(3.14159265f * 0.5f)); NewtonWorld* newton = NewtonCreate(); dScene scene (newton); scene.Deserialize (pathName); // dScene::Iterator iter (scene); // for (iter.Begin(); iter; iter ++) { // dScene::dTreeNode* node = iter.GetNode(); // dNodeInfo* info = scene.GetInfoFromNode(node); // if (info->GetTypeId() == dMeshNodeInfo::GetRttiType()) { // dMeshNodeInfo* mesh = (dMeshNodeInfo*) scene.GetInfoFromNode(node); // mesh->ConvertToTriangles(); // } // } scene.BakeTransform (globalRotation); GeometryCache geometryCache; MaxNodeChache maxNodeCache; LoadMaterials (scene, materialCache); LoadGeometries (scene, geometryCache, materialCache); LoadNodes (scene, geometryCache, materialCache.m_multiMat, maxNodeCache); ApplyModifiers (scene, maxNodeCache); scene.CleanUp(); NewtonDestroy(newton); }
void Model_IO::LoadMesh(Mesh& mesh, BinaryReader& reader, const achar* path) { auto mcount = reader.Get<int32_t>(); mesh.DividedMeshes.resize(mcount); for (auto i = 0; i < mcount; i++) { LoadDividedMesh(mesh.DividedMeshes[i], reader, path); } LoadMaterials(mesh.Materials, reader, path); }
void RBTerrain::Load(const char *name) { RUDE_REPORT("Loading terrain %s\n", name); LoadMesh(name); LoadPhysicsMesh(0.0f); LoadMaterials(); RudePhysicsMesh *obj = (RudePhysicsMesh *) GetPhysicsObject(); btRigidBody *rb = obj->GetRigidBody(); rb->setFriction(50.0f); rb->setRestitution(0.99f); rb->setCollisionFlags(rb->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); rb->setCollisionFlags(rb->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); obj->SetNotifyOnContact(true); obj->SetContactCallback(RBTerrainContactCallback); LoadNodes(); m_holeTexture = RudeTextureManager::GetInstance()->LoadTextureFromPNGFile("hole"); RUDE_ASSERT(m_holeTexture, "Could not load hole texture"); btDiscreteDynamicsWorld *world = RudePhysics::GetInstance()->GetWorld(); btVector3 p0 = m_hole; p0.setY(m_hole.y() - 1000); btVector3 p1 = m_hole; p1.setY(m_hole.y() + 1000); btCollisionWorld::ClosestRayResultCallback cb(p0, p1); world->rayTest(p0, p1, cb); RUDE_ASSERT(cb.hasHit(), "Could not position hole.. is it over terrain? (%f %f %f)", m_hole.x(), m_hole.y(), m_hole.z()); RUDE_REPORT(" Hole %f %f %f -> %f %f %f\n", m_hole.x(), m_hole.y(), m_hole.z(), cb.m_hitPointWorld.x(), cb.m_hitPointWorld.y(), cb.m_hitPointWorld.z()); m_hole = cb.m_hitPointWorld; m_decorator.Load(name); }
void CAnimatedInstanceModel::Initialize(CAnimatedCoreModel *AnimatedCoreModel) { m_AnimatedCoreModel = AnimatedCoreModel; m_CalModel = new CalModel(m_AnimatedCoreModel->GetCalCoreModel()); m_CalHardwareModel = new CalHardwareModel(m_AnimatedCoreModel->GetCalCoreModel()); // attach all meshes to the model //int meshId; //for (meshId = 0; meshId < AnimatedCoreModel->GetCalCoreModel()->getCoreMeshCount(); meshId++) //{ // m_CalModel->attachMesh(meshId); //} LoadVertexBuffer(); LoadMaterials(); BlendCycle(1, 1.0f, 0.0f); Update(0.0f); }
void OgreApplication::Init(void){ /* Set default values for the variables */ animating_ = false; space_down_ = false; animation_state_ = NULL; input_manager_ = NULL; keyboard_ = NULL; mouse_ = NULL; /* Run all initialization steps */ InitRootNode(); InitPlugins(); InitRenderSystem(); InitWindow(); InitViewport(); InitEvents(); InitOIS(); LoadMaterials(); }
void ColladaDoc::Load( lpxmlnode pNode) { lpxmlnode pCurrNode = pNode; std::string Name = pCurrNode->name(); if(Name == "COLLADA") { // COLLADA header found pCurrNode = pCurrNode->first_node(); while(pCurrNode != NULL) { Name = pCurrNode->name(); if(Name == "library_images") LoadImages(pCurrNode->first_node()); else if(Name == "library_effects") LoadEffects(pCurrNode->first_node()); else if(Name == "library_materials") LoadMaterials(pCurrNode->first_node()); else if(Name == "library_geometries") LoadGeometries(pCurrNode->first_node()); else if(Name == "library_animations") LoadAnimations(pCurrNode->first_node()); else if(Name =="library_controllers") LoadControllers(pCurrNode->first_node()); else if(Name == "library_visual_scenes") LoadVisualScenes(pCurrNode->first_node()); else if(Name == "asset") LoadAssets(pCurrNode->first_node()); pCurrNode = pCurrNode->next_sibling(); }; } }
int SceneLoader::LoadFile(const char* filename) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(filename, 0); scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace | aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_JoinIdenticalVertices); if (!scene) { std::stringstream oss; oss << "ERROR - File: " << filename << " not found." << std::endl; std::string debugMsg(oss.str()); OutputDebugStringA(debugMsg.c_str()); return false; } DrawableObject *newObject = new DrawableObject(); std::vector<Vertex> vertexList; std::vector<UINT> indexList; std::stringstream oss; for (unsigned int i = 0; i < scene->mRootNode->mNumChildren; ++i) { bool successfulLoad = true; aiNode* currentNode = scene->mRootNode->mChildren[i]; BuildShaders(d3dDevice, *newObject, mShaderManager); for (unsigned int j = 0; j < currentNode->mNumMeshes; ++j) { ProcessMesh(d3dDevice, *scene->mMeshes[currentNode->mMeshes[j]], *newObject, vertexList, indexList, scene->mMeshes[currentNode->mMeshes[j]]->mMaterialIndex - 1); //LoadMaterials(d3dDevice, scene->mMeshes[currentNode->mMeshes[j]]->mMaterialIndex, *newObject, scene); oss << "MatIndex = " << scene->mMeshes[currentNode->mMeshes[j]]->mMaterialIndex << "\n"; } } std::string debugMsg(oss.str()); OutputDebugStringA(debugMsg.c_str()); for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { LoadMaterials(d3dDevice, i, *newObject, scene); } newObject->GetMeshData()->Initialize(d3dDevice, vertexList, indexList); mDrawableObjects.push_back(newObject); return mDrawableObjects.size() - 1; }
//----------------------------------------------------------------------------- // Purpose: Loads textures from all texture files. //----------------------------------------------------------------------------- void CTextureSystem::LoadAllGraphicsFiles(void) { FreeAllTextures(); // For each game config... // dvs: Disabled for single-config running. //for (int nConfig = 0; nConfig < Options.configs.GetGameConfigCount(); nConfig++) { //CGameConfig *pConfig = Options.configs.GetGameConfig(nConfig); CGameConfig *pConfig = g_pGameConfig; // Create a new texture context with the WADs and materials for that config. TextureContext_t *pContext = AddTextureContext(); // Bind it to this config. pContext->pConfig = pConfig; // Create a group to hold all the textures for this context. pContext->pAllGroup = new CTextureGroup("All Textures"); pContext->Groups.AddToTail(pContext->pAllGroup); HammerFileSystem_SetGame(pConfig->m_szGameExeDir, pConfig->m_szModDir); // Set the new context as the active context. m_pActiveContext = pContext; // Load the textures for all WAD files set in this config. // Only do this for configs that use WAD textures. if (pConfig->GetTextureFormat() == tfWAD3) { LoadWADFiles(pConfig); } // Load the materials for this config. // Do this unconditionally so that we get necessary editor materials. LoadMaterials(pConfig); m_pActiveContext->pAllGroup->Sort(); } }
Model::Model(const std::string& filePath, bool flipUVs) : mMeshes(), mMaterials() { std::ifstream inFile(filePath, ifstream::in | ifstream::binary); if (inFile.is_open()) { char readData[sizeof(uint32_t)]; inFile.read(readData, sizeof(uint32_t)); uint32_t numMat; memcpy(&numMat, readData, sizeof(uint32_t)); inFile.read(readData, sizeof(uint32_t)); uint32_t numMesh; memcpy(&numMesh, readData, sizeof(uint32_t)); LoadMaterials(inFile, numMat); LoadMeshes(inFile, numMesh); inFile.close(); } }
bool CGrannyMesh::CreateFromGrannyMeshPointer(granny_skeleton * pgrnSkeleton, granny_mesh * pgrnMesh, int vtxBasePos, int idxBasePos, CGrannyMaterialPalette& rkMtrlPal) { assert(IsEmpty()); m_pgrnMesh = pgrnMesh; m_vtxBasePos = vtxBasePos; m_idxBasePos = idxBasePos; if (m_pgrnMesh->BoneBindingCount < 0) return true; // WORK m_pgrnMeshBindingTemp = GrannyNewMeshBinding(m_pgrnMesh, pgrnSkeleton, pgrnSkeleton); // END_OF_WORK if (!GrannyMeshIsRigid(m_pgrnMesh)) { m_canDeformPNTVertex = true; granny_data_type_definition * pgrnInputType = GrannyGetMeshVertexType(m_pgrnMesh); granny_data_type_definition * pgrnOutputType = m_pgrnMeshType; m_pgrnMeshDeformer = GrannyNewMeshDeformer(pgrnInputType, pgrnOutputType, GrannyDeformPositionNormal, GrannyAllowUncopiedTail); assert(m_pgrnMeshDeformer != NULL && "Cannot create mesh deformer"); } // Two Side Mesh if (!strncmp(m_pgrnMesh->Name, "2x", 2)) m_isTwoSide = true; if (!LoadMaterials(rkMtrlPal)) return false; if (!LoadTriGroupNodeList(rkMtrlPal)) return false; return true; }
////////////////// //Init Functions// ///////////////// void AsteroidGame::Init(void){ input_manager_ = NULL; keyboard_ = NULL; mouse_ = NULL; /* Run all initialization steps */ InitRootNode(); InitPlugins(); InitRenderSystem(); InitWindow(); InitViewport(); InitEvents(); InitOIS(); LoadMaterials(); InitManagers(); iAsteroidManager->createAsteroidField(); iGameState = GameState::Running; }
int Scene::loadScene(const std::string &filename) { reset(); std::string path = std::string(scene_path); path.append(filename); path.append("/"); path.append(filename); std::string::size_type pathLength = path.length(); /*Materials*/ path.append(".mat"); LoadMaterials(path); /*Primitives*/ path.replace(pathLength, 4, ".prm"); LoadPrimitives(path); /*Mesh*/ path.replace(pathLength, 4, ".ra3"); LoadRA3Triangles(path); int numPrim = numtris + numspheres + numdisks; return numPrim; }
bool CSimpleMesh::LoadFromObjFile(char *szFileName) { TArray<VECTOR3Df> m_oVertexArray; TArray<VECTOR3Df> m_oNormalArray; TArray<VECTOR2Df> m_oTextureCoordArray; m_oMaterials.RemoveAll(); m_oMaterialNames.RemoveAll(); m_oSubsetsStartIndex.RemoveAll(); m_oSubsetsMaterialIndex.RemoveAll(); FreeTexureArray(); m_oMaterialsTextureIndex.RemoveAll(); TArray<FACE_STRUCT> oFaceBuffer; #ifdef USE_HASHTABLE_FOR_VERTEX_SEARCH THashTable<FACE_STRUCT> oFaceHash(NUM_KEYS, FACE_STRUCT::GetKey); #endif //USE_HASHTABLE_FOR_VERTEX_SEARCH TArray<unsigned short> oIndexBuffer; DELETE_OBJECT(m_poVB); DELETE_OBJECT(m_poIB); FILE *file = fopen(szFileName, "rt"); if (!file) return false; char szLine[MAX_LINE_LEN]; CString *ppsTokens; int iNumTokens; int iNumIndexes = 0; while (fgets(szLine, MAX_LINE_LEN, file)) { CString sLine(szLine); sLine.ToUpper(); sLine.Tokenize(&ppsTokens, &iNumTokens, sDelimiters); if (iNumTokens == 0) continue; if (ppsTokens[0].Equals("MTLLIB")) { LoadMaterials(ppsTokens[1]); } else if (ppsTokens[0].Equals("VN")) { m_oNormalArray.Append(VECTOR3Df(ppsTokens[1].ToFloat(), ppsTokens[2].ToFloat(), ppsTokens[3].ToFloat())); } else if (ppsTokens[0].Equals("VT")) { m_oTextureCoordArray.Append(VECTOR2Df(ppsTokens[1].ToFloat(), ppsTokens[2].ToFloat())); } else if (ppsTokens[0].Equals("V")) { m_oVertexArray.Append(VECTOR3Df(ppsTokens[1].ToFloat(), ppsTokens[2].ToFloat(), ppsTokens[3].ToFloat())); } else if (ppsTokens[0].Equals("USEMTL")) { int iMaterialIndex = m_oMaterialNames.Find(ppsTokens[1]); m_oSubsetsMaterialIndex.Append(iMaterialIndex); m_oSubsetsStartIndex.Append(oIndexBuffer.GetSize()); } else if (ppsTokens[0].Equals("F")) { struct FACE_STRUCT face; for (int i = 0; i < 3; i++) { face.iVertexIndex = ppsTokens[i * 3 + 1].ToInt() - 1; face.iTextureIndex = ppsTokens[i * 3 + 2].ToInt() - 1; face.iNormalIndex = ppsTokens[i * 3 + 3].ToInt() - 1; #ifndef USE_HASHTABLE_FOR_VERTEX_SEARCH int index = oFaceBuffer.Find(face); if (index == -1) { oIndexBuffer.Append(oFaceBuffer.GetSize()); oFaceBuffer.Append(face); } else { oIndexBuffer.Append(index); } #else FACE_STRUCT *found = oFaceHash.Find(face); if (found) { int index = found->iIndex; oIndexBuffer.Append(index); } else { face.iIndex = iNumIndexes++; oFaceHash.Insert(face); oIndexBuffer.Append(oFaceBuffer.GetSize()); oFaceBuffer.Append(face); } #endif //USE_HASHTABLE_FOR_VERTEX_SEARCH } } SAFE_DELETE_ARRAY(ppsTokens); } m_oSubsetsStartIndex.Append(oIndexBuffer.GetSize()); fclose(file); m_poIB = new CIndexBuffer(oIndexBuffer.GetSize()); memcpy(m_poIB->GetIndexBuffer(), &oIndexBuffer[0], oIndexBuffer.GetSize() * sizeof(unsigned short)); m_bHasTextures = m_oTextures.GetSize() > 0; m_bHasMaterials = m_oMaterials.GetSize() > 0; int iFormat = VERTEXFORMAT_XYZ | VERTEXFORMAT_NORMAL | (m_bHasTextures ? VERTEXFORMAT_TEXTURE : 0); m_poVB = new CVertexBuffer(iFormat, oFaceBuffer.GetSize()); int iIndex = 0, iNumVertex = oFaceBuffer.GetSize(); for (int i = 0; i < iNumVertex; i++) { float *pVertex = (float *)m_poVB->GetVertexAtIndex(i); memcpy(pVertex, &m_oVertexArray[oFaceBuffer[i].iVertexIndex], 3 * sizeof(float)); memcpy(pVertex + 3, &m_oNormalArray[oFaceBuffer[i].iNormalIndex], 3 * sizeof(float)); if (m_bHasTextures) memcpy(pVertex + 6, &m_oTextureCoordArray[oFaceBuffer[i].iTextureIndex], 2 * sizeof(float)); } return true; }
ObjModel::ObjModel(const std::string& filePath) { // standardise dir seperators std::string filePathStd = std::string(filePath); std::replace(filePathStd.begin(), filePathStd.end(), '\\', '/'); // asd/asd/asd/asd/asd/asd/file.obj auto tokens = SplitString(filePathStd, '/'); std::string fileName = tokens[tokens.size() - 1]; std::string workingDir = filePathStd.substr(0, filePathStd.size() - fileName.size()); std::ifstream file; file.open((workingDir + "/" + fileName).c_str()); int curMaterialIndex = 0; std::string line; if (file.is_open()) { while (file.good()) { getline(file, line); unsigned int lineLength = line.length(); if (lineLength < 2) continue; const char* lineCStr = line.c_str(); switch (lineCStr[0]) { case 'v': // "v?" => vertex { switch (lineCStr[1]) { case 't': // ? == 't' => vertex texture / uv coords { #define TEMP_SSCANF // ~5.5 secs //#define TEMP_SPLIT // ~10 secs //#define TEMP_STREAM // ~7.5 secs #ifdef TEMP_SSCANF glm::vec2 vt; sscanf_s(lineCStr, "vt %f %f", &vt.x, &vt.y); textures.push_back(vt); #endif // SSCANF #ifdef TEMP_SPLIT textures.push_back(ParseVec2(line)); #endif // TEMP_SPLIT #ifdef TEMP_STREAM std::istringstream issvt(line.substr(2)); glm::vec2 vt; issvt >> vt.x; issvt >> vt.y; textures.push_back(vt); #endif // TEMP_STREAM break; } case 'n': // ? == 'n' => vertex normal { #ifdef TEMP_SSCANF glm::vec3 vn; sscanf_s(lineCStr, "vn %f %f %f", &vn.x, &vn.y, &vn.z); normals.push_back(vn); #endif // SSCANF #ifdef TEMP_SPLIT normals.push_back(ParseVec3(line)); #endif // TEMP_SPLIT #ifdef TEMP_STREAM std::istringstream issvt(line.substr(2)); glm::vec3 vn; issvt >> vn.x; issvt >> vn.y; issvt >> vn.z; normals.push_back(vn); #endif // TEMP_STREAM break; } case '\t': // ? == ' ' => vertex case ' ': { #ifdef TEMP_SSCANF glm::vec3 v; sscanf_s(lineCStr, "v %f %f %f", &v.x, &v.y, &v.z); positions.push_back(v); #endif // SSCANF #ifdef TEMP_SPLIT positions.push_back(ParseVec3(line)); #endif // TEMP_SPLIT #ifdef TEMP_STREAM std::istringstream issvt(line.substr(2)); glm::vec3 v; issvt >> v.x; issvt >> v.y; issvt >> v.z; positions.push_back(v); #endif // TEMP_STREAM break; } } break; } case 'f': // 'f' => face { CreateFace(curMaterialIndex, line); break; } case 'm': // 'm' => material template lib { if (lineCStr[1] != 't') break; char buffer[BUFSIZ]; sscanf_s(lineCStr, "mtllib %s", &buffer); std::string mtlFileName = std::string(buffer); //std::string mtlFileName = SplitString(line, ' ')[1]; std::vector<Material*> mats = LoadMaterials(workingDir, mtlFileName); materials.insert(std::end(materials), std::begin(mats), std::end(mats)); break; } case 'u': // 'u' => usemtl { if (lineCStr[1] != 's') break; std::string mtlName = SplitString(line, ' ')[1]; for (int i = 0; i < materials.size(); i++) { if (materials[i]->name == mtlName) { curMaterialIndex = i; break; } } break; } }; } } else {
void ModelObj::LoadObj(const char *FileName) { FILE *fp = fopen(FileName,"r"); if (!fp) { return; } pathName = FileName; ObjMesh *newMesh = new ObjMesh(); char ch = 0; char ch2 = 0; char strLine[255] = {0}; char buff[512]; bool faceLoad = false; bool uvFace = false; bool normal = false; while(!feof(fp)) { //get first character ch = fgetc(fp); switch(ch) { case 'm': //material info { char text[100]; char materialName[100]; //read material info fscanf(fp,"%s %s", &text, &materialName); std::string pathName(FileName); size_t found = pathName.find_last_of("/"); pathName = pathName.substr(0,found) + "/" + materialName; LoadMaterials(pathName.c_str()); //read line to the end fgets(strLine, 100, fp); } break; case 'u'://use material { if (faceLoad) { mMeshes.push_back(newMesh); meshCount++; //new newmesh newMesh = new ObjMesh(); faceLoad = false; uvFace = false; normal = false; } char name[50]; char name2[50]; //read material name fscanf(fp,"%s %s", &name, &name2); newMesh->mMaterial = 0; for(unsigned int i = 0;i < mMaterials.size();i++) { if(strcmp(mMaterials[i]->name.c_str(),name2) == 0) { newMesh->mMaterial = i; } } //read line to the end fgets(strLine, 100, fp); } break; case 'g': //mesh name { //read mesh name fscanf(fp," %s", newMesh->name); //read line to the end fgets(strLine, 100, fp); } break; case 'v': //vertex found { //get second character ch2 = fgetc(fp); switch(ch2) { case ' ': { if (faceLoad) { mMeshes.push_back(newMesh); meshCount++; //new newmesh newMesh = new ObjMesh(); faceLoad = false; uvFace = false; normal = false; } //new vertex position Vector3 vPosition; //read vertex info fscanf(fp,"%f %f %f", &vPosition.x, &vPosition.y, &vPosition.z); allVertex.push_back(vPosition); //read line to the end fgets(strLine, 100, fp); } break; case 't': //texture info { uvFace = true; //new uv map ObjUV nObjUV; //read uv map fscanf(fp,"%f %f", &nObjUV.u, &nObjUV.v); allUVMap.push_back(nObjUV); //read line to the end fgets(strLine, 100, fp); } break; case 'n': //normal info { normal = true; //new normal position Vector3 nNormal; //read normal fscanf(fp,"%f %f %f", &nNormal.x, &nNormal.y ,&nNormal.z); allNormal.push_back(nNormal); //read line to the end fgets(strLine, 100, fp); } break; default: break; } } break; case 'f': //face info { faceLoad = true; //new face ObjFace nFace; ObjFace nUVFace; ObjFace nNorm; /* Read whole line */ fgets (buff, sizeof (buff), fp); if (sscanf(buff,"%d/%d/%d %d/%d/%d %d/%d/%d",&nFace.x,&nUVFace.x,&nNorm.x,&nFace.y,&nUVFace.y,&nNorm.y,&nFace.z,&nUVFace.z,&nNorm.z) == 9) { //push UV face to mesh nUVFace.x -=1;nUVFace.y -=1;nUVFace.z -=1; newMesh->mUVFace.push_back(nUVFace); //we must -1 to all indicies nNorm.x -=1;nNorm.y -=1;nNorm.z -=1; //push newMesh->mNormalFace.push_back(nNorm); uvFace = true; normal = true; }else if (sscanf(buff,"%d/%d %d/%d %d/%d",&nFace.x,&nUVFace.x,&nFace.y,&nUVFace.y,&nFace.z,&nUVFace.z) == 6) { //push UV face to mesh nUVFace.x -=1;nUVFace.y -=1;nUVFace.z -=1; newMesh->mUVFace.push_back(nUVFace); uvFace = true; }else { sscanf(buff,"%d %d %d",&nFace.x,&nFace.y,&nFace.z); } //we must -1 to all indicies nFace.x -=1;nFace.y -=1;nFace.z -=1; //push face to mesh newMesh->mFace.push_back(nFace); } break; case '\n': break; default: //read line to the end fgets(strLine, 100, fp); break; } } //ad last submesh or if thhere is only one mMeshes.push_back(newMesh); fclose(fp); //now build vertices in proper way for each platform RenderManager::Instance()->_createModelObjVertices(this); }
/* Функция загрузки геометрического объекта. * АРГУМЕНТЫ: * - геометрический объект: * as4GEOM *G; * - имя файла материалов: * CHAR *FileName; * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: * (BOOL) TRUE при успехе. */ BOOL AS4_GeomLoad( as4GEOM *G, CHAR *FileName ) { INT vn = 0, vtn = 0, vnn = 0, fn = 0, pn = 0, size, i, p; FILE *F; /* читаемые данные */ VEC *ReadV, *ReadN; as4UV *ReadUV; INT (*ReadF)[3]; /* хранение примитивов */ struct { INT First, Last, /* первый и последний номера вершин примитива */ Mtl; /* материал примитива */ } *PrimInfo; memset(G, 0, sizeof(as4GEOM)); /* разбиваем имя на части и открываем файл */ _splitpath(FileName, ModelDrive, ModelDir, ModelFileName, ModelFileExt); if ((F = fopen(FileName, "rt")) == NULL) return FALSE; /* считаем количества */ while (fgets(Buf, sizeof(Buf), F) != NULL) if (Buf[0] == 'v' && Buf[1] == ' ') vn++; else if (Buf[0] == 'v' && Buf[1] == 't') vtn++; else if (Buf[0] == 'v' && Buf[1] == 'n') vnn++; else if (Buf[0] == 'f' && Buf[1] == ' ') fn += Split() - 3; else if (strncmp(Buf, "usemtl", 6) == 0) pn++; if (pn == 0) pn = 1; /* материалы не использовались */ /* загружаем: * вершины vn * нормали vvn * текстурные координаты vtn * треугольники fn * примитивы pn * дополнительно: * индексы (Vv, Vn, Vt) <- новые номера вершин ? (vn + vt + vnn) * ??? * начальные индексы vn */ /* выделяем память под вспомогательные данные */ size = sizeof(VEC) * vn + /* вершины vn */ sizeof(VEC) * vnn + /* нормали vnn */ sizeof(as4UV) * vtn + /* текстурные координаты vtn */ sizeof(INT [3]) * fn + /* треугольники fn */ sizeof(PrimInfo[0]) * pn + /* примитивы pn */ sizeof(VertexRefs[0]) * (vn + vtn + vnn) + /* индексы (Vv, Vn, Vt) (vn + vt + vnn) */ sizeof(INT) * vn; /* начальные индексы vn */ if ((ReadV = malloc(size)) == NULL) { fclose(F); return FALSE; } memset(ReadV, 0, size); /* расставляем указатели */ ReadN = ReadV + vn; ReadUV = (as4UV *)(ReadN + vnn); ReadF = (INT (*)[3])(ReadUV + vtn); VertexRefsStart = (INT *)(ReadF + fn); PrimInfo = (VOID *)(VertexRefsStart + vn); VertexRefs = (VOID *)(PrimInfo + pn); NumOfAllocedVertexRefs = vn + vtn + vnn; NumOfVertexRefs = 0; /* начала списка индексов вершин ==> -1 */ memset(VertexRefsStart, 0xFF, sizeof(INT) * vn); memset(VertexRefs, 0xFF, sizeof(VertexRefs[0]) * NumOfAllocedVertexRefs); /* второй проход - читаем геометрию */ rewind(F); vn = 0; vtn = 0; vnn = 0; fn = 0; pn = 0; PrimInfo[0].First = 0; /* считаем количества */ while (fgets(Buf, sizeof(Buf), F) != NULL) if (Buf[0] == 'v' && Buf[1] == ' ') { FLT x = 0, y = 0, z = 0; sscanf(Buf + 2, "%f%f%f", &x, &y, &z); ReadV[vn++] = VecSet(x, y, z); } else if (Buf[0] == 'v' && Buf[1] == 't') { FLT u = 0, v = 0; sscanf(Buf + 3, "%f%f", &u, &v); ReadUV[vtn++] = AS4_UVSet(u, v); } else if (Buf[0] == 'v' && Buf[1] == 'n') { FLT nx = 0, ny = 0, nz = 0; sscanf(Buf + 3, "%f%f%f", &nx, &ny, &nz); ReadN[vnn++] = VecNormalize(VecSet(nx, ny, nz)); } else if (Buf[0] == 'f' && Buf[1] == ' ') { INT n0[3], n1[3], n[3], r0, r1, r; Split(); SCANF3(Parts[1], n0); r0 = GetVertexNo(n0[0], n0[1], n0[2]); SCANF3(Parts[2], n1); r1 = GetVertexNo(n1[0], n1[1], n1[2]); for (i = 3; i < NumOfParts; i++) { SCANF3(Parts[i], n); r = GetVertexNo(n[0], n[1], n[2]); ReadF[fn][0] = r0; ReadF[fn][1] = r1; ReadF[fn][2] = r; r1 = r; fn++; } } else if (strncmp(Buf, "usemtl", 6) == 0) { Split(); /* запоминаем номер последней грани */ if (pn != 0) PrimInfo[pn - 1].Last = fn - 1; /* ищем материал */ for (i = 0; i < G->NumOfMtls; i++) if (strcmp(Parts[1], G->Mtls[i].Name) == 0) break; if (i == G->NumOfMtls) PrimInfo[pn].Mtl = -1; else PrimInfo[pn].Mtl = i; PrimInfo[pn].First = fn; pn++; } else if (strncmp(Buf, "mtllib ", 7) == 0) { Split(); LoadMaterials(G, Parts[1]); } /* у последнего примитива запоминаем номер последней грани */ if (pn == 0) { PrimInfo[0].Last = fn - 1; PrimInfo[0].Mtl = -1; } else PrimInfo[pn - 1].Last = fn - 1; fclose(F); /* Формируем примитивы из прочитанных данных */ AS4_DefaultColor = ColorSet(1, 1, 1); for (p = 0; p < pn; p++) { INT minv, maxv, j; as4PRIM prim; BOOL is_need_normal = FALSE; minv = maxv = ReadF[PrimInfo[p].First][0]; for (i = PrimInfo[p].First; i <= PrimInfo[p].Last; i++) for (j = 0; j < 3; j++) { if (minv > ReadF[i][j]) minv = ReadF[i][j]; if (maxv < ReadF[i][j]) maxv = ReadF[i][j]; } vn = maxv - minv + 1; fn = PrimInfo[p].Last - PrimInfo[p].First + 1; AS4_PrimCreate(&prim, AS4_PRIM_TRIMESH, vn, fn * 3); /* копируем вершины */ for (i = 0; i < vn; i++) { INT n; prim.V[i].P = ReadV[VertexRefs[minv + i].Nv]; if ((n = VertexRefs[minv + i].Nn) != -1) prim.V[i].N = ReadN[n]; else is_need_normal = TRUE; if ((n = VertexRefs[minv + i].Nt) != -1) prim.V[i].T = ReadUV[n]; } /* копируем грани */ for (i = 0; i < fn; i++) for (j = 0; j < 3; j++) prim.I[i * 3 + j] = ReadF[PrimInfo[p].First + i][j] - minv; if (is_need_normal) AS4_PrimAutoNormals(&prim); prim.Mtl = PrimInfo[p].Mtl; AS4_GeomAddPrim(G, &prim); } /* освобождаем память из-под прочитанных данных */ free(ReadV); return TRUE; } /* End of 'AS4_GeomLoad' function */
std::list< Object* > ObjectLoaderObj::LoadObjects( Instance* instance, File* file ) { fDebug( instance, file ); std::list< Object* > objects; std::string currentName = ""; std::string line; std::stringstream tokenizer; std::stringstream tokenizer2; std::string type; std::string str; std::string str2; float f = 0.0f; std::vector< Vector3f > verts; std::vector< Vector3f > tex; std::vector< Vector3f > norms; Material base_mat; base_mat.diffuse[0] = base_mat.diffuse[1] = base_mat.diffuse[2] = base_mat.diffuse[3]= 1.0f; Material* mat = &base_mat; uint32_t iVert = 0; uint32_t iTex = 0; uint32_t iNorm = 0; uint32_t iFace = 0; verts.reserve( 1024 ); tex.reserve( 1024 ); norms.reserve( 1024 ); std::unordered_map< std::string, uint32_t > elements; Vertex* buff = ( Vertex* )instance->Malloc( sizeof( Vertex ) * 1024 * 1024 ); uint32_t iBuff = 0; uint32_t maxBuff = 1024 * 1024; uint32_t* indices = ( uint32_t* )instance->Malloc( sizeof( uint32_t ) * 128 * 3 * 1024 ); uint32_t iIndices = 0; uint32_t maxIndices = 128 * 3 * 1024; while ( file->ReadLine( line ) ) { tokenizer.clear(); tokenizer.str( line ); type = ""; tokenizer >> type; if ( type == "mtllib" ) { str = ""; tokenizer >> str; LoadMaterials( instance, file, str ); } if ( type == "g" ) { // Insert loaded data if ( elements.size() > 0 ) { gDebug() << "Inserting object " << currentName << "\n"; uint32_t finalVerticesCount = iBuff; Vertex* finalVertices = ( Vertex* )instance->Malloc( sizeof( Vertex ) * iBuff, false ); memcpy( finalVertices, buff, sizeof( Vertex ) * iBuff ); uint32_t finalIndicesCount = iIndices; uint32_t* finalIndices = ( uint32_t* )instance->Malloc( sizeof( uint32_t ) * iIndices, false ); memcpy( finalIndices, indices, sizeof( uint32_t ) * iIndices ); Vector3f center = Vector3f(); for ( uint32_t i = 0; i < iBuff; i++ ) { center = center + Vector3f( finalVertices[i].x, finalVertices[i].y, finalVertices[i].z ) * ( 1.0f / (float)iBuff ); } for ( uint32_t i = 0; i < iBuff; i++ ) { finalVertices[i].x -= center.x; finalVertices[i].y -= center.y; finalVertices[i].z -= center.z; } Object* obj = instance->CreateObject( finalVertices, finalVerticesCount, finalIndices, finalIndicesCount ); obj->matrix()->Translate( center.x, center.y, center.z ); obj->setName( currentName ); if ( mat && mat != &base_mat ) { if ( mat->map_Kd ) obj->setTexture( instance, 0, mat->map_Kd ); // if ( mat->map_bump ) obj->setTexture( instance, 1, mat->map_bump ); } objects.emplace_back( obj ); } elements.clear(); iBuff = 0; iIndices = 0; currentName = ""; tokenizer >> currentName; } if ( type == "usemtl" ) { tokenizer >> str; if ( mMaterials.find( str ) != mMaterials.end() ) { mat = mMaterials[ str ]; } else { mat = &base_mat; } }
Shader* ShadersLoader::LoadFromFile(const std::string& Filename) { TiXmlDocument doc(Filename.c_str()); if (!doc.LoadFile()) { Logger::Log() << "[ERROR] TinyXML error : " << doc.ErrorDesc() << "\n"; throw CLoadingFailed(Filename, "unable to load xml with TinyXML"); } // Get the root TiXmlHandle hdl(&doc); TiXmlElement *root = hdl.FirstChild("Shader").Element(); // Problem to find the root if (!root) { throw CLoadingFailed(Filename, "unable to find root (Shader)"); } // Get the shader name and display it std::string name; std::string shaderTypeName; TinyXMLGetAttributeValue<std::string>(root, "name", &name); TinyXMLGetAttributeValue<std::string>(root, "type", &shaderTypeName); Logger::Log() << "[INFO] Load shader : " << name << " ( " << shaderTypeName << " ) ... \n"; ShaderType shaderType; if (shaderTypeName == "Basic") shaderType = BASIC_SHADER; else if (shaderTypeName == "GBuffer") shaderType = GBUFFER_SHADER; else throw CException("unknow shader type"); // Load the shader compiler config ShaderCompilerConfig config = LoadShaderCompilerConfig(root); // Get the 2 files name // * Vertex shader TiXmlElement *shadername = root->FirstChildElement("VertexShader"); if (!shadername) { throw CLoadingFailed(Filename, "unable to find VertexShader (Shader)"); } std::string vertexShadername = std::string( shadername->Attribute("filename")); Logger::Log() << " * Vertex shader : " << vertexShadername << "\n"; // * Fragment shader shadername = root->FirstChildElement("FragmentShader"); if (!shadername) { throw CLoadingFailed(Filename, "unable to find VertexShader (Shader)"); } std::string fragmentShadername = std::string( shadername->Attribute("filename")); Logger::Log() << " * Fragment shader : " << fragmentShadername << "\n"; /* * Find full path */ vertexShadername = CMediaManager::Instance().FindMedia(vertexShadername).Fullname(); fragmentShadername = CMediaManager::Instance().FindMedia(fragmentShadername).Fullname(); Shader* shader = 0; shadername = root->FirstChildElement("GeometryShader"); if (shadername != 0) { std::string geometryShadername = std::string( shadername->Attribute("filename")); Logger::Log() << " * Geometry shader : " << geometryShadername << "\n"; geometryShadername = CMediaManager::Instance().FindMedia( geometryShadername).Fullname(); std::string in, out; TinyXMLGetAttributeValue(shadername, "in", &in); TinyXMLGetAttributeValue(shadername, "out", &out); shader = CShaderManager::Instance().loadfromFile( vertexShadername.c_str(), fragmentShadername.c_str(), geometryShadername.c_str(), shaderType, config); shader->SetGeometryShaderParameters(OpenGLEnumFromString(in), OpenGLEnumFromString(out)); } else { Logger::Log() << " * No Geometry shader\n"; // Shader creation .... shader = CShaderManager::Instance().loadfromFile( vertexShadername.c_str(), fragmentShadername.c_str(), shaderType, config); } shader->Link(); // Attrib blinding ... LoadShaderAttributs(shader, root); // Textures uniform LoadShaderTextures(shader, root); // Matrix uniform LoadShaderMatrix(shader, root); // FBO LoadShaderFBO(shader, root); // Materials LoadMaterials(shader, root); // Update all bindings // * Warning : Need to relink after shader->UpdateAll(); return shader; }
bool KPModel::LoadFile(void) { char buffer[512]; // buffer for the obj file char mtlfileName[MAX_PATH] = ""; // path to the material library file FILE *mtlfile; // handle of the material library file char materialName[100]; // name of the currently active material UINT v0=0,v1=0,v2=0,vt0=0,vt1=0,vt2=0; // temporary vetrex and vertex texture index ids UINT numVertices = 0, numTextCoords = 0; // temporary data counters UINT numGroups = 0; UINT *numFaces; // tmp counter for faces of each group VERTEX *v = NULL; // tmp vertex and vertex texture coordinate buffers VERTEX *vt = NULL; UINT vi =0, vti = 0, gi = 0; // tmp indexes KPVector vMin, vMax; // Max and min coordinates of the object UINT vCount=0, iCount=0; if (!m_pDevice) return false; numFaces = new UINT[65534]; ZeroMemory(numFaces, sizeof(UINT)*65534); //// // First we have to load the materials and textures //// while ( fgets(buffer, sizeof(buffer), m_pFile) != NULL ) { // Load the Material Libraries ////////////////////////////// // If the line starts with a Material Library definition if ( IsInString(buffer, "mtllib ") == 0 ) { // Get the file path from buffer and open the file sscanf_s(buffer, "mtllib %s", mtlfileName, sizeof(mtlfileName)); // Open the Material Library fopen_s(&mtlfile, mtlfileName, "r"); assert(mtlfile); if ( mtlfile ) { LoadMaterials(mtlfile); fclose(mtlfile); } else return false; } } // ! while loading materials rewind(m_pFile); //// // Count the number of vertex, texture, group and face entries //// while ( fgets(buffer, sizeof(buffer), m_pFile) != NULL ) { if ( buffer[0] == 'v' && buffer[1] == ' ' ) numVertices++; else if ( buffer[0] == 'v' && buffer[1] == 't' ) numTextCoords++; else if ( buffer[0] == 'f' && buffer[1] == ' ' ) { iCount+=3; numFaces[numGroups-1]++; } else if ( IsInString(buffer, "usemtl ") != -1 ) numGroups++; } // ! while vCount = numVertices; rewind(m_pFile); //// // Allocate memory for the arrays //// try { v = new VERTEX[numVertices]; vt = new VERTEX[numTextCoords]; m_pBufferID = new UINT[m_numMaterials]; } catch (std::bad_alloc) { delete[] v; delete[] vt; v = NULL; vt = NULL; return false; } //// // Start reading the data //// while ( fgets(buffer, sizeof(buffer), m_pFile) != NULL ) { if ( buffer[0] == 'v' && buffer[1] == ' ' ) { sscanf_s(buffer, "v %f %f %f", &v[vi].x, &v[vi].y, &v[vi].z); vi++; } else if ( buffer[0] == 'v' && buffer[1] == 't' ) { sscanf_s(buffer, "vt %f %f", &vt[vti].tu, &vt[vti].tv); vti++; } else if ( IsInString(buffer, "usemtl ") != -1 ) { // Now we can allocate vertex and index buffers try { m_numVertices = numFaces[gi]*3; m_pVertices = new VERTEX[m_numVertices]; m_numIndices= m_numVertices; m_pIndices = new WORD[m_numIndices]; } catch (std::bad_alloc) { delete m_pVertices; delete m_pIndices; } // Change the active material to the specified one sscanf_s(buffer, "usemtl %s", materialName, sizeof(materialName)); // Loop through the face entries belonging to this group for ( UINT i = 0; i< numFaces[gi]; ++i ) { // Read new line from file if ( fgets(buffer, sizeof(buffer), m_pFile) != NULL ) { // Fill temprorary variables with face data if ( strstr(buffer, "/") ) sscanf_s(buffer, "f %d/%d %d/%d %d/%d", &v0, &vt0, &v1, &vt1, &v2, &vt2); else sscanf_s(buffer, "f %d %d %d", &v0, &v1, &v2); // Construct the vertices and indices // int idx = i*3; memcpy(&m_pVertices[idx], &v[v0-1], sizeof(VERTEX)); memcpy(&m_pVertices[idx+1], &v[v1-1], sizeof(VERTEX)); memcpy(&m_pVertices[idx+2], &v[v2-1], sizeof(VERTEX)); if ( strstr(buffer, "/") ) { m_pVertices[idx].tu = vt[vt0-1].tu; m_pVertices[idx].tv = vt[vt0-1].tv; m_pVertices[idx+1].tu = vt[vt1-1].tu; m_pVertices[idx+1].tv = vt[vt1-1].tv; m_pVertices[idx+2].tu = vt[vt2-1].tu; m_pVertices[idx+2].tv = vt[vt2-1].tv; } // TODO: Vector normals for better lightning. // Build the vertex index list // m_pIndices[idx] = idx; m_pIndices[idx+1] = idx+1; m_pIndices[idx+2] = idx+2; } // ! if read line } // ! for faces // Add data to the vertex cache manager // if ( ! m_pDevice->GetVertexManager() ) return false; if ( FAILED( m_pDevice->GetVertexManager()->CreateStaticBuffer(VID_UU, m_pSkins[MapMaterial(materialName)], m_numVertices, m_numIndices, m_pVertices, m_pIndices, &m_pBufferID[MapMaterial(materialName)]) ) ) return false; // we are done with this material group, set index to next gi++; delete m_pVertices; m_pVertices = NULL; delete m_pIndices; m_pIndices = NULL; m_numVertices = m_numIndices = 0; } // ! else usemtl } // ! while // Find Min and Max point of the object // Find half length diameter of the bounding box memcpy(&vMin, &v[0], sizeof(float)*3); memcpy(&vMax, &v[0], sizeof(float)*3); for (UINT i=1; i< numVertices; ++i) { if ( vMin.x > v[i].x ) vMin.x = v[i].x; if ( vMin.y > v[i].y ) vMin.y = v[i].y; if ( vMin.z > v[i].z ) vMin.z = v[i].z; if ( vMax.x < v[i].x ) vMax.x = v[i].x; if ( vMax.y < v[i].y ) vMax.y = v[i].y; if ( vMax.z < v[i].z ) vMax.z = v[i].z; } m_vCenter = (vMax + vMin) * 0.5f; m_fHalfLength = ((vMax - vMin) * 0.5f).GetLength(); delete[] numFaces; delete[] v; delete[] vt; v = NULL; vt = NULL; numFaces = NULL; m_numVertices = vCount; m_numIndices = iCount; return true; } // ! LoadFile
bool Animated_Mesh::Load_Assimp(const std::string& file){ const aiScene* load =aiImportFile(file.c_str(), aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_ConvertToLeftHanded ); if(load==NULL) { OUTPUT_DEBUG_MSG("Could not load the Model in Animated_Mesh::Load_MyFormat file: '" + file+"'"); return false; } size_t numverts(0), currentvertex(0), currentindex(0), numindices(0); bool hasbones=false; // go through the mesh counting all the verts and indices that I will need for (unsigned int i = 0; i < load->mNumMeshes;++i) { numverts+=load->mMeshes[i]->mNumVertices; numindices+=load->mMeshes[i]->mNumFaces*3; if(load->mMeshes[i]->HasBones()) hasbones=true; } if(!hasbones) { aiReleaseImport(load);// free the resrouces OUTPUT_DEBUG_MSG("Could not load the Model in Animated_Mesh::Load_MyFormat file: '" + file+"', there were no bones deteected."); return false; } IB.Stride=2; if(numverts >= 65536) IB.Stride=4; Vertices.resize(numverts); Indices.resize((IB.Stride/2)*numindices); std::vector<Vertex_Types::Pos_Tex_Norm_Tang_Bone_Weight> tempverts(numverts); std::vector<std::string> bonenames; for (unsigned int i = 0; i < load->mNumMeshes;++i){ Graphics::Texture diffuse, normal; const aiMesh* mesh = load->mMeshes[i]; if(mesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) { OUTPUT_DEBUG_MSG("There are errors with this submesh, named: "<<mesh->mName.data<<" Please, fix it"); if(mesh->mPrimitiveTypes == aiPrimitiveType_LINE){ OUTPUT_DEBUG_MSG("Problem: The mesh containes lines when it should only contain triangles"); }else { OUTPUT_DEBUG_MSG("Problem: The mesh containes points when it should only contain triangles"); } continue; } if (!mesh->HasTextureCoords(0)) { OUTPUT_DEBUG_MSG("There are errors with this submesh, named: "<<mesh->mName.data<<" Please, fix it"); OUTPUT_DEBUG_MSG("Problem: The mesh containes no texcoords, which means there will just be color displayed. This engine does not support color mesh displays, only textured mesh!"); continue; } if(!mesh->HasTangentsAndBitangents()) { OUTPUT_DEBUG_MSG("There are errors with this submesh, named: "<<mesh->mName.data<<" Please, fix it"); OUTPUT_DEBUG_MSG("Problem: Tangents were not created. No known fix"); continue; } OUTPUT_DEBUG_MSG("Loading "<<mesh->mNumBones<<" bones . . ."); for( unsigned int a = 0; a < mesh->mNumBones; a++) { const aiBone* bone = mesh->mBones[a]; size_t bonein(-1); for(size_t ib(0); ib< bonenames.size(); ib++){ std::string tname = bone->mName.data; if(tname == bonenames[ib]){// found the bone.. break bonein=ib; break; } } if(bonein ==-1){// did not find the bone, this is a new one push back bonein = bonenames.size();// get the index before insertion bonenames.push_back(bone->mName.data); } // there should only be 4 per vertex here because assimp guaranteees it, but if there are more, we are ok for( unsigned int b = 0; b < bone->mNumWeights; b++){ if( tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.x <= 0.f) { tempverts[bone->mWeights[b].mVertexId+ currentvertex].Bones[0] = static_cast<float>(bonein); tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.x = bone->mWeights[b].mWeight; } else if( tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.y <= 0.f){ tempverts[bone->mWeights[b].mVertexId+ currentvertex].Bones[1] = static_cast<float>(bonein); tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.y = bone->mWeights[b].mWeight; } else if( tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.z <= 0.f){ tempverts[bone->mWeights[b].mVertexId+ currentvertex].Bones[2] = static_cast<float>(bonein); tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.z = bone->mWeights[b].mWeight; } else if( tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.w <= 0.f){ tempverts[bone->mWeights[b].mVertexId+ currentvertex].Bones[3] = static_cast<float>(bonein); tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.w = bone->mWeights[b].mWeight; } } } for (unsigned int x = 0; x < mesh->mNumVertices;++x){ Vertices[x + currentvertex] = tempverts[x + currentvertex].Pos = *reinterpret_cast<vec3*>(&mesh->mVertices[x]); tempverts[x + currentvertex].Tex = *reinterpret_cast<vec2*>(&mesh->mTextureCoords[0][x]); tempverts[x + currentvertex].Norm = *reinterpret_cast<vec3*>(&mesh->mNormals[x]); tempverts[x + currentvertex].Tang = *reinterpret_cast<vec3*>(&mesh->mTangents[x]); } // check whether we can use 16 bit indices for our format... the ASSIMPOBLARBLA uses 32 bit indices for all theirs.. if (IB.Stride == 4){ uint32_t* pbData = reinterpret_cast<uint32_t*>(&Indices[currentindex]); for (unsigned int x = 0; x < mesh->mNumFaces;++x){ for (unsigned int a = 0; a < 3 ;++a) { *pbData++ = static_cast<uint32_t>(mesh->mFaces[x].mIndices[a]+ currentvertex); } } } else { uint16_t* pbData = reinterpret_cast<uint16_t*>(&Indices[currentindex]); for (unsigned int x = 0; x < mesh->mNumFaces;++x){ for (unsigned int a = 0; a < 3 ;++a) { *pbData++ = static_cast<uint16_t>(mesh->mFaces[x].mIndices[a]+ currentvertex); } } } //load the textures std::string pathtomodel(GetPath(file)); Batch *batch = new Batch(); LoadMaterials(mesh, load->mMaterials, batch, pathtomodel, Asset_Dir); batch->NumIndices=mesh->mNumFaces*3; batch->StartIndex = static_cast<uint32_t>(currentindex); batch->NumVerts= mesh->mNumVertices; // make sure to increment the ref count for thesse so they are properly destroyed currentvertex+=mesh->mNumVertices; currentindex+=mesh->mNumFaces*3; //For now, there will be a new shader for each material. I will create a shader cache where the graphics lib will cache the shaders and issue out already created shaders like it does with textures. Graphics::Shader_Macro macro1[] = { {"NORMALMAP", "1" }, {"MATRIX_PALETTE_SIZE_DEFAULT", "60" }, {NULL, NULL} }; Graphics::Shader_Macro macro0[] = { {"NORMALMAP", "0" }, {"MATRIX_PALETTE_SIZE_DEFAULT", "60" }, {NULL, NULL} }; Graphics::Shader_Macro* ptr = nullptr; if(batch->Has_NormalMap()) ptr = macro1; else ptr = macro0; batch->GetVS()->CompileShaderFromFile("Animated_Mesh.fx", "VS", "vs_4_0", ptr); FormatDesc lay[] = { FormatDesc(), FormatDesc(TYPE_TEXCOORD, FORMAT_FLOAT, 2), FormatDesc(TYPE_NORMAL, FORMAT_FLOAT, 3), FormatDesc(TYPE_TANGENT, FORMAT_FLOAT, 3), FormatDesc(TYPE_BONE, FORMAT_FLOAT, 4), FormatDesc(TYPE_WEIGHT, FORMAT_FLOAT, 4) }; batch->GetVS()->CreateInputLayout(lay, sizeof(lay)/sizeof(FormatDesc)); batch->GetPS()->CompileShaderFromFile("Animated_Mesh.fx", "PS", "ps_4_0", ptr); Batches.push_back(batch); } Animatior.Init(load); aiReleaseImport(load);// free the resrouces if(currentvertex==0) {// this could happen, if so GET OUTOF HERE OUTPUT_DEBUG_MSG("Problem loading the mesh, there were no vertices loaded. Failed to load the mesh"); return false; } VB[0].Create(currentvertex, sizeof(Vertex_Types::Pos_Tex_Norm_Tang_Bone_Weight), VERTEX_BUFFER, IMMUTABLE, CPU_NONE, &tempverts[0] ); IB.Create(currentindex, IB.Stride, INDEX_BUFFER, IMMUTABLE, CPU_NONE, &Indices[0]); // create index buffer! OUTPUT_DEBUG_MSG("Finished Loading the Mesh"); Name=FileName =file; return true; }