Ejemplo n.º 1
0
        /// <summary>
        /// Gets Unity Material from Daggerfall texture with more options.
        /// </summary>
        /// <param name="archive">Archive index.</param>
        /// <param name="record">Record index.</param>
        /// <param name="frame">Frame index.</param>
        /// <param name="rectOut">Receives UV rect for texture inside border.</param>
        /// <param name="borderSize">Number of pixels internal border around each texture.</param>
        /// <param name="dilate">Blend texture into surrounding empty pixels.</param>
        /// <param name="isBillboard">Set true when creating atlas material for simple billboards.</param>
        /// <returns>Material or null.</returns>
        public Material GetMaterial(
            int archive,
            int record,
            int frame,
            int alphaIndex,
            out Rect rectOut,
            int borderSize   = 0,
            bool dilate      = false,
            bool isBillboard = false)
        {
            // Ready check
            if (!IsReady)
            {
                rectOut = new Rect();
                return(null);
            }

            // Try to retrieve from cache
            int key = MakeTextureKey((short)archive, (byte)record, (byte)frame);

            if (materialDict.ContainsKey(key))
            {
                CachedMaterial cm = GetMaterialFromCache(key);
                rectOut = cm.singleRect;
                return(cm.material);
            }

            Material          material;
            GetTextureResults results;

            // Try to import a material from mods, otherwise create a standard material
            // and import textures from Daggerfall files and loose files.
            if (!TextureReplacement.TextureExistsAmongLooseFiles(archive, record, frame) &&
                TextureReplacement.TryImportMaterial(archive, record, frame, out material))
            {
                results = TextureReplacement.MakeResults(material, archive, record);
                TextureReplacement.AssignFiltermode(material);
            }
            else
            {
                // Create new texture settings
                GetTextureSettings settings = TextureReader.CreateTextureSettings(archive, record, frame, alphaIndex, borderSize, dilate);
                settings.autoEmissionForWindows = true;
                settings.sharpen = Sharpen;
                if (GenerateNormals)
                {
                    settings.createNormalMap = true;
                    settings.normalStrength  = NormalTextureStrength;
                }

                // Set emissive for self-illuminated textures
                if (textureReader.IsEmissive(archive, record))
                {
                    settings.createEmissionMap = true;
                    settings.emissionIndex     = -1;
                }

                // Get texture
                results = textureReader.GetTexture2D(settings, AlphaTextureFormat, TextureImport.LooseFiles);

                // Create material
                if (isBillboard)
                {
                    material = CreateStandardMaterial(CustomBlendMode.Cutout);
                }
                else
                {
                    material = CreateStandardMaterial();
                }

                // Setup material
                material.name                   = FormatName(archive, record);
                material.mainTexture            = results.albedoMap;
                material.mainTexture.filterMode = MainFilterMode;

                // Setup normal map
                bool importedNormals = TextureReplacement.TextureExistsAmongLooseFiles(settings.archive, settings.record, settings.frame, TextureMap.Normal);
                if ((GenerateNormals || importedNormals) && results.normalMap != null)
                {
                    results.normalMap.filterMode = MainFilterMode;
                    material.SetTexture(Uniforms.BumpMap, results.normalMap);
                    material.EnableKeyword(KeyWords.NormalMap);
                }

                // Setup emission map
                if (results.isEmissive && !results.isWindow && results.emissionMap != null)
                {
                    results.emissionMap.filterMode = MainFilterMode;
                    material.SetTexture(Uniforms.EmissionMap, results.emissionMap);
                    material.SetColor(Uniforms.EmissionColor, Color.white);
                    material.EnableKeyword(KeyWords.Emission);
                }
                else if (results.isEmissive && results.isWindow && results.emissionMap != null)
                {
                    results.emissionMap.filterMode = MainFilterMode;
                    material.SetTexture(Uniforms.EmissionMap, results.emissionMap);
                    material.SetColor(Uniforms.EmissionColor, DayWindowColor * DayWindowIntensity);
                    material.EnableKeyword(KeyWords.Emission);
                }

                // Import additional custom components of material
                TextureReplacement.CustomizeMaterial(archive, record, frame, material);
            }

            // Setup cached material
            DFSize     size   = results.textureFile.GetSize(record);
            DFSize     scale  = results.textureFile.GetScale(record);
            DFPosition offset = results.textureFile.GetOffset(record);

            Vector2[] recordSizes = new Vector2[1] {
                new Vector2(size.Width, size.Height)
            };
            Vector2[] recordScales = new Vector2[1] {
                new Vector2(scale.Width, scale.Height)
            };
            Vector2[] recordOffsets = new Vector2[1] {
                new Vector2(offset.X, offset.Y)
            };
            CachedMaterial newcm = new CachedMaterial()
            {
                key              = key,
                keyGroup         = 0,
                albedoMap        = results.albedoMap,
                normalMap        = results.normalMap,
                emissionMap      = results.emissionMap,
                singleRect       = rectOut = results.singleRect,
                material         = material,
                filterMode       = MainFilterMode,
                isWindow         = results.isWindow,
                recordSizes      = recordSizes,
                recordScales     = recordScales,
                recordOffsets    = recordOffsets,
                singleFrameCount = results.textureFile.GetFrameCount(record),
                framesPerSecond  = archive == FireWallsArchive ? 5 : 0, // Slow down fire walls
            };

            materialDict.Add(key, newcm);

            return(material);
        }