Esempio n. 1
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);
        }
Esempio n. 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="rectsOut">Array of rects, one for each record sub-texture and frame.</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="shader">Shader for material. If null, DefaultShaderName will be applied.</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,
            Shader shader             = null)
        {
            // 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 = materialDict[key];
                if (cm.filterMode == MainFilterMode)
                {
                    // Properties are the same
                    rectsOut   = cm.atlasRects;
                    indicesOut = cm.indices;
                    return(cm.material);
                }
                else
                {
                    // Properties don't match, remove material and reload
                    materialDict.Remove(key);
                }
            }

            if (shader == null)
            {
                shader = Shader.Find(DefaultShaderName);
            }

            Vector2[] sizesOut, scalesOut, offsetsOut;
            Material  material = new Material(shader);

            material.name = string.Format("TEXTURE.{0:000} [Atlas]", archive);
            Texture2D texture = textureReader.GetTexture2DAtlas(
                archive,
                alphaIndex,
                padding,
                maxAtlasSize,
                out rectsOut,
                out indicesOut,
                out sizesOut,
                out scalesOut,
                out offsetsOut,
                border,
                dilate,
                shrinkUVs,
                copyToOppositeBorder);

            material.mainTexture            = texture;
            material.mainTexture.filterMode = MainFilterMode;

            CachedMaterial newcm = new CachedMaterial();

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

            return(material);
        }