/// <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> /// 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.MeshAndTextureReplacement) { 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> /// 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; } }