diff --git a/GameData/ConformalDecals/Plugins/ConformalDecals.dll b/GameData/ConformalDecals/Plugins/ConformalDecals.dll index b9bb823..11ba282 100644 Binary files a/GameData/ConformalDecals/Plugins/ConformalDecals.dll and b/GameData/ConformalDecals/Plugins/ConformalDecals.dll differ diff --git a/Source/ConformalDecals/ModuleConformalText.cs b/Source/ConformalDecals/ModuleConformalText.cs index 32733bd..b389311 100644 --- a/Source/ConformalDecals/ModuleConformalText.cs +++ b/Source/ConformalDecals/ModuleConformalText.cs @@ -78,7 +78,7 @@ namespace ConformalDecals { private ColorPickerController _outlineColorPickerController; private MaterialTextureProperty _decalTextureProperty; - private MaterialFloatProperty _decalTextWeightProperty; + private MaterialFloatProperty _decalTextWeightProperty; private MaterialKeywordProperty _fillEnabledProperty; private MaterialColorProperty _fillColorProperty; @@ -93,7 +93,7 @@ namespace ConformalDecals { public override void OnLoad(ConfigNode node) { base.OnLoad(node); OnAfterDeserialize(); - + UpdateTextRecursive(); } @@ -104,13 +104,13 @@ namespace ConformalDecals { public override void OnStart(StartState state) { base.OnStart(state); - + UpdateTextRecursive(); } public override void OnAwake() { base.OnAwake(); - + _decalTextureProperty = materialProperties.AddOrGetTextureProperty("_Decal", true); _decalTextWeightProperty = materialProperties.AddOrGetProperty("_Weight"); @@ -121,7 +121,7 @@ namespace ConformalDecals { _outlineColorProperty = materialProperties.AddOrGetProperty("_OutlineColor"); _outlineWidthProperty = materialProperties.AddOrGetProperty("_OutlineWidth"); } - + public void OnTextUpdate(string newText, DecalFont newFont, DecalTextStyle newStyle) { text = newText; _font = newFont; @@ -152,30 +152,28 @@ namespace ConformalDecals { } public void OnFillToggle(BaseField field, object obj) { - if (!fillEnabled && !outlineEnabled) { - outlineEnabled = true; - OnOutlineToggle(field, obj); - } + // fill and outline cant both be disabled + outlineEnabled = outlineEnabled || (!outlineEnabled && !fillEnabled); UpdateTweakables(); foreach (var counterpart in part.symmetryCounterparts) { var decal = counterpart.GetComponent(); decal.fillEnabled = fillEnabled; + decal.outlineEnabled = outlineEnabled; decal.UpdateTweakables(); } } public void OnOutlineToggle(BaseField field, object obj) { - if (!fillEnabled && !outlineEnabled) { - fillEnabled = true; - OnFillToggle(field, obj); - } + // fill and outline cant both be disabled + fillEnabled = fillEnabled || (!fillEnabled && !outlineEnabled); UpdateTweakables(); foreach (var counterpart in part.symmetryCounterparts) { var decal = counterpart.GetComponent(); + decal.fillEnabled = fillEnabled; decal.outlineEnabled = outlineEnabled; decal.UpdateTweakables(); } @@ -206,7 +204,7 @@ namespace ConformalDecals { public override void OnDestroy() { if (_currentText != null) TextRenderer.UnregisterText(_currentText); - + base.OnDestroy(); } @@ -215,7 +213,7 @@ namespace ConformalDecals { if (_textEntryController != null) _textEntryController.OnClose(); if (_fillColorPickerController != null) _fillColorPickerController.OnClose(); if (_outlineColorPickerController != null) _outlineColorPickerController.OnClose(); - + base.OnDetach(); } @@ -251,8 +249,7 @@ namespace ConformalDecals { public void UpdateTexture(TextRenderOutput output) { _decalTextureProperty.Texture = output.Texture; _decalTextureProperty.SetTile(output.Window); - _decalTextWeightProperty.value = output.Weight; - + UpdateMaterials(); UpdateScale(); } @@ -269,22 +266,17 @@ namespace ConformalDecals { } protected override void UpdateTweakables() { - Debug.Log($"Fields is null: {Fields == null}"); - Debug.Log($"Actions is null: {Actions == null}"); var fillEnabledField = Fields[nameof(fillEnabled)]; - var fillColorAction = Actions["SetFillColor"]; + var fillColorEvent = Events["SetFillColor"]; var outlineEnabledField = Fields[nameof(outlineEnabled)]; var outlineWidthField = Fields[nameof(outlineWidth)]; - var outlineColorAction = Actions["SetOutlineColor"]; - - Debug.Log($"outlineColorAction is null: {outlineColorAction == null}"); + var outlineColorEvent = Events["SetOutlineColor"]; - // fillColorAction.activeEditor = fillEnabled; - // outlineWidthField.guiActiveEditor = outlineEnabled; - // outlineColorAction.activeEditor = outlineEnabled; + fillColorEvent.guiActiveEditor = fillEnabled; + outlineWidthField.guiActiveEditor = outlineEnabled; + outlineColorEvent.guiActiveEditor = outlineEnabled; - Debug.Log("Fart"); ((UI_Toggle) fillEnabledField.uiControlEditor).onFieldChanged = OnFillToggle; ((UI_Toggle) outlineEnabledField.uiControlEditor).onFieldChanged = OnOutlineToggle; ((UI_FloatRange) outlineWidthField.uiControlEditor).onFieldChanged = OnOutlineWidthUpdate; diff --git a/Source/ConformalDecals/Text/DecalText.cs b/Source/ConformalDecals/Text/DecalText.cs index 1993b99..07ff603 100644 --- a/Source/ConformalDecals/Text/DecalText.cs +++ b/Source/ConformalDecals/Text/DecalText.cs @@ -21,6 +21,7 @@ namespace ConformalDecals.Text { } public DecalText(string text, DecalFont font, DecalTextStyle style) { + if (font == null) throw new ArgumentNullException(nameof(font)); Text = text; Font = font; Style = style; diff --git a/Source/ConformalDecals/Text/TextRenderOutput.cs b/Source/ConformalDecals/Text/TextRenderOutput.cs index b3b5f27..035bda5 100644 --- a/Source/ConformalDecals/Text/TextRenderOutput.cs +++ b/Source/ConformalDecals/Text/TextRenderOutput.cs @@ -6,14 +6,11 @@ namespace ConformalDecals.Text { public Rect Window { get; private set; } - public float Weight { get; private set; } - public int UserCount { get; set; } - public TextRenderOutput(Texture2D texture, Rect window, float weight) { + public TextRenderOutput(Texture2D texture, Rect window) { Texture = texture; Window = window; - Weight = weight; } } } \ No newline at end of file diff --git a/Source/ConformalDecals/Text/TextRenderer.cs b/Source/ConformalDecals/Text/TextRenderer.cs index 01c008d..669db76 100644 --- a/Source/ConformalDecals/Text/TextRenderer.cs +++ b/Source/ConformalDecals/Text/TextRenderer.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Collections.Generic; using TMPro; using UnityEngine; @@ -32,7 +33,7 @@ namespace ConformalDecals.Text { private bool _isSetup; private TextMeshPro _tmp; - private Material _blitMaterial; + private Shader _blitShader; private static readonly Dictionary RenderCache = new Dictionary(); private static readonly Queue RenderJobs = new Queue(); @@ -44,10 +45,10 @@ namespace ConformalDecals.Text { RenderJobs.Enqueue(job); return job; } - + public static TextRenderOutput UpdateTextNow(DecalText oldText, DecalText newText) { if (newText == null) throw new ArgumentNullException(nameof(newText)); - + return Instance.RunJob(new TextRenderJob(oldText, newText, null), out _); } @@ -91,7 +92,7 @@ namespace ConformalDecals.Text { var shader = Shabby.Shabby.FindShader(BlitShader); if (shader == null) Debug.LogError($"[ConformalDecals] could not find text blit shader named '{shader}'"); - _blitMaterial = new Material(Shabby.Shabby.FindShader(BlitShader)); + _blitShader = Shabby.Shabby.FindShader(BlitShader); _isSetup = true; } @@ -146,6 +147,11 @@ namespace ConformalDecals.Text { } public TextRenderOutput RenderText(DecalText text, Texture2D texture) { + if (text == null) throw new ArgumentNullException(nameof(text)); + if (_tmp == null) throw new InvalidOperationException("TextMeshPro object not yet created."); + + Debug.Log($"[ConformalDecals] rendering text '{text.Text}' in {text.Font.Name}"); + // SETUP TMP OBJECT FOR RENDERING _tmp.text = text.FormattedText; _tmp.font = text.Font.FontAsset; @@ -157,33 +163,54 @@ namespace ConformalDecals.Text { _tmp.enableKerning = true; _tmp.enableWordWrapping = false; _tmp.overflowMode = TextOverflowModes.Overflow; - _tmp.alignment = TextAlignmentOptions.Center | TextAlignmentOptions.Baseline; + _tmp.alignment = TextAlignmentOptions.Center; _tmp.fontSize = FontSize; - - // CALCULATE FONT WEIGHT - - float weight = 0; - if (text.Style.Bold && text.Font.FontAsset.fontWeights[7].regularTypeface == null) { - weight = text.Font.FontAsset.boldStyle; - } - - // SETUP BLIT MATERIAL - _blitMaterial.SetTexture(PropertyIDs._MainTex, text.Font.FontAsset.atlas); // GENERATE MESH _tmp.ForceMeshUpdate(); - var mesh = _tmp.mesh; - mesh.RecalculateBounds(); - var bounds = mesh.bounds; + + var meshFilters = gameObject.GetComponentsInChildren(); + var meshes = new Mesh[meshFilters.Length]; + var materials = new Material[meshFilters.Length]; + + var bounds = new Bounds(); + + Debug.Log($"meshFilter count: {meshFilters.Length}"); + // SETUP MATERIALS AND BOUNDS + for (int i = 0; i < meshFilters.Length; i++) { + var renderer = meshFilters[i].gameObject.GetComponent(); + + meshes[i] = meshFilters[i].mesh; + meshes[i].RecalculateBounds(); + + materials[i] = Instantiate(renderer.material); + materials[i].shader = _blitShader; + + if (renderer == null) throw new FormatException($"Object {meshFilters[i].gameObject.name} has filter but no renderer"); + if (meshes[i] == null) throw new FormatException($"Object {meshFilters[i].gameObject.name} has a null mesh"); + + if (i == 0) { + bounds = meshes[i].bounds; + } + else { + bounds.Encapsulate(meshes[i].bounds); + } + } // CALCULATE SIZES var size = bounds.size * PixelDensity; - var textureSize = new Vector2Int { x = Mathf.NextPowerOfTwo((int) size.x), y = Mathf.NextPowerOfTwo((int) size.y) }; + if (textureSize.x == 0 || textureSize.y == 0) { + Debug.LogWarning("[ConformalDecals] No text present or error in texture size calculation. Aborting."); + return new TextRenderOutput(Texture2D.blackTexture, Rect.zero); + } + + Debug.Log($"Texture size: {textureSize}"); + // make sure texture isnt too big, scale it down if it is // this is just so you dont crash the game by pasting in the entire script of The Bee Movie if (textureSize.x > MaxTextureSize) { @@ -204,9 +231,8 @@ namespace ConformalDecals.Text { size = size * sizeRatio, center = (Vector2) textureSize / 2 }; - + Debug.Log($"Window size: {window.size}"); - Debug.Log($"Texture size: {textureSize}"); // SETUP TEXTURE if (texture == null) { @@ -230,8 +256,14 @@ namespace ConformalDecals.Text { GL.PushMatrix(); GL.LoadProjectionMatrix(matrix); GL.Clear(false, true, Color.black); - _blitMaterial.SetPass(0); - Graphics.DrawMeshNow(mesh, Matrix4x4.identity); + + for (var i = 0; i < meshes.Length; i++) { + if (meshes[i].vertexCount >= 3) { + materials[i].SetPass(0); + Graphics.DrawMeshNow(meshes[i], Matrix4x4.identity); + } + } + GL.PopMatrix(); // COPY TEXTURE BACK INTO RAM @@ -242,7 +274,12 @@ namespace ConformalDecals.Text { // RELEASE RENDERTEX RenderTexture.ReleaseTemporary(renderTex); - return new TextRenderOutput(texture, window, weight); + // CLEAR SUBMESHES + for (int i = 0; i < transform.childCount; i++) { + Destroy(transform.GetChild(i).gameObject); + } + + return new TextRenderOutput(texture, window); } } } \ No newline at end of file