Skip to content

Commit

Permalink
feat: Reimpl badgemaker, fix tools page, increase tab instantiation s…
Browse files Browse the repository at this point in the history
…tability
  • Loading branch information
benaclejames committed May 20, 2024
1 parent 4406206 commit 6a5ef33
Show file tree
Hide file tree
Showing 15 changed files with 156 additions and 68 deletions.
19 changes: 19 additions & 0 deletions BadgeMaker/BadgeMaker.asmdef
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "BadgeMaker",
"rootNamespace": "Furality.Editor.Tools.BadgeMaker",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"Magick.NET-Q8-x64.dll",
"Magick.NET.Core.dll"
],
"autoReferenced": false,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
143 changes: 96 additions & 47 deletions BadgeMaker/Editor/BadgeMaker.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,53 @@
// Copyright Furality, Inc. 2023
// Copyright Furality, Inc. 2024

using System;
using System.Collections.Generic;
using System.IO;
using ImageMagick;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace Furality.Editor.Tools.BadgeMaker
{
{
public class BadgeMaker : EditorWindow
{
private static readonly Dictionary<string, Dictionary<string, MagickColor>> ConventionsToColors = new Dictionary<string, Dictionary<string, MagickColor>>()
{
{"Furality Umbra", new Dictionary<string, MagickColor>()
{
{"Attendee", new MagickColor("#37ff79")},
{"First Class", new MagickColor("#fe3fff")},
{"Sponsor", new MagickColor("#ffce49")}
}}
};

[DllImport("Gdi32.dll")]
private static extern int AddFontResourceEx(string lpFileName, uint fl, IntPtr pdv);

[DllImport("Gdi32.dll")]
private static extern bool RemoveFontResourceEx(string lpFileName, uint fl, IntPtr pdv);

private string _badgeName = "Your Name";
private string _pronouns = "(Any Pronouns)";
private string _pronouns = "Title/Pronouns";
private int _badgeTier = -1;
private int _badgeConvention = -1;
private bool _applyToMaterial = true;

// Name Bounds
private const int NameX = 2048, NameY = 1304;
private const int NameX = 2048, NameY = 1504;
private const int NameWidth = 3208, NameHeight = 855;

// Pronouns Bounds
private const int PronounsX = 2048, PronounsY = 1717;
private const int PronounsX = 2048, PronounsY = 1917;
private const int PronounsWidth = 1554, PronounsHeight = 257;

private string FontPath => Application.persistentDataPath + "/Fonts/";

private const string TitleFontName = "Rowdies-Light.ttf";
private const string PronounsFontName = "Rowdies-Regular.ttf";

[DllImport("Gdi32.dll")]
private static extern int AddFontResourceEx(string lpFileName, uint fl, IntPtr pdv);

[DllImport("Gdi32.dll")]
private static extern bool RemoveFontResourceEx(string lpFileName, uint fl, IntPtr pdv);
private const string TitleFontName = "Roboto-BoldItalic.ttf";
private const string PronounsFontName = "Roboto-BoldItalic.ttf";


[MenuItem("Furality/Show Badge Maker")]
Expand All @@ -47,12 +60,17 @@ static void Init()
window.Show();
}

private void OnDestroy()
private void UnloadFonts()
{
RemoveFontResourceEx(FontPath + TitleFontName, 0, IntPtr.Zero);
RemoveFontResourceEx(FontPath + PronounsFontName, 0, IntPtr.Zero);
}

private void OnDestroy() => UnloadFonts();

string MakeBadgeFolder(string convention, string tier) =>
"Assets/Furality/" + convention + "/Avatar Assets/Badges/" + tier;

void OnGUI()
{
GUILayout.BeginHorizontal();
Expand All @@ -63,17 +81,30 @@ void OnGUI()

GUILayout.Space(10);

string[] folders =
AssetDatabase.GetSubFolders("Assets/Furality/Furality Sylva/Avatar Assets/Badges");
string[] tierNames = folders.Select(folder => folder.Split('/')[folder.Split('/').Length - 1]).ToArray();
List<string> tierNames = new List<string>();
List<string> conventionNames = new List<string>();
var conventionFolders = AssetDatabase.GetSubFolders("Assets/Furality");
foreach (var conventionFolder in conventionFolders)
{
var tiers = AssetDatabase.GetSubFolders(Path.Combine(conventionFolder, "Avatar Assets/Badges"));
if (tiers.Length == 0) continue;

var splitConventionFolder = conventionFolder.Split('/');
tierNames.AddRange(tiers.Select(tier => tier.Split('/')[^1]));
conventionNames.Add(splitConventionFolder[^1]);
}

// If our selected tier is -1, this is the first time we open the window, so we select the highest tier (this doesn't work too well for people with multiple tiers but works well enough)
if (_badgeTier == -1)
_badgeTier = tierNames.Length - 1;
_badgeTier = tierNames.Count - 1;

if (_badgeConvention == -1)
_badgeConvention = conventionNames.Count - 1;

// If there were no folders found, show a warning saying that you need badges imported
if (folders.Length == 0)
if (tierNames.Count == 0 || conventionNames.Count == 0)
{
EditorGUILayout.HelpBox("No badges found! Please import the badges from the Furality Luma Festival package.", MessageType.Warning);
EditorGUILayout.HelpBox("No badges found! Please download badges from the downloads tab.", MessageType.Warning);
return;
}

Expand All @@ -82,48 +113,65 @@ void OnGUI()
_pronouns = EditorGUILayout.TextField("Title", _pronouns);

// Create a dropdown menu for the badge type but only show the folder name
_badgeTier = EditorGUILayout.Popup("Badge Type", _badgeTier, tierNames);

// get the path to the currently selected folder + Textures
string folderPath = folders[_badgeTier] + "/Texture/";

// By default (pin), we just need to select image name tierName+_Empty.png
string fileName = tierNames[_badgeTier] + "_Empty";
_badgeTier = EditorGUILayout.Popup("Badge Type", _badgeTier, tierNames.ToArray());
_badgeConvention = EditorGUILayout.Popup("Convention", _badgeConvention, conventionNames.ToArray());

// Checkbox to apply the new texture to the material
_applyToMaterial = EditorGUILayout.Toggle("Auto-Apply to Base Material", _applyToMaterial);

// Button to create the badge
if (GUILayout.Button("Create Badge"))
{
if (!ConventionsToColors.ContainsKey(conventionNames[_badgeConvention]))
{
Debug.LogError("Convention could not be found in color map. Quitting BadgeMaker");
return;
}

if (!ConventionsToColors[conventionNames[_badgeConvention]].ContainsKey(tierNames[_badgeTier]))
{
Debug.LogError("Badge tier could not be found in color map. Quitting BadgeMaker");
return;
}

var textColor = ConventionsToColors[conventionNames[_badgeConvention]][tierNames[_badgeTier]];

EditorUtility.DisplayProgressBar("Creating Badge", "Loading Font...", 0.125f);

// get the path to the currently selected folder + Textures
string folderPath = MakeBadgeFolder(conventionNames[_badgeConvention], tierNames[_badgeTier]) + "/Textures/";

// By default (pin), we just need to select image name tierName+_Empty.png
string fileName = "Badge " + Regex.Replace(tierNames[_badgeTier], @"\s+", "");

// Create a save path and ensure the folder exists. We want the image to be saved in a folder named "Custom" relative to the original image
string outPath = folderPath + "Custom/";
if (!System.IO.Directory.Exists(outPath))
System.IO.Directory.CreateDirectory(outPath);
outPath += "CUSTOM_" + _badgeName;

string titleFontPath = Path.Combine(Application.dataPath,
"Furality\\BadgeMaker\\Editor\\f6-title.bean");
"Furality\\BadgeMaker\\Editor\\f7-font.bean");
// Convert fontpath to only have backslashes
titleFontPath = titleFontPath.Replace('/', '\\');

string pronounsFontPath = Path.Combine(Application.dataPath,
"Furality\\BadgeMaker\\Editor\\f6-pronouns.bean");
"Furality\\BadgeMaker\\Editor\\f7-font.bean");
// Convert fontpath to only have backslashes
pronounsFontPath = titleFontPath.Replace('/', '\\');

// Ensure the font path exists and copy it to there, while ensuring the new name matches the FontName
if (!System.IO.Directory.Exists(FontPath))
System.IO.Directory.CreateDirectory(FontPath);

UnloadFonts();

// Copy the file over
File.Copy(
Path.Combine(Application.dataPath, "Furality\\BadgeMaker\\Editor\\f6-name.bean"),
Path.Combine(Application.dataPath, "Furality\\BadgeMaker\\Editor\\f7-font.bean"),
FontPath + TitleFontName, true);
File.Copy(
Path.Combine(Application.dataPath, "Furality\\BadgeMaker\\Editor\\f6-pronouns.bean"),
Path.Combine(Application.dataPath, "Furality\\BadgeMaker\\Editor\\f7-font.bean"),
FontPath + PronounsFontName, true);

int returnFontSize = AddFontResourceEx(FontPath + TitleFontName, 0, IntPtr.Zero);
Expand All @@ -138,34 +186,35 @@ void OnGUI()

MagickImage nameImage = null;
MagickImage pronounsImage = null;

if (!string.IsNullOrEmpty(_badgeName))
nameImage = FindFontSize(FontPath + TitleFontName, _badgeName, NameWidth, NameHeight);
nameImage = FindFontSize(FontPath + TitleFontName, _badgeName, NameWidth, NameHeight, textColor);

EditorUtility.DisplayProgressBar("Creating Badge", "Creating Title Text...", 0.175f);

if (!string.IsNullOrEmpty(_pronouns))
pronounsImage = FindFontSize(FontPath + PronounsFontName, _pronouns, PronounsWidth, PronounsHeight);
pronounsImage = FindFontSize(FontPath + PronounsFontName, _pronouns, PronounsWidth, PronounsHeight, textColor);

EditorUtility.DisplayProgressBar("Creating Badge", "Compositing main texture...", 0.5f);

// Create the badge
CreateBadge(folderPath + fileName + ".png", nameImage, pronounsImage, outPath + ".png");
// DISABLED FOR UMBRA
//CreateBadge(folderPath + fileName + ".png", nameImage, pronounsImage, outPath + ".png");

EditorUtility.DisplayProgressBar("Creating Badge", "Compositing emission texture...", 0.625f);

// Another for the emission
CreateBadge(folderPath + fileName + "_EMI.png", nameImage, pronounsImage, outPath + "_EMI.png");
CreateBadge(folderPath + fileName + "_EMI_BLANK.png", nameImage, pronounsImage, outPath + "_EMI_BLANK.png");

AssetDatabase.Refresh();

EditorUtility.DisplayProgressBar("Creating Badge", "Applying mipmaps...", 0.75f);

// Apply mipmaps
TextureImporter importer = AssetImporter.GetAtPath(outPath + ".png") as TextureImporter;
importer.streamingMipmaps = true;
importer.SaveAndReimport();
importer = AssetImporter.GetAtPath(outPath + "_EMI.png") as TextureImporter;
//TextureImporter importer = AssetImporter.GetAtPath(outPath + ".png") as TextureImporter;
//importer.streamingMipmaps = true;
//importer.SaveAndReimport();
TextureImporter importer = AssetImporter.GetAtPath(outPath + "_EMI_BLANK.png") as TextureImporter;
importer.streamingMipmaps = true;
importer.SaveAndReimport();

Expand All @@ -175,13 +224,13 @@ void OnGUI()

// Find the material named Attendee in the folders[_badgeTier]+Materials folder
Material material =
AssetDatabase.LoadAssetAtPath<Material>($"{folders[_badgeTier]}/Material/{tierNames[_badgeTier]}.mat");
AssetDatabase.LoadAssetAtPath<Material>($"{MakeBadgeFolder(conventionNames[_badgeConvention], tierNames[_badgeTier])}/Materials/Badge{ Regex.Replace(tierNames[_badgeTier], @"\s+", "")}.mat");
// Load the new texture
Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(outPath + ".png");
Texture2D emission = AssetDatabase.LoadAssetAtPath<Texture2D>(outPath + "_EMI.png");
//Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(outPath + ".png");
Texture2D emission = AssetDatabase.LoadAssetAtPath<Texture2D>(outPath + "_EMI_BLANK.png");
// Set the texture to the material
material.SetTexture("_MainTex", texture);
material.SetTexture("_EffectMask", texture);
//material.SetTexture("_MainTex", texture);
//material.SetTexture("_EffectMask", texture);
material.SetTexture("_EmissionMap", emission);
// Save the material
AssetDatabase.SaveAssets();
Expand Down Expand Up @@ -244,7 +293,7 @@ private void CreateBadge(string filePath, MagickImage nameImage, MagickImage pro
}
}

private static MagickImage FindFontSize(string fontFamily, string text, int desiredWidth, int desiredHeight)
private static MagickImage FindFontSize(string fontFamily, string text, int desiredWidth, int desiredHeight, MagickColor color)
{
// Use imagemagick to find the font size that fits the text in the desired width and height
// Using the equivalent of the following command:
Expand All @@ -253,7 +302,7 @@ private static MagickImage FindFontSize(string fontFamily, string text, int desi
MagickImage image = new MagickImage($"label:{text}", new MagickReadSettings
{
BackgroundColor = MagickColors.None,
FillColor = MagickColors.White,
FillColor = color,
Font = fontFamily,
Width = desiredWidth,
Height = desiredHeight,
Expand Down
Binary file added BadgeMaker/Editor/Magick.NET-Q8-x64.dll
Binary file not shown.
Binary file added BadgeMaker/Editor/Magick.NET.Core.dll
Binary file not shown.
Binary file added BadgeMaker/Editor/Magick.Native-Q8-x64.dll
Binary file not shown.
Binary file added BadgeMaker/Editor/f7-font.bean
Binary file not shown.
21 changes: 12 additions & 9 deletions com.furality.sdk/Editor/External/FoxApi/Models/Files/FoxFileDto.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Furality.SDK.Editor.External.AssetHandling;
using NUnit.Framework;

namespace Furality.SDK.Editor.External.FoxApi.Models.Files
{
Expand Down Expand Up @@ -31,22 +32,24 @@ public override List<Package> Dependencies
{
get
{
var list = new List<Package>();
if (Category == "badge")
{
list.Add(new Package() { Id = "com.furality.badgemaker", Version = new Version(1, 1, 0) });
}

switch (ConventionId)
{
case "furality06":
return new List<Package>
{
new Package() { Id = "com.furality.sylvashader", Version = new Version(1, 3, 3) }
};
list.Add(new Package() { Id = "com.furality.sylvashader", Version = new Version(1, 3, 3) });
break;

case "furality07":
return new List<Package>
{
new Package() { Id = "com.furality.umbrashader", Version = new Version(1, 6, 0) }
};
list.Add(new Package() { Id = "com.furality.umbrashader", Version = new Version(1, 6, 0)});
break;
}

return new List<Package>();
return list;
}
}

Expand Down
5 changes: 5 additions & 0 deletions com.furality.sdk/Editor/Pages/DownloadsPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ private void RefreshPage()
_currentPage = _categories[0];
}

public override void BeforeDraw()
{
RefreshPage();
}

public override void Draw()
{
if (!MainWindow.Api.IsLoggedIn)
Expand Down
11 changes: 7 additions & 4 deletions com.furality.sdk/Editor/Pages/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ private void OnEnable()
_pages = new Dictionary<string, MenuPage>
{
{ "Assets", new DownloadsPage(this) },
{ "Settings", new SettingsPage(this) },
{ "Help", new ToolsPage(this) }
{ "Tools", new ToolsPage(this) },
{ "Settings", new SettingsPage(this) }
};

if (_currentPage == null)
Expand Down Expand Up @@ -112,10 +112,13 @@ private void OnGUI()
{
bool isSelected = page.Value == _currentPage;
if (isSelected)
GUI.color = new Color(1.2f, 1.2f, 1.2f);
GUI.color = new Color(1.2f, 1.2f, 1.2f);

if (GUILayout.Button(page.Key.Replace("Page", ""), GUILayout.ExpandWidth(true)))
{
page.Value.BeforeDraw();
_currentPage = page.Value;
}

if (isSelected)
GUI.color = Color.white;
Expand Down
2 changes: 2 additions & 0 deletions com.furality.sdk/Editor/Pages/MenuPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ protected MenuPage(MainWindow mainWindow)
}

public abstract void Draw();

public abstract void BeforeDraw();
}
}
Loading

0 comments on commit 6a5ef33

Please sign in to comment.