Пример #1
0
        /// <summary>
        /// Set custom material on billboard gameobject.
        /// </summary>
        /// <paran name="go">Billboard gameobject.</param>
        /// <param name="archive">Archive index.</param>
        /// <param name="record">Record index.</param>
        static public void SetBillboardCustomMaterial(GameObject go, ref DaggerfallBillboard.BillboardSummary summary)
        {
            // Variables
            int numberOfFrames;
            int archive = summary.Archive;
            int record  = summary.Record;
            //string name = GetName(archive, record);
            var       meshRenderer = go.GetComponent <MeshRenderer>();
            Texture2D albedoTexture, emissionMap;

            // Check if billboard is emissive
            bool isEmissive = meshRenderer.material.GetTexture("_EmissionMap");

            // UVs
            Vector2 uv = Vector2.zero;

            // Get properties from Xml
            string path = Path.Combine(texturesPath, GetName(archive, record));

            if (XMLManager.XmlFileExists(path))
            {
                var xml = new XMLManager(path);

                // Set billboard scale
                Transform transform = go.GetComponent <Transform>();
                transform.localScale = xml.GetVector3("scaleX", "scaleY", transform.localScale);
                summary.Size.x      *= transform.localScale.x;
                summary.Size.y      *= transform.localScale.y;

                // Get UV
                uv = xml.GetVector2("uvX", "uvY", uv);
            }

            // Update UV
            SetUv(go.GetComponent <MeshFilter>(), uv.x, uv.y);

            // Get material from cache or import from disk
            MaterialReader materialReader = DaggerfallUnity.Instance.MaterialReader;
            CachedMaterial cachedMaterialOut;

            if (materialReader.GetCachedMaterialCustomBillboard(archive, record, 0, out cachedMaterialOut))
            {
                // Get and set material
                meshRenderer.material = cachedMaterialOut.material;

                // Get other properties
                numberOfFrames = cachedMaterialOut.singleFrameCount;
                albedoTexture  = cachedMaterialOut.albedoMap;
                emissionMap    = cachedMaterialOut.emissionMap;
            }
            else
            {
                // Get textures from disk
                LoadCustomBillboardFrameTexture(isEmissive, out albedoTexture, out emissionMap, archive, record);

                // Main texture
                meshRenderer.material.SetTexture("_MainTex", albedoTexture);

                // Emission maps for lights
                if (isEmissive)
                {
                    meshRenderer.material.SetTexture("_EmissionMap", emissionMap);
                }

                // Get number of frames on disk
                numberOfFrames = NumberOfAvailableFrames(archive, record);

                // Save material in cache
                CachedMaterial newcm = new CachedMaterial()
                {
                    albedoMap        = albedoTexture,
                    emissionMap      = emissionMap,
                    material         = meshRenderer.material,
                    singleFrameCount = numberOfFrames
                };
                materialReader.SetCachedMaterialCustomBillboard(archive, record, 0, newcm);
            }

            // Import textures for each frame if billboard is animated
            summary.CustomBillboard = new CustomBillboard();
            summary.CustomBillboard.isCustomAnimated = numberOfFrames > 1;
            if (summary.CustomBillboard.isCustomAnimated)
            {
                List <Texture2D> albedoTextures = new List <Texture2D>();
                List <Texture2D> emissionmaps   = new List <Texture2D>();

                // Frame zero
                albedoTextures.Add(albedoTexture);
                if (isEmissive)
                {
                    emissionmaps.Add(emissionMap);
                }

                // Other frames
                for (int frame = 1; frame < numberOfFrames; frame++)
                {
                    if (materialReader.GetCachedMaterialCustomBillboard(archive, record, frame, out cachedMaterialOut))
                    {
                        // Get textures from cache
                        albedoTexture = cachedMaterialOut.albedoMap;
                        emissionMap   = cachedMaterialOut.emissionMap;
                    }
                    else
                    {
                        // Get textures from disk
                        LoadCustomBillboardFrameTexture(isEmissive, out albedoTexture, out emissionMap, archive, record, frame);

                        // Save textures in cache
                        CachedMaterial newcm = new CachedMaterial()
                        {
                            albedoMap   = albedoTexture,
                            emissionMap = emissionMap,
                        };
                        materialReader.SetCachedMaterialCustomBillboard(archive, record, frame, newcm);
                    }

                    albedoTextures.Add(albedoTexture);
                    if (isEmissive)
                    {
                        emissionmaps.Add(emissionMap);
                    }
                }

                // Set textures and properties
                summary.CustomBillboard.MainTexture    = albedoTextures;
                summary.CustomBillboard.EmissionMap    = emissionmaps;
                summary.CustomBillboard.NumberOfFrames = numberOfFrames;
                summary.CustomBillboard.isEmissive     = isEmissive;
            }
        }
        /// <summary>
        /// Import textures and emission maps for all frames of this billboard. Also set other material properties from xml.
        /// </summary>
        public static void SetBillboardImportedTextures(GameObject go, ref DaggerfallBillboard.BillboardSummary summary)
        {
            if (!DaggerfallUnity.Settings.AssetInjection)
            {
                return;
            }

            MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>();

            int  archive    = summary.Archive;
            int  record     = summary.Record;
            int  frame      = 0;
            bool isEmissive = DaggerfallUnity.Instance.MaterialReader.TextureReader.IsEmissive(archive, record);

            // Check first frame
            Texture2D albedo, emission;
            bool      hasImportedTextures = LoadFromCacheOrImport(archive, record, frame, isEmissive, out albedo, out emission);

            if (summary.ImportedTextures.HasImportedTextures = hasImportedTextures)
            {
                // Set texture on material
                meshRenderer.material.SetTexture(Uniforms.MainTex, albedo);
                if (isEmissive)
                {
                    meshRenderer.material.SetTexture(Uniforms.EmissionMap, emission);
                }

                // Import animation frames
                var albedoTextures   = new List <Texture2D>();
                var emissionTextures = new List <Texture2D>();
                do
                {
                    albedoTextures.Add(albedo);
                    if (isEmissive)
                    {
                        emissionTextures.Add(emission);
                    }
                }while (LoadFromCacheOrImport(archive, record, ++frame, isEmissive, out albedo, out emission));

                // Set scale and uv
                Vector2    uv = Vector2.zero;
                XMLManager xml;
                if (XMLManager.TryReadXml(texturesPath, GetName(archive, record), out xml))
                {
                    // Set billboard scale
                    Transform transform = go.GetComponent <Transform>();
                    transform.localScale = xml.GetVector3("scaleX", "scaleY", transform.localScale);
                    summary.Size.x      *= transform.localScale.x;
                    summary.Size.y      *= transform.localScale.y;

                    // Get UV
                    uv = xml.GetVector2("uvX", "uvY", uv);
                }
                SetUv(go.GetComponent <MeshFilter>(), uv.x, uv.y);

                // Save results
                summary.ImportedTextures.FrameCount = frame;
                summary.ImportedTextures.IsEmissive = isEmissive;
                summary.ImportedTextures.Albedo     = albedoTextures;
                summary.ImportedTextures.Emission   = emissionTextures;
            }
        }
        /// <summary>
        /// Gets a custom material for a static billboard with textures and configuration imported from mods.
        /// </summary>
        /// <param name="go">The billboard object.</param>
        /// <param name="archive">Archive index.</param>
        /// <param name="record">Record index.</param>
        /// <param name="summary">Summary data of the billboard object.</param>
        /// <remarks>
        /// Seek the texture for the first frame of the given record. If found, it imports all other frames.
        /// Always creates an emission map for textures marked as emissive by TextureReader, import emission maps for others only if available.
        /// </remarks>
        /// <returns>A material or null.</returns>
        public static Material GetStaticBillboardMaterial(GameObject go, int archive, int record, ref DaggerfallBillboard.BillboardSummary summary)
        {
            if (!DaggerfallUnity.Settings.AssetInjection)
            {
                return(null);
            }

            MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>();
            int          frame        = 0;

            Texture2D albedo, emission;

            if (summary.ImportedTextures.HasImportedTextures = LoadFromCacheOrImport(archive, record, frame, true, true, out albedo, out emission))
            {
                bool isEmissive = emission || DaggerfallUnity.Instance.MaterialReader.TextureReader.IsEmissive(archive, record);

                // Read xml configuration
                Vector2    uv         = Vector2.zero;
                string     renderMode = null;
                XMLManager xml;
                if (XMLManager.TryReadXml(texturesPath, GetName(archive, record), out xml))
                {
                    xml.TryGetString("renderMode", out renderMode);
                    isEmissive |= xml.GetBool("emission");

                    // Set billboard scale
                    Transform transform = go.GetComponent <Transform>();
                    transform.localScale = xml.GetVector3("scaleX", "scaleY", transform.localScale);
                    summary.Size.x      *= transform.localScale.x;
                    summary.Size.y      *= transform.localScale.y;

                    // Get UV
                    uv = xml.GetVector2("uvX", "uvY", uv);
                }

                // Make material
                Material material = MakeBillboardMaterial(renderMode);
                summary.Rect = new Rect(uv.x, uv.y, 1 - 2 * uv.x, 1 - 2 * uv.y);

                // Set textures on material; emission is always overriden, with actual texture or null.
                material.SetTexture(Uniforms.MainTex, albedo);
                material.SetTexture(Uniforms.EmissionMap, isEmissive ? emission ?? albedo : null);
                ToggleEmission(material, isEmissive);

                // Import animation frames
                var albedoTextures   = new List <Texture2D>();
                var emissionTextures = isEmissive ? new List <Texture2D>() : null;
                do
                {
                    albedoTextures.Add(albedo);
                    if (isEmissive)
                    {
                        emissionTextures.Add(emission ?? albedo);
                    }
                }while (LoadFromCacheOrImport(archive, record, ++frame, isEmissive, true, out albedo, out emission));

                // Save results
                summary.ImportedTextures.FrameCount = frame;
                summary.ImportedTextures.IsEmissive = isEmissive;
                summary.ImportedTextures.Albedo     = albedoTextures;
                summary.ImportedTextures.Emission   = emissionTextures;

                return(material);
            }

            return(null);
        }
        /// <summary>
        /// Gets a custom material for a mobile billboard with textures and configuration imported from mods.
        /// </summary>
        /// <param name="archive">Archive index.</param>
        /// <param name="meshFilter">The MeshFilter of the billboard object.</param>
        /// <param name="importedTextures">All the imported textures for the archive.</param>
        /// <remarks>
        /// Seek the texture for the first frame of the first record. If found, it imports the entire archive.
        /// If this texture has an emission map the material is considered emissive and all emission maps are imported.
        /// </remarks>
        /// <returns>A material or null.</returns>
        public static Material GetMobileBillboardMaterial(int archive, MeshFilter meshFilter, ref MobileBillboardImportedTextures importedTextures)
        {
            if (!DaggerfallUnity.Settings.AssetInjection)
            {
                return(null);
            }

            Texture2D tex, emission;

            if (importedTextures.HasImportedTextures = LoadFromCacheOrImport(archive, 0, 0, true, true, out tex, out emission))
            {
                string renderMode = null;

                // Read xml configuration
                XMLManager xml;
                if (XMLManager.TryReadXml(ImagesPath, string.Format("{0:000}", archive), out xml))
                {
                    xml.TryGetString("renderMode", out renderMode);
                    importedTextures.IsEmissive = xml.GetBool("emission");
                }

                // Make material
                Material material = MakeBillboardMaterial(renderMode);

                // Enable emission
                ToggleEmission(material, importedTextures.IsEmissive |= emission != null);

                // Load texture file to get record and frame count
                string fileName    = TextureFile.IndexToFileName(archive);
                var    textureFile = new TextureFile(Path.Combine(DaggerfallUnity.Instance.Arena2Path, fileName), FileUsage.UseMemory, true);

                // Import all textures in this archive
                importedTextures.Albedo       = new Texture2D[textureFile.RecordCount][];
                importedTextures.EmissionMaps = importedTextures.IsEmissive ? new Texture2D[textureFile.RecordCount][] : null;
                for (int record = 0; record < textureFile.RecordCount; record++)
                {
                    int frames            = textureFile.GetFrameCount(record);
                    var frameTextures     = new Texture2D[frames];
                    var frameEmissionMaps = importedTextures.IsEmissive ? new Texture2D[frames] : null;

                    for (int frame = 0; frame < frames; frame++)
                    {
                        if (record != 0 || frame != 0)
                        {
                            LoadFromCacheOrImport(archive, record, frame, importedTextures.IsEmissive, true, out tex, out emission);
                        }

                        frameTextures[frame] = tex ?? ImageReader.GetTexture(fileName, record, frame, true);
                        if (frameEmissionMaps != null)
                        {
                            frameEmissionMaps[frame] = emission ?? frameTextures[frame];
                        }
                    }

                    importedTextures.Albedo[record] = frameTextures;
                    if (importedTextures.EmissionMaps != null)
                    {
                        importedTextures.EmissionMaps[record] = frameEmissionMaps;
                    }
                }

                // Update UV map
                SetUv(meshFilter);

                return(material);
            }

            return(null);
        }
Пример #5
0
        /// <summary>
        /// Set custom material on billboard gameobject.
        /// </summary>
        /// <paran name="go">Billboard gameobject.</param>
        /// <param name="archive">Archive index.</param>
        /// <param name="record">Record index.</param>
        static public void SetBillboardCustomMaterial(GameObject go, int archive, int record)
        {
            int       numberOfFrames;
            string    name = GetName(archive, record);
            var       meshRenderer = go.GetComponent <MeshRenderer>();
            var       daggerfallBillboard = go.GetComponent <DaggerfallBillboard>();
            Texture2D albedoTexture, emissionMap;

            // Check if billboard is emissive
            bool isEmissive = false;

            if (meshRenderer.material.GetTexture("_EmissionMap") != null)
            {
                isEmissive = true;
            }

            // UVs
            Vector2 uv = Vector2.zero;

            // Get properties from Xml
            if (XMLManager.XmlFileExist(archive, record))
            {
                // Customize billboard size (scale)
                Transform transform = go.GetComponent <Transform>();
                transform.localScale = XMLManager.GetScale(name, texturesPath, transform.localScale);
                daggerfallBillboard.SetCustomSize(archive, record, transform.localScale.y);

                // Get UV
                uv = XMLManager.GetUv(name, texturesPath, uv.x, uv.y);
            }

            // Update UV
            UpdateUV(go.GetComponent <MeshFilter>(), uv.x, uv.y);

            // Get material from cache or import from disk
            MaterialReader materialReader = DaggerfallUnity.Instance.MaterialReader;
            CachedMaterial cachedMaterialOut;

            if (materialReader.GetCachedMaterialCustomBillboard(archive, record, 0, out cachedMaterialOut))
            {
                // Get and set material
                meshRenderer.material = cachedMaterialOut.material;

                // Get other properties
                numberOfFrames = cachedMaterialOut.singleFrameCount;
                albedoTexture  = cachedMaterialOut.albedoMap;
                emissionMap    = cachedMaterialOut.emissionMap;
            }
            else
            {
                // Get textures from disk
                LoadCustomBillboardFrameTexture(isEmissive, out albedoTexture, out emissionMap, archive, record);

                // Main texture
                meshRenderer.material.SetTexture("_MainTex", albedoTexture);

                // Emission maps for lights
                if (isEmissive)
                {
                    meshRenderer.material.SetTexture("_EmissionMap", emissionMap);
                }

                // Get number of frames on disk
                numberOfFrames = NumberOfAvailableFrames(archive, record);

                // Save material in cache
                CachedMaterial newcm = new CachedMaterial()
                {
                    albedoMap        = albedoTexture,
                    emissionMap      = emissionMap,
                    material         = meshRenderer.material,
                    singleFrameCount = numberOfFrames
                };
                materialReader.SetCachedMaterialCustomBillboard(archive, record, 0, newcm);
            }

            // Import textures for each frame if billboard is animated
            if (numberOfFrames > 1)
            {
                List <Texture2D> albedoTextures = new List <Texture2D>();
                List <Texture2D> emissionmaps   = new List <Texture2D>();

                // Frame zero
                albedoTextures.Add(albedoTexture);
                if (isEmissive)
                {
                    emissionmaps.Add(emissionMap);
                }

                // Other frames
                for (int frame = 1; frame < numberOfFrames; frame++)
                {
                    if (materialReader.GetCachedMaterialCustomBillboard(archive, record, frame, out cachedMaterialOut))
                    {
                        // Get textures from cache
                        albedoTexture = cachedMaterialOut.albedoMap;
                        emissionMap   = cachedMaterialOut.emissionMap;
                    }
                    else
                    {
                        // Get textures from disk
                        LoadCustomBillboardFrameTexture(isEmissive, out albedoTexture, out emissionMap, archive, record, frame);

                        // Save textures in cache
                        CachedMaterial newcm = new CachedMaterial()
                        {
                            albedoMap   = albedoTexture,
                            emissionMap = emissionMap,
                        };
                        materialReader.SetCachedMaterialCustomBillboard(archive, record, frame, newcm);
                    }

                    albedoTextures.Add(albedoTexture);
                    if (isEmissive)
                    {
                        emissionmaps.Add(emissionMap);
                    }
                }

                // Set textures and properties
                CustomBillboard customBillboard = new CustomBillboard()
                {
                    MainTexture    = albedoTextures,
                    EmissionMap    = emissionmaps,
                    NumberOfFrames = numberOfFrames,
                    isEmissive     = isEmissive
                };
                daggerfallBillboard.SetCustomMaterial(customBillboard);
            }
        }