示例#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);
        }
示例#2
0
        /// <summary>
        /// Gets Unity Material atlas from Daggerfall texture archive.
        /// </summary>
        /// <param name="archive">Archive index to create atlas from.</param>
        /// <param name="alphaIndex">Index to receive transparent alpha.</param>
        /// <param name="padding">Number of pixels each sub-texture.</param>
        /// <param name="maxAtlasSize">Max size of atlas.</param>
        /// <param name="rectsOut">Array of rects, one for each record sub-texture and frame.</param>
        /// <param name="indicesOut">Array of record indices into rect array, accounting for animation frames.</param>
        /// <param name="border">Number of pixels internal border around each texture.</param>
        /// <param name="dilate">Blend texture into surrounding empty pixels.</param>
        /// <param name="shrinkUVs">Number of pixels to shrink UV rect.</param>
        /// <param name="copyToOppositeBorder">Copy texture edges to opposite border. Requires border, will overwrite dilate.</param>
        /// <param name="isBillboard">Set true when creating atlas material for simple billboards.</param>
        /// <returns>Material or null.</returns>
        public Material GetMaterialAtlas(
            int archive,
            int alphaIndex,
            int padding,
            int maxAtlasSize,
            out Rect[] rectsOut,
            out RecordIndex[] indicesOut,
            int border                = 0,
            bool dilate               = false,
            int shrinkUVs             = 0,
            bool copyToOppositeBorder = false,
            bool isBillboard          = false)
        {
            // Ready check
            if (!IsReady)
            {
                rectsOut   = null;
                indicesOut = null;
                return(null);
            }

            int key = MakeTextureKey((short)archive, (byte)0, (byte)0, AtlasKeyGroup);

            if (materialDict.ContainsKey(key))
            {
                CachedMaterial cm = GetMaterialFromCache(key);
                if (cm.filterMode == MainFilterMode)
                {
                    // Properties are the same
                    rectsOut   = cm.atlasRects;
                    indicesOut = cm.atlasIndices;
                    return(cm.material);
                }
                else
                {
                    // Properties don't match, remove material and reload
                    materialDict.Remove(key);
                }
            }

            // Create material
            Material material;

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

            // Create settings
            GetTextureSettings settings = TextureReader.CreateTextureSettings(archive, 0, 0, alphaIndex, border, dilate);

            settings.createNormalMap      = GenerateNormals;
            settings.autoEmission         = true;
            settings.atlasShrinkUVs       = shrinkUVs;
            settings.atlasPadding         = padding;
            settings.atlasMaxSize         = maxAtlasSize;
            settings.copyToOppositeBorder = copyToOppositeBorder;

            // Setup material
            material.name = string.Format("TEXTURE.{0:000} [Atlas]", archive);
            GetTextureResults results = textureReader.GetTexture2DAtlas(settings, AlphaTextureFormat);

            material.mainTexture            = results.albedoMap;
            material.mainTexture.filterMode = MainFilterMode;

            // Setup normal map
            if (GenerateNormals && results.normalMap != null)
            {
                results.normalMap.filterMode = MainFilterMode;
                material.SetTexture(Uniforms.BumpMap, results.normalMap);
                material.EnableKeyword(KeyWords.NormalMap);
            }

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

            // TEMP: Bridging between legacy material out params and GetTextureResults for now
            Vector2[] sizesOut, scalesOut, offsetsOut;
            sizesOut   = results.atlasSizes.ToArray();
            scalesOut  = results.atlasScales.ToArray();
            offsetsOut = results.atlasOffsets.ToArray();
            rectsOut   = results.atlasRects.ToArray();
            indicesOut = results.atlasIndices.ToArray();

            // Setup cached material
            CachedMaterial newcm = new CachedMaterial();

            newcm.key              = key;
            newcm.keyGroup         = AtlasKeyGroup;
            newcm.atlasRects       = rectsOut;
            newcm.atlasIndices     = indicesOut;
            newcm.material         = material;
            newcm.filterMode       = MainFilterMode;
            newcm.recordSizes      = sizesOut;
            newcm.recordScales     = scalesOut;
            newcm.recordOffsets    = offsetsOut;
            newcm.atlasFrameCounts = results.atlasFrameCounts.ToArray();
            materialDict.Add(key, newcm);

            return(material);
        }
示例#3
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>
        /// <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)
        {
            // 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 = materialDict[key];
                rectOut = cm.singleRect;
                return(cm.material);
            }

            // 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
            GetTextureResults results = textureReader.GetTexture2D(settings, AlphaTextureFormat, NonAlphaTextureFormat);

            rectOut = results.singleRect;

            // Setup material
            Material material = CreateStandardMaterial();

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

            // Setup normal map
            if (GenerateNormals && results.normalMap != null)
            {
                results.normalMap.filterMode = MainFilterMode;
                material.SetTexture("_BumpMap", results.normalMap);
                material.EnableKeyword("_NORMALMAP");
            }

            // Setup emission map
            if (results.isEmissive && !results.isWindow && results.emissionMap != null)
            {
                results.emissionMap.filterMode = MainFilterMode;
                material.SetTexture("_EmissionMap", results.emissionMap);
                material.SetColor("_EmissionColor", Color.white);
                material.EnableKeyword("_EMISSION");
            }
            else if (results.isEmissive && results.isWindow && results.emissionMap != null)
            {
                results.emissionMap.filterMode = MainFilterMode;
                material.SetTexture("_EmissionMap", results.emissionMap);
                material.SetColor("_EmissionColor", DayWindowColor * DayWindowIntensity);
                material.EnableKeyword("_EMISSION");
            }

            // 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,
                material         = material,
                filterMode       = MainFilterMode,
                isWindow         = results.isWindow,
                recordSizes      = recordSizes,
                recordScales     = recordScales,
                recordOffsets    = recordOffsets,
                singleFrameCount = results.textureFile.GetFrameCount(record),
            };

            materialDict.Add(key, newcm);

            return(material);
        }