private PhysicallyBasedMaterial CreatePbrMaterial(AssimpMaterial assimpMaterial, string filePath, string customTexturesFolder, bool useStrictFileNameMatch, bool supportDDSTextures)
        {
            PhysicallyBasedMaterial physicallyBasedMaterial;

            if (_dxMaterials.TryGetValue(assimpMaterial, out physicallyBasedMaterial))
            {
                Log($"  Material: {assimpMaterial.Name ?? ""} (already defined)");
                return(physicallyBasedMaterial);
            }

            if (!assimpMaterial.HasTextureDiffuse)
            {
                Log($"  Material {assimpMaterial.Name ?? ""} does not define a diffuse texture");
                return(null);
            }


            Log($"  Material {assimpMaterial.Name ?? ""}:");

            //PhysicallyBasedMaterial physicallyBasedMaterial;
            string diffuseTextureFileName = assimpMaterial.TextureDiffuse.FilePath;

            if (!string.IsNullOrEmpty(customTexturesFolder))
            {
                diffuseTextureFileName = System.IO.Path.Combine(customTexturesFolder, System.IO.Path.GetFileName(diffuseTextureFileName));
            }
            else if (!System.IO.Path.IsPathRooted(diffuseTextureFileName))
            {
                diffuseTextureFileName = System.IO.Path.Combine(filePath, diffuseTextureFileName);
            }

            string folderName = System.IO.Path.GetDirectoryName(diffuseTextureFileName);

            if (!System.IO.Directory.Exists(folderName))
            {
                Log($"  Folder for diffuse texture does not exist: {folderName ?? ""}:");
                return(null);
            }


            if (_folderImageFiles == null)
            {
                _folderImageFiles = new Dictionary <string, string[]>();
            }

            string[] allFilesInFolder;

            if (!_folderImageFiles.TryGetValue(folderName, out allFilesInFolder))
            {
                allFilesInFolder = System.IO.Directory.GetFiles(folderName, "*.*", SearchOption.TopDirectoryOnly);
                _folderImageFiles.Add(folderName, allFilesInFolder);
            }


            string fileNameWithoutKnownSuffix = KnownTextureFiles.GetFileNameWithoutKnownSuffix(diffuseTextureFileName);

            // Get material files that start with the diffuse texture file name without a suffix
            List <string> materialFiles;

            if (useStrictFileNameMatch)
            {
                materialFiles = allFilesInFolder.Where(f => fileNameWithoutKnownSuffix == KnownTextureFiles.GetFileNameWithoutKnownSuffix(f)).ToList();
            }
            else
            {
                materialFiles = allFilesInFolder.Where(f => f.IndexOf(fileNameWithoutKnownSuffix, 0, StringComparison.OrdinalIgnoreCase) != -1).ToList();
            }


            _textureFiles.Clear();

            if (materialFiles.Count == 0)
            {
                Log($"   Folder ({folderName}) for {assimpMaterial.Name ?? ""} material does not define any texture files");
                return(null);
            }
            else
            {
                bool hasDiffuseTexture = false;
                foreach (var materialFile in materialFiles)
                {
                    if (!TextureLoader.IsSupportedFile(materialFile, supportDDSTextures)) // Skip unsupported files
                    {
                        continue;
                    }

                    var textureMapType = KnownTextureFiles.GetTextureType(materialFile);
                    if (textureMapType == TextureMapTypes.Unknown)
                    {
                        if (!hasDiffuseTexture)
                        {
                            textureMapType = TextureMapTypes.DiffuseColor; // First unknown file type is considered to be diffuse texture file
                        }
                        else
                        {
                            continue; // Unknown file type
                        }
                    }

                    bool isDiffuseTexture = (textureMapType == TextureMapTypes.DiffuseColor ||
                                             textureMapType == TextureMapTypes.Albedo ||
                                             textureMapType == TextureMapTypes.BaseColor);

                    string existingTextureFileName;
                    if (_textureFiles.TryGetValue(textureMapType, out existingTextureFileName))
                    {
                        // Map for this texture type already exist
                        var existingFileExtension = System.IO.Path.GetExtension(existingTextureFileName);
                        if (existingFileExtension != null && existingFileExtension.Equals(".dds", StringComparison.OrdinalIgnoreCase))
                        {
                            continue; // DDS texture already found for this texture type - we will use existing dds texture
                        }
                    }


                    hasDiffuseTexture |= isDiffuseTexture;

                    _textureFiles.Add(textureMapType, materialFile);

                    Log("    " + textureMapType + ": " + System.IO.Path.GetFileName(materialFile));
                }

                if (_textureFiles.Count > 0)
                {
                    physicallyBasedMaterial = new PhysicallyBasedMaterial();

                    foreach (var oneTextureFile in _textureFiles)
                    {
                        var textureType = oneTextureFile.Key;
                        var oneFileName = oneTextureFile.Value;

                        ShaderResourceView shaderResourceView;

                        if (!_texturesCache.TryGetValue(oneFileName, out shaderResourceView))
                        {
                            var convertTo32bppPRGBA = (textureType == TextureMapTypes.BaseColor ||
                                                       textureType == TextureMapTypes.Albedo ||
                                                       textureType == TextureMapTypes.DiffuseColor);

                            shaderResourceView = Ab3d.DirectX.TextureLoader.LoadShaderResourceView(MainDXViewportView.DXScene.DXDevice.Device, oneFileName, loadDdsIfPresent: false, convertTo32bppPRGBA: convertTo32bppPRGBA);

                            physicallyBasedMaterial.TextureMaps.Add(new TextureMapInfo((Ab3d.DirectX.Materials.TextureMapTypes)textureType, shaderResourceView, null, oneFileName));

                            _texturesCache.Add(oneFileName, shaderResourceView);
                        }
                    }

                    _dxMaterials.Add(assimpMaterial, physicallyBasedMaterial);
                    _disposables.Add(physicallyBasedMaterial);
                }
            }

            return(physicallyBasedMaterial);
        }
        private void AddPBRTextures(AssimpMaterial assimpMaterial, string filePath, string customTexturesFolder, bool useStrictFileNameMatch, bool supportDDSTextures, PhysicallyBasedMaterial physicallyBasedMaterial)
        {
            //PhysicallyBasedMaterial physicallyBasedMaterial;
            string diffuseTextureFileName = assimpMaterial.TextureDiffuse.FilePath;

            if (!string.IsNullOrEmpty(customTexturesFolder))
            {
                diffuseTextureFileName = System.IO.Path.Combine(customTexturesFolder, System.IO.Path.GetFileName(diffuseTextureFileName));
            }
            else if (!System.IO.Path.IsPathRooted(diffuseTextureFileName))
            {
                diffuseTextureFileName = System.IO.Path.Combine(filePath, diffuseTextureFileName);
            }

            string folderName = System.IO.Path.GetDirectoryName(diffuseTextureFileName);

            if (!System.IO.Directory.Exists(folderName))
            {
                Log($"  Folder for diffuse texture does not exist: {folderName ?? ""}:");
                return;
            }


            if (_folderImageFiles == null)
            {
                _folderImageFiles = new Dictionary <string, string[]>();
            }

            string[] allFilesInFolder;

            if (!_folderImageFiles.TryGetValue(folderName, out allFilesInFolder))
            {
                allFilesInFolder = System.IO.Directory.GetFiles(folderName, "*.*", SearchOption.TopDirectoryOnly);
                _folderImageFiles.Add(folderName, allFilesInFolder);
            }


            //TextureMapTypes textureMapType = KnownTextureFiles.GetTextureType(diffuseTextureFileName);

            string fileNameWithoutKnownSuffix = KnownTextureFiles.GetFileNameWithoutKnownSuffix(diffuseTextureFileName);

            // Get material files that start with the diffuse texture file name without a suffix
            List <string> materialFiles;

            if (useStrictFileNameMatch)
            {
                materialFiles = allFilesInFolder.Where(f => fileNameWithoutKnownSuffix == KnownTextureFiles.GetFileNameWithoutKnownSuffix(f)).ToList();
            }
            else
            {
                materialFiles = allFilesInFolder.Where(f => f.IndexOf(fileNameWithoutKnownSuffix, 0, StringComparison.OrdinalIgnoreCase) != -1).ToList();
            }


            _textureFiles.Clear();

            if (materialFiles.Count == 0)
            {
                Log($"   Folder ({folderName}) for {assimpMaterial.Name ?? ""} material does not define any texture files");
                return;
            }
            else
            {
                bool hasDiffuseTexture = false;
                foreach (var materialFile in materialFiles)
                {
                    if (!TextureLoader.IsSupportedFile(materialFile, supportDDSTextures)) // Skip unsupported files
                    {
                        continue;
                    }

                    var textureMapType = KnownTextureFiles.GetTextureType(materialFile);
                    if (textureMapType == TextureMapTypes.Unknown)
                    {
                        if (!hasDiffuseTexture)
                        {
                            textureMapType = TextureMapTypes.DiffuseColor; // First unknown file type is considered to be diffuse texture file
                        }
                        else
                        {
                            continue; // Unknown file type
                        }
                    }

                    bool isDiffuseTexture = (textureMapType == TextureMapTypes.DiffuseColor ||
                                             textureMapType == TextureMapTypes.Albedo ||
                                             textureMapType == TextureMapTypes.BaseColor);

                    string existingTextureFileName;
                    if (_textureFiles.TryGetValue(textureMapType, out existingTextureFileName))
                    {
                        // Map for this texture type already exist
                        var existingFileExtension = System.IO.Path.GetExtension(existingTextureFileName);
                        if (existingFileExtension != null && existingFileExtension.Equals(".dds", StringComparison.OrdinalIgnoreCase))
                        {
                            continue; // DDS texture already found for this texture type - we will use existing dds texture
                        }
                    }


                    hasDiffuseTexture |= isDiffuseTexture;

                    _textureFiles.Add(textureMapType, materialFile);

                    Log("    " + textureMapType + ": " + System.IO.Path.GetFileName(materialFile));
                }

                if (_textureFiles.Count > 0)
                {
                    foreach (var oneTextureFile in _textureFiles)
                    {
                        var textureType = oneTextureFile.Key;
                        var oneFileName = oneTextureFile.Value;

                        ShaderResourceView shaderResourceView;

                        if (!_texturesCache.TryGetValue(oneFileName, out shaderResourceView))
                        {
                            var isBaseColor = (textureType == TextureMapTypes.BaseColor ||
                                               textureType == TextureMapTypes.Albedo ||
                                               textureType == TextureMapTypes.DiffuseColor);

                            // To load a texture from file, you can use the TextureLoader.LoadShaderResourceView (this supports loading standard image files and also loading dds files).
                            // This method returns a ShaderResourceView and it can also set a textureInfo parameter that defines some of the properties of the loaded texture (bitmap size, dpi, format, hasTransparency).
                            TextureInfo textureInfo;
                            shaderResourceView = Ab3d.DirectX.TextureLoader.LoadShaderResourceView(MainDXViewportView.DXScene.Device,
                                                                                                   oneFileName,
                                                                                                   loadDdsIfPresent: true,
                                                                                                   convertTo32bppPRGBA: isBaseColor,
                                                                                                   generateMipMaps: true,
                                                                                                   textureInfo: out textureInfo);

                            physicallyBasedMaterial.TextureMaps.Add(new TextureMapInfo((Ab3d.DirectX.Materials.TextureMapTypes)textureType, shaderResourceView, null, oneFileName));

                            if (isBaseColor)
                            {
                                // Get recommended BlendState based on HasTransparency and HasPreMultipliedAlpha values.
                                // Possible values are: CommonStates.Opaque, CommonStates.PremultipliedAlphaBlend or CommonStates.NonPremultipliedAlphaBlend.
                                var recommendedBlendState = MainDXViewportView.DXScene.DXDevice.CommonStates.GetRecommendedBlendState(textureInfo.HasTransparency, textureInfo.HasPremultipliedAlpha);

                                physicallyBasedMaterial.BlendState      = recommendedBlendState;
                                physicallyBasedMaterial.HasTransparency = textureInfo.HasTransparency;
                            }


                            _texturesCache.Add(oneFileName, shaderResourceView);
                        }
                    }
                }
            }
        }