From 2f2b6fb692df01ddc4aa908bce2650d8327a3423 Mon Sep 17 00:00:00 2001 From: drewcassidy Date: Thu, 31 Dec 2020 21:05:30 -0800 Subject: [PATCH] Get multi-projection to work --- .../Plugins/ConformalDecals.dll | Bin 83968 -> 86016 bytes Source/ConformalDecals/IProjectionTarget.cs | 9 ++ .../ConformalDecals/ModuleConformalDecal.cs | 118 +++++++++++++----- Source/ConformalDecals/ModuleConformalText.cs | 2 +- ...ctionTarget.cs => ProjectionMeshTarget.cs} | 96 ++++++++------ .../ConformalDecals/ProjectionPartTarget.cs | 51 ++++++++ 6 files changed, 201 insertions(+), 75 deletions(-) create mode 100644 Source/ConformalDecals/IProjectionTarget.cs rename Source/ConformalDecals/{ProjectionTarget.cs => ProjectionMeshTarget.cs} (60%) create mode 100644 Source/ConformalDecals/ProjectionPartTarget.cs diff --git a/GameData/ConformalDecals/Plugins/ConformalDecals.dll b/GameData/ConformalDecals/Plugins/ConformalDecals.dll index f55108e3da2c03d4a5343eec75cbbe4cfc651867..2336c5f607bd4a4c632ec990d6d7d11d7edc7f1f 100644 GIT binary patch literal 86016 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 R&8c|`GS>N!_5V|U{}-3#RbT)B literal 83968 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 V+@s}9#F=?2GS>N!_5Z8C{{==vI>7({ diff --git a/Source/ConformalDecals/IProjectionTarget.cs b/Source/ConformalDecals/IProjectionTarget.cs new file mode 100644 index 0000000..31f6f58 --- /dev/null +++ b/Source/ConformalDecals/IProjectionTarget.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace ConformalDecals { + public interface IProjectionTarget { + void Project(Matrix4x4 orthoMatrix, Transform projector, Bounds projectionBounds); + void Render(Material decalMaterial, MaterialPropertyBlock partMPB, Camera camera); + ConfigNode Save(); + } +} \ No newline at end of file diff --git a/Source/ConformalDecals/ModuleConformalDecal.cs b/Source/ConformalDecals/ModuleConformalDecal.cs index 3580f2e..4ffb31e 100644 --- a/Source/ConformalDecals/ModuleConformalDecal.cs +++ b/Source/ConformalDecals/ModuleConformalDecal.cs @@ -99,7 +99,7 @@ namespace ConformalDecals { private const int DecalQueueMax = 2400; private static int _decalQueueCounter = -1; - private List _targets; + private Dictionary _targets; private bool _isAttached; private Matrix4x4 _orthoMatrix; @@ -155,7 +155,7 @@ namespace ConformalDecals { /// public override void OnIconCreate() { UpdateTextures(); - UpdateScale(); + UpdateProjection(); } /// @@ -226,12 +226,12 @@ namespace ConformalDecals { protected void OnProjectionTweakEvent(BaseField field, object obj) { // scale or depth values have been changed, so update scale // and update projection matrices if attached - UpdateScale(); + UpdateProjection(); UpdateTargets(); foreach (var counterpart in part.symmetryCounterparts) { var decal = counterpart.GetComponent(); - decal.UpdateScale(); + decal.UpdateProjection(); decal.UpdateTargets(); } } @@ -256,38 +256,80 @@ namespace ConformalDecals { /// Called when a new variant is applied in the editor protected void OnVariantApplied(Part eventPart, PartVariant variant) { - if (_isAttached && eventPart != null) { - if (projectMultiple && eventPart != part.parent) return; - else if (!_targets.Select(o => o.targetPart).Contains(eventPart)) return; - + if (_isAttached && eventPart != null && (!projectMultiple || eventPart == part.parent)) { + _targets.Remove(eventPart); UpdateTargets(); } } /// Called when an editor event occurs protected void OnEditorEvent(ConstructionEventType eventType, Part eventPart) { - if (this.part != eventPart && !part.symmetryCounterparts.Contains(eventPart)) return; switch (eventType) { case ConstructionEventType.PartAttached: - OnAttach(); + OnPartAttached(eventPart); break; case ConstructionEventType.PartDetached: - OnDetach(); + OnPartDetached(eventPart); break; case ConstructionEventType.PartOffsetting: case ConstructionEventType.PartRotating: - UpdateScale(); - UpdateTargets(); + OnPartTransformed(eventPart); break; } } + /// Called when a part is transformed in the editor + protected void OnPartTransformed(Part eventPart) { + if (this.part == eventPart) { + UpdateProjection(); + UpdateTargets(); + } + else { + UpdatePartTarget(eventPart, _boundsRenderer.bounds); + // recursively call for child parts + foreach (var child in eventPart.children) { + OnPartTransformed(child); + } + } + } + + /// Called when a part is attached in the editor + protected void OnPartAttached(Part eventPart) { + if (this.part == eventPart) { + OnAttach(); + } + else { + UpdatePartTarget(eventPart, _boundsRenderer.bounds); + // recursively call for child parts + foreach (var child in eventPart.children) { + OnPartAttached(child); + } + } + } + + /// Called when a part is detached in the editor + protected void OnPartDetached(Part eventPart) { + if (this.part == eventPart) { + OnDetach(); + } + else { + _targets.Remove(eventPart); + // recursively call for child parts + foreach (var child in eventPart.children) { + OnPartDetached(child); + } + } + } + /// Called when part `willDie` will be destroyed protected void OnPartWillDie(Part willDie) { if (willDie == part.parent) { this.Log("Parent part about to be destroyed! Killing decal part."); part.Die(); } + else if (projectMultiple) { + _targets.Remove(willDie); + } } /// Called when decal is attached to a new part @@ -310,7 +352,7 @@ namespace ConformalDecals { Camera.onPreCull += Render; UpdateMaterials(); - UpdateScale(); + UpdateProjection(); UpdateTargets(); } @@ -328,11 +370,11 @@ namespace ConformalDecals { Camera.onPreCull -= Render; UpdateMaterials(); - UpdateScale(); + UpdateProjection(); } // FUNCTIONS - + /// Load any settings from the decal config protected virtual void LoadDecal(ConfigNode node) { // PARSE TRANSFORMS @@ -498,10 +540,10 @@ namespace ConformalDecals { protected virtual void UpdateAll() { UpdateTextures(); UpdateMaterials(); - UpdateScale(); + UpdateProjection(); UpdateTargets(); } - + /// Update decal textures protected virtual void UpdateTextures() { } @@ -521,7 +563,7 @@ namespace ConformalDecals { } /// Update decal scale and projection - protected void UpdateScale() { + protected void UpdateProjection() { // Update scale and depth scale = Mathf.Max(0.01f, scale); @@ -559,7 +601,7 @@ namespace ConformalDecals { if (_isAttached) { // Update projection targets if (_targets == null) { - _targets = new List(); + _targets = new Dictionary(); } else { _targets.Clear(); @@ -587,6 +629,9 @@ namespace ConformalDecals { protected void UpdateTargets() { if (!_isAttached) return; + var projectionBounds = _boundsRenderer.bounds; + + // collect list of potential targets IEnumerable targetParts; if (projectMultiple) { targetParts = HighLogic.LoadedSceneIsFlight ? part.vessel.parts : EditorLogic.fetch.ship.parts; @@ -596,25 +641,30 @@ namespace ConformalDecals { } foreach (var targetPart in targetParts) { - if (targetPart.GetComponent() != null) continue; // skip other decals + UpdatePartTarget(targetPart, projectionBounds); + } + } - foreach (var renderer in targetPart.FindModelComponents()) { - var target = renderer.transform; - var filter = target.GetComponent(); + protected void UpdatePartTarget(Part targetPart, Bounds projectionBounds) { + if (targetPart.GetComponent() != null) return; // skip other decals - // check if the target has any missing data - if (!ProjectionTarget.ValidateTarget(target, renderer, filter)) continue; + this.Log($"Updating projection onto part {targetPart.name}"); - // check bounds for intersection - if (_boundsRenderer.bounds.Intersects(renderer.bounds)) { - // create new ProjectionTarget to represent the renderer - var projectionTarget = new ProjectionTarget(targetPart, target, renderer, filter, _orthoMatrix, decalProjectorTransform, useBaseNormal); + if (!_targets.TryGetValue(targetPart, out var target)) { + var rendererList = targetPart.FindModelComponents(); - // add the target to the list - _targets.Add(projectionTarget); - } + if (rendererList.Any(o => projectionBounds.Intersects(o.bounds))) { + target = new ProjectionPartTarget(targetPart, useBaseNormal); + _targets.Add(targetPart, target); + } + else { + return; } } + + this.Log($"valid target: {targetPart.name}"); + + target.Project(_orthoMatrix, decalProjectorTransform, projectionBounds); } /// Render the decal @@ -622,7 +672,7 @@ namespace ConformalDecals { if (!_isAttached) return; // render on each target object - foreach (var target in _targets) { + foreach (var target in _targets.Values) { target.Render(_decalMaterial, part.mpb, camera); } } diff --git a/Source/ConformalDecals/ModuleConformalText.cs b/Source/ConformalDecals/ModuleConformalText.cs index 7aee17d..9e60841 100644 --- a/Source/ConformalDecals/ModuleConformalText.cs +++ b/Source/ConformalDecals/ModuleConformalText.cs @@ -264,7 +264,7 @@ namespace ConformalDecals { UpdateTextures(); UpdateMaterials(); - UpdateScale(); + UpdateProjection(); // QUEUE PART FOR ICON FIXING IN VAB DecalIconFixer.QueuePart(part.name); diff --git a/Source/ConformalDecals/ProjectionTarget.cs b/Source/ConformalDecals/ProjectionMeshTarget.cs similarity index 60% rename from Source/ConformalDecals/ProjectionTarget.cs rename to Source/ConformalDecals/ProjectionMeshTarget.cs index fc0eb0c..49b3dea 100644 --- a/Source/ConformalDecals/ProjectionTarget.cs +++ b/Source/ConformalDecals/ProjectionMeshTarget.cs @@ -6,69 +6,65 @@ using UnityEngine; using UnityEngine.Rendering; namespace ConformalDecals { - public class ProjectionTarget { + public class ProjectionMeshTarget : IProjectionTarget { + // enabled flag + public bool enabled = true; + // Target object data - public readonly Transform target; - public readonly Part targetPart; - private readonly Mesh _targetMesh; - private readonly Matrix4x4 _decalMatrix; - private readonly Vector3 _decalNormal; - private readonly Vector3 _decalTangent; - private readonly bool _useBaseNormal; + public readonly Transform target; + public readonly Transform root; + public readonly Mesh mesh; + public readonly MeshRenderer renderer; + + // Projection data + private Matrix4x4 _decalMatrix; + private Vector3 _decalNormal; + private Vector3 _decalTangent; // property block private readonly MaterialPropertyBlock _decalMPB; - public ProjectionTarget(Part targetPart, Transform target, MeshRenderer renderer, MeshFilter filter, - Matrix4x4 orthoMatrix, Transform projector, bool useBaseNormal) { - - this.targetPart = targetPart; + public ProjectionMeshTarget(Transform target, Transform root, MeshRenderer renderer, Mesh mesh, bool useBaseNormal) { + this.root = root; this.target = target; - _targetMesh = filter.sharedMesh; - _useBaseNormal = useBaseNormal; + this.renderer = renderer; + this.mesh = mesh; _decalMPB = new MaterialPropertyBlock(); - var projectorToTargetMatrix = target.worldToLocalMatrix * projector.localToWorldMatrix; - - _decalMatrix = orthoMatrix * projectorToTargetMatrix.inverse; - _decalNormal = projectorToTargetMatrix.MultiplyVector(Vector3.back).normalized; - _decalTangent = projectorToTargetMatrix.MultiplyVector(Vector3.right).normalized; - - SetupMPB(renderer.sharedMaterial); + SetNormalMap(renderer.sharedMaterial, useBaseNormal); } - public ProjectionTarget(ConfigNode node, Vessel vessel, bool useBaseNormal) { - var flightID = (uint) ParseUtil.ParseInt(node, "part"); + public ProjectionMeshTarget(ConfigNode node, Transform root, bool useBaseNormal) { + if (node == null) throw new ArgumentNullException(nameof(node)); + if (root == null) throw new ArgumentNullException(nameof(root)); + var targetPath = ParseUtil.ParseString(node, "targetPath"); var targetName = ParseUtil.ParseString(node, "targetName"); _decalMatrix = ParseUtil.ParseMatrix4x4(node, "decalMatrix"); _decalNormal = ParseUtil.ParseVector3(node, "decalNormal"); _decalTangent = ParseUtil.ParseVector3(node, "decalTangent"); - _useBaseNormal = useBaseNormal; _decalMPB = new MaterialPropertyBlock(); - targetPart = vessel[flightID]; - if (targetPart == null) throw new IndexOutOfRangeException("Vessel returned null part"); - target = LoadTransformPath(targetPath, targetPart.transform); + target = LoadTransformPath(targetPath, root); if (target.name != targetName) throw new FormatException("Target name does not match"); - var renderer = target.GetComponent(); + renderer = target.GetComponent(); var filter = target.GetComponent(); if (!ValidateTarget(target, renderer, filter)) throw new FormatException("Invalid target"); - _targetMesh = filter.sharedMesh; + mesh = filter.sharedMesh; - SetupMPB(renderer.sharedMaterial); - } - - private void SetupMPB(Material targetMaterial) { + SetNormalMap(renderer.sharedMaterial, useBaseNormal); + _decalMPB.SetMatrix(DecalPropertyIDs._ProjectionMatrix, _decalMatrix); _decalMPB.SetVector(DecalPropertyIDs._DecalNormal, _decalNormal); - _decalMPB.SetVector(DecalPropertyIDs._DecalTangent, _decalTangent); + _decalMPB.SetVector(DecalPropertyIDs._DecalTangent, _decalTangent); + } - if (_useBaseNormal && targetMaterial.HasProperty(DecalPropertyIDs._BumpMap)) { + private void SetNormalMap(Material targetMaterial, bool useBaseNormal) { + if (useBaseNormal && targetMaterial.HasProperty(DecalPropertyIDs._BumpMap)) { _decalMPB.SetTexture(DecalPropertyIDs._BumpMap, targetMaterial.GetTexture(DecalPropertyIDs._BumpMap)); var normalScale = targetMaterial.GetTextureScale(DecalPropertyIDs._BumpMap); @@ -81,20 +77,40 @@ namespace ConformalDecals { } } + public void Project(Matrix4x4 orthoMatrix, Transform projector, Bounds projectionBounds) { + if (projectionBounds.Intersects(renderer.bounds)) { + enabled = true; + + var projectorToTargetMatrix = target.worldToLocalMatrix * projector.localToWorldMatrix; + + _decalMatrix = orthoMatrix * projectorToTargetMatrix.inverse; + _decalNormal = projectorToTargetMatrix.MultiplyVector(Vector3.back).normalized; + _decalTangent = projectorToTargetMatrix.MultiplyVector(Vector3.right).normalized; + + _decalMPB.SetMatrix(DecalPropertyIDs._ProjectionMatrix, _decalMatrix); + _decalMPB.SetVector(DecalPropertyIDs._DecalNormal, _decalNormal); + _decalMPB.SetVector(DecalPropertyIDs._DecalTangent, _decalTangent); + } + else { + enabled = false; + } + } + public void Render(Material decalMaterial, MaterialPropertyBlock partMPB, Camera camera) { + if (!enabled) return; + _decalMPB.SetFloat(PropertyIDs._RimFalloff, partMPB.GetFloat(PropertyIDs._RimFalloff)); _decalMPB.SetColor(PropertyIDs._RimColor, partMPB.GetColor(PropertyIDs._RimColor)); - Graphics.DrawMesh(_targetMesh, target.localToWorldMatrix, decalMaterial, 0, camera, 0, _decalMPB, ShadowCastingMode.Off, true); + Graphics.DrawMesh(mesh, target.localToWorldMatrix, decalMaterial, 0, camera, 0, _decalMPB, ShadowCastingMode.Off, true); } public ConfigNode Save() { - var node = new ConfigNode("TARGET"); - node.AddValue("part", targetPart.flightID); + var node = new ConfigNode("MESH_TARGET"); node.AddValue("decalMatrix", _decalMatrix); node.AddValue("decalNormal", _decalNormal); node.AddValue("decalTangent", _decalTangent); - node.AddValue("targetPath", SaveTransformPath(target, targetPart.transform)); // used to find the target transform + node.AddValue("targetPath", SaveTransformPath(target, root)); // used to find the target transform node.AddValue("targetName", target.name); // used to validate the mesh has not changed since last load return node; @@ -116,7 +132,7 @@ namespace ConformalDecals { } private static string SaveTransformPath(Transform leaf, Transform root) { - var builder = new StringBuilder(leaf.name); + var builder = new StringBuilder($"{leaf.GetSiblingIndex()}"); var current = leaf.parent; while (current != root) { diff --git a/Source/ConformalDecals/ProjectionPartTarget.cs b/Source/ConformalDecals/ProjectionPartTarget.cs new file mode 100644 index 0000000..3b060e1 --- /dev/null +++ b/Source/ConformalDecals/ProjectionPartTarget.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace ConformalDecals { + public class ProjectionPartTarget : IProjectionTarget { + public readonly Part part; + public readonly List meshTargets; + + public ProjectionPartTarget(Part part, bool useBaseNormal) { + this.part = part; + meshTargets = new List(); + + foreach (var renderer in part.FindModelComponents()) { + var target = renderer.transform; + var filter = target.GetComponent(); + + // check if the target has any missing data + if (!ProjectionMeshTarget.ValidateTarget(target, renderer, filter)) continue; + + // create new ProjectionTarget to represent the renderer + var projectionTarget = new ProjectionMeshTarget(target, part.transform, renderer, filter.sharedMesh, useBaseNormal); + + // add the target to the list + meshTargets.Add(projectionTarget); + } + } + + public void Project(Matrix4x4 orthoMatrix, Transform projector, Bounds projectionBounds) { + foreach (var meshTarget in meshTargets) { + meshTarget.Project(orthoMatrix, projector, projectionBounds); + } + } + + public void Render(Material decalMaterial, MaterialPropertyBlock partMPB, Camera camera) { + foreach (var target in meshTargets) { + target.Render(decalMaterial, partMPB, camera); + } + } + + public ConfigNode Save() { + var node = new ConfigNode("PART_TARGET"); + node.AddValue("part", part.flightID); + foreach (var meshTarget in meshTargets) { + node.AddNode(meshTarget.Save()); + } + + return node; + } + } +} \ No newline at end of file