std::vector<Path> QueryDirectory(const Path &path, const Pred& predicate) { std::vector<Path> result; auto pathStr = path.ToShortString(); auto dp = opendir(pathStr.c_str()); if (dp == nullptr) { throw NotADirectoryException(); } struct dirent *entry; while ((entry = readdir(dp))) { std::string fileName(entry->d_name); if ((fileName == ".") || (fileName == "..")) { continue; } std::wstring wideFileName(fileName.begin(), fileName.end()); struct stat st; if (stat((pathStr + "/" + fileName).c_str(), &st) == 0) { if (predicate(wideFileName, st)) { result.push_back(Path(wideFileName)); } } } closedir(dp); return result; }
Model *HalflingModelFile::Load(ID3D11Device *device, Engine::TextureManager *textureManager, Engine::MaterialShaderManager *materialShaderManager, Engine::MaterialCache *materialCache, Graphics::SamplerStateManager *samplerStateManager, const wchar *filePath) { // Read the entire file into memory DWORD bytesRead; char *fileBuffer = Common::ReadWholeFile(filePath, &bytesRead); if (fileBuffer == NULL) { return NULL; } Common::MemoryInputStream fin(fileBuffer, bytesRead); // Read in the file data // Check that this is a 'HFM' file uint32 fileId; fin.readUInt32(&fileId); if (fileId != MKTAG('\0', 'F', 'M', 'H')) { return NULL; } // File format version byte fileFormatVersion; fin.readByte(&fileFormatVersion); assert(fileFormatVersion == kFileFormatVersion); // Flags uint64 flags; fin.readUInt64(&flags); // String table std::string *stringTable = nullptr; if ((flags & HAS_STRING_TABLE) == HAS_STRING_TABLE) { uint32 numStrings; fin.readUInt32(&numStrings); stringTable = new std::string[numStrings]; for (uint i = 0; i < numStrings; ++i) { uint16 stringLength; fin.readUInt16(&stringLength); // Read in the string characters stringTable[i].resize(stringLength + 1); // Allow space for the null terminator fin.read(&stringTable[i][0], stringLength); // Manually create the null terminator stringTable[i][stringLength] = '\0'; } } // Num vertices uint32 numVertices; fin.readUInt32(&numVertices); // Num indices uint32 numIndices; fin.readUInt32(&numIndices); // Num vertex elements // TODO: Do we want to store this? // Vertex buffer desc D3D11_BUFFER_DESC vertexBufferDesc; fin.read((char *)&vertexBufferDesc, sizeof(D3D11_BUFFER_DESC)); // Index buffer desc D3D11_BUFFER_DESC indexBufferDesc; fin.read((char *)&indexBufferDesc, sizeof(D3D11_BUFFER_DESC)); // Vertex data char *vertexData = new char[vertexBufferDesc.ByteWidth]; fin.read(vertexData, vertexBufferDesc.ByteWidth); // Index data char *indexData = new char[indexBufferDesc.ByteWidth]; fin.read(indexData, indexBufferDesc.ByteWidth); // Material table MaterialTableData *materialTable = nullptr; if ((flags & HAS_MATERIAL_TABLE) == HAS_MATERIAL_TABLE) { uint32 numMaterials; fin.readUInt32(&numMaterials); materialTable = new MaterialTableData[numMaterials]; for (uint i = 0; i < numMaterials; ++i) { fin.readUInt32(&materialTable[i].HMATFilePathIndex); uint32 numTextures; fin.readUInt32(&numTextures); for (uint j = 0; j < numTextures; ++j) { TextureData data; fin.readUInt32(&data.FilePathIndex); fin.readByte(&data.Sampler); materialTable[i].Textures.push_back(data); } } } // Num subsets uint32 numSubsets; fin.readUInt32(&numSubsets); // Subset data Subset *subsets = new Subset[numSubsets]; fin.read((char *)subsets, sizeof(Subset) * numSubsets); // Process the subsets ModelSubset *modelSubsets = new ModelSubset[numSubsets]; for (uint i = 0; i < numSubsets; ++i) { ZeroMemory(&modelSubsets[i], sizeof(ModelSubset)); modelSubsets[i].VertexStart = subsets[i].VertexStart; modelSubsets[i].VertexCount = subsets[i].VertexCount; modelSubsets[i].IndexStart = subsets[i].IndexStart; modelSubsets[i].IndexCount = subsets[i].IndexCount; modelSubsets[i].AABB_min = subsets[i].AABB_min; modelSubsets[i].AABB_max = subsets[i].AABB_max; MaterialTableData materialData = materialTable[subsets[i].MaterialIndex]; std::wstring hmatFilePath = Common::ToWideStr(stringTable[materialData.HMATFilePathIndex]); Graphics::MaterialShader *shader = materialShaderManager->GetShader(device, hmatFilePath); std::vector<ID3D11ShaderResourceView *> textureSRVs; std::vector<ID3D11SamplerState *> textureSamplers; for (uint j = 0; j < materialData.Textures.size(); ++j) { std::wstring wideFileName(stringTable[materialData.Textures[j].FilePathIndex].begin(), stringTable[materialData.Textures[j].FilePathIndex].end()); textureSRVs.push_back(textureManager->GetSRVFromFile(device, wideFileName, D3D11_USAGE_IMMUTABLE)); textureSamplers.push_back(GetSamplerStateFromSamplerType(static_cast<TextureSampler>(materialData.Textures[j].Sampler), samplerStateManager)); } modelSubsets[i].Material = materialCache->getMaterial(shader, textureSRVs, textureSamplers); } // Cleanup delete[] stringTable; delete[] materialTable; delete[] subsets; // Create the model with the read data Model *model = new Model(); model->CreateVertexBuffer(device, vertexData, numVertices, vertexBufferDesc); model->CreateIndexBuffer(device, (uint *)indexData, numIndices, indexBufferDesc); model->CreateSubsets(modelSubsets, numSubsets); return model; }