Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions Components/Components/Decals/ChiselDecalComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ public sealed class ChiselDecalComponent : MonoBehaviour
[SerializeField] int imageTile = 0;
[SerializeField] Vector2 repeat = Vector2.one;

// Per pair of targets, the edge a trim decal lies on: the edge's number along the first surface's outline, times
// two, plus one when it is the second surface's; -1 (or missing) to find it from where the decal is
[SerializeField] List<int> trimEdges = new();

// The line a trim decal's first edge lay on at its last update, in world space: of two surfaces' edges, the trim
// keeps to this one while the decal is on it (so dragging it past where another edge starts doesn't jump)
[NonSerialized] internal bool hasTrimLine;
[NonSerialized] internal Vector3 trimLinePoint, trimLineDirection;

public const string kMaterialName = nameof(material);
public const string kSettingsName = nameof(settings);
public const string kTargetsName = nameof(targets);
Expand Down Expand Up @@ -147,7 +156,52 @@ public void SetTargets(IEnumerable<ChiselDecalSurfaceTarget> newTargets)
targets.Clear();
if (newTargets != null)
targets.AddRange(newTargets);
trimEdges.Clear();
hasTrimLine = false;
ChiselDecalManager.SetDirty();
}

/// <summary>The edge a trim decal's pair of targets lies on: its number along the first surface's outline (the
/// second's, with onSecond); -1 when it is found from where the decal is</summary>
public int TrimEdgeOf(int pair, out bool onSecond)
{
var code = pair >= 0 && pair < trimEdges.Count ? trimEdges[pair] : -1;
onSecond = code >= 0 && (code & 1) != 0;
return code < 0 ? -1 : code >> 1;
}

/// <summary>The edge the first pair of targets lies on (see <see cref="TrimEdgeOf"/>)</summary>
public void SetTrimEdge(bool onSecond, int edgeIndex)
{
if (trimEdges.Count == 0)
trimEdges.Add(-1);
trimEdges[0] = edgeIndex < 0 ? -1 : edgeIndex * 2 + (onSecond ? 1 : 0);
ChiselDecalManager.SetDirty();
}

/// <summary>Adds an edge to a trim decal's chain: a pair of targets and the edge they lie on. False, and nothing
/// added, when the chain already has that edge of that surface.</summary>
public bool AddTrimEdge(ChiselDecalSurfaceTarget a, ChiselDecalSurfaceTarget b, bool onSecond, int edgeIndex)
{
var pair = targets.Count / 2;
var code = edgeIndex < 0 ? -1 : edgeIndex * 2 + (onSecond ? 1 : 0);
var owner = onSecond ? b : a;
for (int p = 0; p < pair && code >= 0; p++)
{
var existing = TrimEdgeOf(p, out var existingOnSecond);
var existingOwner = targets[p * 2 + (existingOnSecond ? 1 : 0)];
if (existing == edgeIndex && existingOwner.brush == owner.brush && existingOwner.surfaceIndex == owner.surfaceIndex)
return false;
}
targets.RemoveRange(pair * 2, targets.Count - pair * 2);
targets.Add(a);
targets.Add(b);
while (trimEdges.Count < pair)
trimEdges.Add(-1);
trimEdges.RemoveRange(pair, trimEdges.Count - pair);
trimEdges.Add(code);
ChiselDecalManager.SetDirty();
return true;
}

public Material Material
Expand Down
506 changes: 468 additions & 38 deletions Components/Components/Decals/ChiselTrimDecals.cs

Large diffs are not rendered by default.

23 changes: 19 additions & 4 deletions Components/Managers/ChiselDecalManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,21 @@ static bool SameTrim(DecalState state, ChiselModelComponent model)
return false;
for (int p = 0; p < s_TrimHalves.Count; p++)
{
if (!s_TrimHalves[p].decal.Equals(state.trimPieces[p]) || !s_TrimHalves[p].target.Equals(state.trimTargets[p][0]))
if (!s_TrimHalves[p].decal.Equals(state.trimPieces[p]) || !SameTargets(s_TrimHalves[p].targets, state.trimTargets[p]))
return false;
}
return true;
}

static bool SameTargets(ChiselDecalTarget[] a, ChiselDecalTarget[] b)
{
if (a == null || b == null)
return a == b;
if (a.Length != b.Length)
return false;
for (int i = 0; i < a.Length; i++)
{
if (!a[i].Equals(b[i]))
return false;
}
return true;
Expand All @@ -371,7 +385,7 @@ static bool UpdateTrim(DecalState state)
foreach (var half in s_TrimHalves)
{
state.trimPieces.Add(half.decal);
state.trimTargets.Add(new[] { half.target });
state.trimTargets.Add(half.targets);
}
return true;
}
Expand Down Expand Up @@ -472,8 +486,9 @@ static void Describe(ChiselDecalComponent decal, DecalState decalState, Matrix4x
var tile = settings;
tile.center = new float3((from + to) * 0.5f, settings.center.z);
tile.size = new float3(to - from, size.z);
tile.uvScale = userScale * (float2)rect.size * shown;
tile.uvOffset = (float2)settings.uvOffset + userScale * (float2)rect.position;
ChiselDecalSettings.TurnMapping(shown, float2.zero, settings.imageTurns, out var imageScale, out var imageOffset);
tile.uvScale = userScale * (float2)rect.size * imageScale;
tile.uvOffset = (float2)settings.uvOffset + userScale * ((float2)rect.position + (float2)rect.size * imageOffset);
instance.entityID = ChiselTrimDecals.PieceEntityID(decalState.entityID, piece);
instance.settings = tile;
tiles.Add(instance);
Expand Down
Loading
Loading