Exemple #1
0
        /// <summary>
        /// Gets terrain albedo texture array containing each terrain tile in a seperate array slice.
        /// </summary>
        /// <param name="archive">Archive index.</param>
        /// <param name="stayReadable">Texture should stay readable.</param>
        /// <param name="nonAlphaFormat">Non-alpha TextureFormat.</param>
        /// <returns>Texture2DArray or null</returns>
        public Texture2DArray GetTerrainAlbedoTextureArray(
            int archive,
            bool stayReadable = false,
            SupportedNonAlphaTextureFormats nonAlphaFormat = SupportedNonAlphaTextureFormats.RGB24)
        {
            // Load texture file and check count matches terrain tiles
            TextureFile textureFile = new TextureFile(Path.Combine(Arena2Path, TextureFile.IndexToFileName(archive)), FileUsage.UseMemory, true);
            int         numSlices   = 0;

            if (textureFile.RecordCount == 56)
            {
                numSlices = textureFile.RecordCount;
            }
            else
            {
                return(null);
            }

            Texture2DArray textureArray;

            if (TextureReplacement.CustomTextureExist(archive, 0, 0))
            {
                GetTextureResults results = new GetTextureResults();
                TextureReplacement.LoadCustomTextureResults(archive, 0, 0, ref results, ref DaggerfallUnity.Instance.MaterialReader.GenerateNormals);
                textureArray = new Texture2DArray(results.albedoMap.width, results.albedoMap.height, numSlices, ParseTextureFormat(nonAlphaFormat), MipMaps);
            }
            else
            {
                textureArray = new Texture2DArray(textureFile.GetWidth(0), textureFile.GetWidth(1), numSlices, ParseTextureFormat(nonAlphaFormat), MipMaps);
            }

            // Rollout tiles into texture array
            for (int record = 0; record < textureFile.RecordCount; record++)
            {
                // Create base image with gutter
                DFSize    sz;
                Color32[] albedo = textureFile.GetColor32(record, 0, -1, 0, out sz);


                // Import custom texture(s)
                GetTextureResults resultsTile = new GetTextureResults();
                if (TextureReplacement.CustomTextureExist(archive, record, 0))
                {
                    TextureReplacement.LoadCustomTextureResults(archive, record, 0, ref resultsTile, ref DaggerfallUnity.Instance.MaterialReader.GenerateNormals);
                    albedo = resultsTile.albedoMap.GetPixels32();
                }

                // Insert into texture array
                textureArray.SetPixels32(albedo, record, 0);
            }
            textureArray.Apply(true, !stayReadable);

            // Change settings for these textures
            textureArray.wrapMode   = TextureWrapMode.Clamp;
            textureArray.anisoLevel = 8;

            return(textureArray);
        }
        /// <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 = 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);

            // Import custom textures
            TextureReplacement.LoadCustomTextureResults(archive, record, frame, ref results, ref GenerateNormals);

            rectOut = results.singleRect;

            // Create material
            Material 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
            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");
            }

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

            materialDict.Add(key, newcm);

            return(material);
        }