UnityGame/Library/PackageCache/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowProvider/EdgeDictionary.cs
2024-10-27 10:53:47 +03:00

89 lines
3.1 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Collections;
namespace UnityEngine.Rendering.Universal
{
internal struct EdgeDictionary : IEdgeStore
{
static private Dictionary<ShadowEdge, int> m_EdgeDictionary = new Dictionary<ShadowEdge, int>(new EdgeComparer()); // This is done so we don't create garbage allocating and deallocating a dictionary object
private class EdgeComparer : IEqualityComparer<ShadowEdge>
{
public bool Equals(ShadowEdge edge0, ShadowEdge edge1)
{
return (edge0.v0 == edge1.v0 && edge0.v1 == edge1.v1) || (edge0.v1 == edge1.v0 && edge0.v0 == edge1.v1);
}
public int GetHashCode(ShadowEdge edge)
{
int v0 = edge.v0;
int v1 = edge.v1;
if (edge.v1 < edge.v0)
{
v0 = edge.v1;
v1 = edge.v0;
}
int hashCode = v0 << 15 | v1;
return hashCode.GetHashCode();
}
}
public NativeArray<ShadowEdge> GetOutsideEdges(NativeArray<Vector3> vertices, NativeArray<int> indices)
{
m_EdgeDictionary.Clear();
m_EdgeDictionary.EnsureCapacity(indices.Length);
for (int i = 0; i < indices.Length; i += 3)
{
int v0Index = indices[i];
int v1Index = indices[i + 1];
int v2Index = indices[i + 2];
ShadowEdge edge0 = new ShadowEdge(v0Index, v1Index);
ShadowEdge edge1 = new ShadowEdge(v1Index, v2Index);
ShadowEdge edge2 = new ShadowEdge(v2Index, v0Index);
// When a key comparison is made edges (A, B) and (B, A) are equal (see EdgeComparer)
if (m_EdgeDictionary.ContainsKey(edge0))
m_EdgeDictionary[edge0] = m_EdgeDictionary[edge0] + 1;
else
m_EdgeDictionary.Add(edge0, 1);
if (m_EdgeDictionary.ContainsKey(edge1))
m_EdgeDictionary[edge1] = m_EdgeDictionary[edge1] + 1;
else
m_EdgeDictionary.Add(edge1, 1);
if (m_EdgeDictionary.ContainsKey(edge2))
m_EdgeDictionary[edge2] = m_EdgeDictionary[edge2] + 1;
else
m_EdgeDictionary.Add(edge2, 1);
}
// Count the outside edges
int outsideEdges = 0;
foreach (KeyValuePair<ShadowEdge, int> keyValuePair in m_EdgeDictionary)
{
if (keyValuePair.Value == 1)
outsideEdges++;
}
// Create unsorted edges array
int edgeIndex = 0;
NativeArray<ShadowEdge> edges = new NativeArray<ShadowEdge>(outsideEdges, Allocator.Temp);
foreach (KeyValuePair<ShadowEdge, int> keyValuePair in m_EdgeDictionary)
{
if (keyValuePair.Value == 1)
{
edges[edgeIndex++] = keyValuePair.Key;
}
}
return edges;
}
}
}