wxString wxPathList::FindAbsoluteValidPath (const wxString& file) const { wxString f = FindValidPath(file); if ( f.empty() || wxIsAbsolutePath(f) ) return f; wxString buf = ::wxGetCwd(); if ( !wxEndsWithPathSeparator(buf) ) { buf += wxFILE_SEP_PATH; } buf += f; return buf; }
//------------------------------------------------------------------------------- int CMaterialManager::LoadTexture(TextureID* p_ppiOut,aiString* szPath) { //???ai_assert(-1 != *p_ppiOut); ai_assert(0 != szPath); *p_ppiOut = -1; #if 1 LOG_PRINT("szPath=%s\n", szPath); // first get a valid path to the texture if( 5 == FindValidPath(szPath)) { // embedded file. Find its index unsigned int iIndex = atoi(szPath->data+1); if (iIndex < mr->GetAsset()->pcScene->mNumTextures) { /* if (0 == mr->GetAsset()->pcScene->mTextures[iIndex]->mHeight) { // it is an embedded file ... don't need the file format hint, // simply let D3DXFROMWINE load the file if (FAILED(D3DXFROMWINECreateTextureFromFileInMemoryEx(mr->m_piDevice, mr->GetAsset()->pcScene->mTextures[iIndex]->pcData, mr->GetAsset()->pcScene->mTextures[iIndex]->mWidth, D3DXFROMWINE_DEFAULT, D3DXFROMWINE_DEFAULT, 0, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DXFROMWINE_DEFAULT, D3DXFROMWINE_DEFAULT, 0, 0, 0, p_ppiOut))) { std::string sz = "[ERROR] Unable to load embedded texture (#1): "; sz.append(szPath->data); //CLogDisplay::Instance().AddEntry(sz,D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); this->SetDefaultTexture(p_ppiOut); return 1; } } else*/ { // fill a new texture ... Image3 img; BYTE* dst=img.create( FORMAT_RGBA8,//??? mr->GetAsset()->pcScene->mTextures[iIndex]->mWidth, mr->GetAsset()->pcScene->mTextures[iIndex]->mHeight,1,1); //BYTE* dst=img.getPixels(); // now copy the data to it ... (assume non pow2 to be supported) //D3DLOCKED_RECT sLock; // sLock.pBits=IRenderer::GetRendererInstance()->LockTexture(*p_ppiOut, 0, sLock.Pitch); const aiTexel* pcData = mr->GetAsset()->pcScene->mTextures[iIndex]->pcData; for (unsigned int y = 0; y < mr->GetAsset()->pcScene->mTextures[iIndex]->mHeight;++y) { stx_memcpy(dst,pcData,mr->GetAsset()->pcScene->mTextures[iIndex]-> mWidth *sizeof(aiTexel)); dst = (BYTE *)dst + 4*mr->GetAsset()->pcScene->mTextures[iIndex]->mWidth; pcData += mr->GetAsset()->pcScene->mTextures[iIndex]->mWidth; } // IRenderer::GetRendererInstance()->UnlockTexture(*p_ppiOut, 0); // (*p_ppiOut)->GenerateMipSubLevels(); *p_ppiOut=IRenderer::GetRendererInstance()->addTexture( &img, false, IRenderer::GetRendererInstance()->Getlinear() ,STATIC); } return 1; } else { std::string sz = "[ERROR] Invalid index for embedded texture: "; sz.append(szPath->data); //CLogDisplay::Instance().AddEntry(sz,D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); SetDefaultTexture(p_ppiOut); return 1; } } ////LOG_PRINT("mr->m_piDevice=%x\n", mr->m_piDevice); //DBG_HALT; // then call D3DXFROMWINE to load the texture //D3DFMT_A8R8G8B8, #endif std::string f1=szPath->data; LOG_FNLN; LOG_PRINT("Assimp Mesh Texture:%s\n", f1.c_str()); #if 1 *p_ppiOut=//IRenderer::GetRendererInstance()-> IRenderer::GetRendererInstance()->addImageLibTexture( f1.c_str(), false, IRenderer::GetRendererInstance()->Getlinear() ,STATIC ); #else Image3 img; if (img.loadImageLibImage(szPath->data, false)) { img.createMipMaps(); *p_ppiOut=IRenderer::GetRendererInstance()->addTexture(&img,false, IRenderer::GetRendererInstance()->Getlinear(),STATIC,0.0f,false); } #endif return 1; }
//------------------------------------------------------------------------------- int CMaterialManager::LoadTexture(IDirect3DTexture9** p_ppiOut,aiString* szPath) { ai_assert(NULL != p_ppiOut); ai_assert(NULL != szPath); *p_ppiOut = NULL; const std::string s = szPath->data; TextureCache::iterator ff; if ((ff = sCachedTextures.find(s)) != sCachedTextures.end()) { *p_ppiOut = (*ff).second; (*p_ppiOut)->AddRef(); return 1; } // first get a valid path to the texture if( 5 == FindValidPath(szPath)) { // embedded file. Find its index unsigned int iIndex = atoi(szPath->data+1); if (iIndex < g_pcAsset->pcScene->mNumTextures) { if (0 == g_pcAsset->pcScene->mTextures[iIndex]->mHeight) { // it is an embedded file ... don't need the file format hint, // simply let D3DX load the file D3DXIMAGE_INFO info; if (FAILED(D3DXCreateTextureFromFileInMemoryEx(g_piDevice, g_pcAsset->pcScene->mTextures[iIndex]->pcData, g_pcAsset->pcScene->mTextures[iIndex]->mWidth, D3DX_DEFAULT, D3DX_DEFAULT, 1, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, &info, NULL, p_ppiOut))) { std::string sz = "[ERROR] Unable to load embedded texture (#1): "; sz.append(szPath->data); CLogDisplay::Instance().AddEntry(sz,D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); this->SetDefaultTexture(p_ppiOut); return 1; } } else { // fill a new texture ... if(FAILED(g_piDevice->CreateTexture( g_pcAsset->pcScene->mTextures[iIndex]->mWidth, g_pcAsset->pcScene->mTextures[iIndex]->mHeight, 0,D3DUSAGE_AUTOGENMIPMAP,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,p_ppiOut,NULL))) { std::string sz = "[ERROR] Unable to load embedded texture (#2): "; sz.append(szPath->data); CLogDisplay::Instance().AddEntry(sz,D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); this->SetDefaultTexture(p_ppiOut); return 1; } // now copy the data to it ... (assume non pow2 to be supported) D3DLOCKED_RECT sLock; (*p_ppiOut)->LockRect(0,&sLock,NULL,0); const aiTexel* pcData = g_pcAsset->pcScene->mTextures[iIndex]->pcData; for (unsigned int y = 0; y < g_pcAsset->pcScene->mTextures[iIndex]->mHeight;++y) { memcpy(sLock.pBits,pcData,g_pcAsset->pcScene->mTextures[iIndex]-> mWidth *sizeof(aiTexel)); sLock.pBits = (char*)sLock.pBits + sLock.Pitch; pcData += g_pcAsset->pcScene->mTextures[iIndex]->mWidth; } (*p_ppiOut)->UnlockRect(0); (*p_ppiOut)->GenerateMipSubLevels(); } sCachedTextures[s] = *p_ppiOut; (*p_ppiOut)->AddRef(); return 1; } else { std::string sz = "[ERROR] Invalid index for embedded texture: "; sz.append(szPath->data); CLogDisplay::Instance().AddEntry(sz,D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); SetDefaultTexture(p_ppiOut); return 1; } } // then call D3DX to load the texture if (FAILED(D3DXCreateTextureFromFileEx( g_piDevice, szPath->data, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, p_ppiOut))) { // error ... use the default texture instead std::string sz = "[ERROR] Unable to load texture: "; sz.append(szPath->data); CLogDisplay::Instance().AddEntry(sz,D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); this->SetDefaultTexture(p_ppiOut); } sCachedTextures[s] = *p_ppiOut; (*p_ppiOut)->AddRef(); return 1; }
//! Loads and returns a skinned model from a file. SkinnedModel* ModelImporter::LoadSkinnedModel(string filename) { // Is the model already loaded? if(mSkinnedModelMap.find(filename) != mSkinnedModelMap.end()) return mSkinnedModelMap[filename]; Assimp::Importer importer; mFilename = filename; SkinnedModel* model = NULL; // Important! Makes sure that if the angle between two face normals is > 80 they are not smoothed together. // Since the angle between a cubes face normals is 90 the lighting looks very bad if we don't specify this. importer.SetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.0f); importer.SetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 1); importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE); // Load scene from the file. const aiScene* scene = importer.ReadFile(filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_SplitLargeMeshes | aiProcess_ConvertToLeftHanded | aiProcess_SortByPType); if(scene) { // Create the model that is getting filled out. model = new SkinnedModel(); // Create the animator. SceneAnimator* animator = new SceneAnimator(); animator->Init(scene); model->SetAnimator(animator); // Loop through all meshes. for(int j = 0; j < scene->mNumMeshes; j++) { aiMesh* assimpMesh = scene->mMeshes[j]; // Calculate vertex weight and bone indices. vector<Weights> weights = CalculateWeights(assimpMesh, animator); vector<SkinnedVertex> vertices; vector<UINT> indices; // Add vertices to the vertex list. for(int i = 0; i < assimpMesh->mNumVertices; i++) { aiVector3D v = assimpMesh->mVertices[i]; aiVector3D n = assimpMesh->mNormals[i]; aiVector3D t = aiVector3D(0, 0, 0); if(assimpMesh->HasTextureCoords(0)) t = assimpMesh->mTextureCoords[0][i]; n = n.Normalize(); // Pos, normal and texture coordinates. SkinnedVertex vertex(v.x, v.y, v.z, n.x, n.y, n.z, 0, 0, 1, t.x, t.y); // Bone indices and weights. for(int k = 0; k < weights[i].boneIndices.size(); k++) vertex.BoneIndices[k] = weights[i].boneIndices[k]; vertex.Weights.x = weights[i].weights.size() >= 1 ? weights[i].weights[0] : 0; vertex.Weights.y = weights[i].weights.size() >= 2 ? weights[i].weights[1] : 0; vertex.Weights.z = weights[i].weights.size() >= 3 ? weights[i].weights[2] : 0; vertices.push_back(vertex); } // Add indices to the index list. for(int i = 0; i < assimpMesh->mNumFaces; i++) for(int k = 0; k < assimpMesh->mFaces[i].mNumIndices; k++) indices.push_back(assimpMesh->mFaces[i].mIndices[k]); // Get the path to the texture in the directory. aiString path; aiMaterial* material = scene->mMaterials[assimpMesh->mMaterialIndex]; material->Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path); FindValidPath(&path); // Extract all the ambient, diffuse and specular colors. aiColor4D ambient, diffuse, specular; material->Get(AI_MATKEY_COLOR_AMBIENT, ambient); material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); material->Get(AI_MATKEY_COLOR_SPECULAR, specular); // Create the mesh and its primitive. SkinnedMesh* mesh = new SkinnedMesh(); Primitive* primitive = new Primitive(GlobalApp::GetD3DDevice(), vertices, indices); mesh->SetPrimitive(primitive); mesh->SetVertices(vertices); mesh->SetIndices(indices); mPrimtiveFactory->AddPrimitive(path.C_Str(), primitive); // Replace .tga with .bmp [HACK]. string texturePath = path.C_Str(); int tgaPos = texturePath.find_first_of(".tga"); if(tgaPos != string::npos) { texturePath.replace(texturePath.size()-4, 4, ".bmp"); path = texturePath; } // Any texture? if(_stricmp(path.C_Str(), "") != 0) mesh->LoadTexture(path.C_Str()); // Any normal map? aiString nmap; material->Get(AI_MATKEY_TEXTURE_HEIGHT(0), nmap); FindValidPath(&nmap); if(_stricmp(nmap.C_Str(), "") != 0) mesh->SetNormalMap(GlobalApp::GetGraphics()->LoadTexture(nmap.C_Str())); // [NOTE] The material is set to white. mesh->SetMaterial(Material(Colors::White)); //mesh->SetMaterial(Material(diffuse, diffuse, diffuse)); model->SetFilename(filename); // Add the mesh to the model. model->AddMesh(mesh); } // Pre-calculate the bounding box. model->CalculateAABB(); // Add the newly created mesh to the map and return it. mSkinnedModelMap[filename] = model; return mSkinnedModelMap[filename]; } else { char buffer[246]; sprintf(buffer, "Error loading model: %s", filename.c_str()); MessageBox(0, buffer, "Error!", 0); mSkinnedModelMap[filename] = LoadSkinnedModel("models/box.obj"); return mSkinnedModelMap[filename]; } }
//! Loads and returns a static model from a file. StaticModel* ModelImporter::LoadStaticModel(string filename) { // Is the model already loaded? if(mStaticModelMap.find(filename) != mStaticModelMap.end()) return mStaticModelMap[filename]; Assimp::Importer importer; mFilename = filename; StaticModel* model = NULL; // Important! Makes sure that if the angle between two face normals is > 80 they are not smoothed together. // Since the angle between a cubes face normals is 90 the lighting looks very bad if we don't specify this. importer.SetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.0f); importer.SetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 1); importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE); // Load scene from the file. const aiScene* scene = importer.ReadFile(filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_SplitLargeMeshes | aiProcess_ConvertToLeftHanded | aiProcess_SortByPType); // Successfully loaded the scene. if(scene) { // Create the model that is getting filled out. model = new StaticModel(); // Loop through all meshes. for(int i = 0; i < scene->mNumMeshes; i++) { aiMesh* assimpMesh = scene->mMeshes[i]; vector<Vertex> vertices; vector<UINT> indices; // Add vertices to the vertex list. for(int i = 0; i < assimpMesh->mNumVertices; i++) { aiVector3D v = assimpMesh->mVertices[i]; aiVector3D n = assimpMesh->mNormals[i]; aiVector3D t = aiVector3D(0, 0, 0); if(assimpMesh->HasTextureCoords(0)) t = assimpMesh->mTextureCoords[0][i]; n = n.Normalize(); Vertex vertex(v.x, v.y, v.z, n.x, n.y, n.z, 0, 0, 0, t.x, t.y); vertices.push_back(vertex); } // Add indices to the index list. for(int i = 0; i < assimpMesh->mNumFaces; i++) for(int j = 0; j < assimpMesh->mFaces[i].mNumIndices; j++) indices.push_back(assimpMesh->mFaces[i].mIndices[j]); // Get the path to the texture in the directory. aiString path; aiMaterial* material = scene->mMaterials[assimpMesh->mMaterialIndex]; material->Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path); FindValidPath(&path); // Extract all the ambient, diffuse and specular colors. aiColor4D ambient, diffuse, specular; material->Get(AI_MATKEY_COLOR_AMBIENT, ambient); material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); material->Get(AI_MATKEY_COLOR_SPECULAR, specular); // Create the mesh and its primitive. StaticMesh* mesh = new StaticMesh(); Primitive* primitive = new Primitive(GlobalApp::GetD3DDevice(), vertices, indices); mesh->SetPrimitive(primitive); mesh->SetVertices(vertices); mesh->SetIndices(indices); mPrimtiveFactory->AddPrimitive(path.C_Str(), primitive); // Any texture? if(_stricmp(path.C_Str(), "") != 0) mesh->LoadTexture(path.C_Str()); // Any normal map? aiString nmap; material->Get(AI_MATKEY_TEXTURE_HEIGHT(0), nmap); FindValidPath(&nmap); if(_stricmp(nmap.C_Str(), "") != 0) mesh->SetNormalMap(GlobalApp::GetGraphics()->LoadTexture(nmap.C_Str())); // [NOTE] The material is set to white. mesh->SetMaterial(Material(Colors::White)); // Was before [NOTE] model->SetFilename(filename); // Add the mesh to the model. model->AddMesh(mesh); } // Add to the model map and return it. mStaticModelMap[filename] = model; return mStaticModelMap[filename]; } else { char buffer[246]; sprintf(buffer, "Error loading model: %s", filename.c_str()); MessageBox(0, buffer, "Error!", 0); mStaticModelMap[filename] = LoadStaticModel("models/box.obj"); return mStaticModelMap[filename]; } }