Exemplo n.º 1
0
        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;
}