Files
2026-06-04 11:42:34 +02:00

294 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using ProBuilder2.Common;
using UnityEngine;
namespace ProBuilder2.MeshOperations
{
// Token: 0x0200000F RID: 15
public static class pb_Extrude
{
// Token: 0x0600008E RID: 142 RVA: 0x0000BAB2 File Offset: 0x00009EB2
public static bool Extrude(this pb_Object pb, pb_Face[] faces, ExtrudeMethod method, float distance)
{
if (method != ExtrudeMethod.IndividualFaces)
{
return pb_Extrude.ExtrudeAsGroups(pb, faces, method == ExtrudeMethod.FaceNormal, distance);
}
return pb_Extrude.ExtrudePerFace(pb, faces, distance);
}
// Token: 0x0600008F RID: 143 RVA: 0x0000BAD4 File Offset: 0x00009ED4
private static bool ExtrudePerFace(pb_Object pb, pb_Face[] faces, float distance)
{
if (faces == null || faces.Length < 1)
{
return false;
}
List<pb_Vertex> list = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, null));
int num = pb.sharedIndices.Length;
int num2 = 0;
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
Dictionary<int, int> dictionary2 = pb.sharedIndicesUV.ToDictionary();
List<pb_Face> list2 = new List<pb_Face>(pb.faces);
Dictionary<int, int> dictionary3 = new Dictionary<int, int>();
foreach (pb_Face pb_Face in faces)
{
pb_Face.smoothingGroup = -1;
pb_Face.textureGroup = -1;
Vector3 vector = pb_Math.Normal(pb, pb_Face) * distance;
pb_Edge[] edges = pb_Face.edges;
dictionary3.Clear();
for (int j = 0; j < edges.Length; j++)
{
int count = list.Count;
int x = edges[j].x;
int y = edges[j].y;
if (!dictionary3.ContainsKey(x))
{
dictionary3.Add(x, dictionary[x]);
dictionary[x] = num + num2++;
}
if (!dictionary3.ContainsKey(y))
{
dictionary3.Add(y, dictionary[y]);
dictionary[y] = num + num2++;
}
dictionary.Add(count, dictionary3[x]);
dictionary.Add(count + 1, dictionary3[y]);
dictionary.Add(count + 2, dictionary[x]);
dictionary.Add(count + 3, dictionary[y]);
pb_Vertex pb_Vertex = new pb_Vertex(list[x]);
pb_Vertex pb_Vertex2 = new pb_Vertex(list[y]);
pb_Vertex.position += vector;
pb_Vertex2.position += vector;
list.Add(new pb_Vertex(list[x]));
list.Add(new pb_Vertex(list[y]));
list.Add(pb_Vertex);
list.Add(pb_Vertex2);
pb_Face pb_Face2 = new pb_Face(new int[]
{
count,
count + 1,
count + 2,
count + 1,
count + 3,
count + 2
}, pb_Face.material, new pb_UV(pb_Face.uv), pb_Face.smoothingGroup, -1, -1, false);
list2.Add(pb_Face2);
}
for (int k = 0; k < pb_Face.distinctIndices.Length; k++)
{
pb_Vertex pb_Vertex3 = list[pb_Face.distinctIndices[k]];
pb_Vertex3.position.x = pb_Vertex3.position.x + vector.x;
pb_Vertex pb_Vertex4 = list[pb_Face.distinctIndices[k]];
pb_Vertex4.position.y = pb_Vertex4.position.y + vector.y;
pb_Vertex pb_Vertex5 = list[pb_Face.distinctIndices[k]];
pb_Vertex5.position.z = pb_Vertex5.position.z + vector.z;
if (dictionary2 != null && dictionary2.ContainsKey(pb_Face.distinctIndices[k]))
{
dictionary2.Remove(pb_Face.distinctIndices[k]);
}
}
}
pb.SetVertices(list, false);
pb.SetFaces(list2.ToArray());
pb.SetSharedIndices(dictionary);
pb.SetSharedIndicesUV(dictionary2);
return true;
}
// Token: 0x06000090 RID: 144 RVA: 0x0000BE28 File Offset: 0x0000A228
private static bool ExtrudeAsGroups(pb_Object pb, pb_Face[] faces, bool compensateAngleVertexDistance, float distance)
{
if (faces == null || faces.Length < 1)
{
return false;
}
List<pb_Vertex> list = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, null));
int num = pb.sharedIndices.Length;
int num2 = 0;
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
Dictionary<int, int> dictionary2 = pb.sharedIndicesUV.ToDictionary();
List<pb_Face> list2 = new List<pb_Face>(pb.faces);
Dictionary<int, int> dictionary3 = new Dictionary<int, int>();
Dictionary<int, int> dictionary4 = new Dictionary<int, int>();
Dictionary<int, int> dictionary5 = new Dictionary<int, int>();
Dictionary<int, pb_Tuple<Vector3, Vector3, List<int>>> dictionary6 = new Dictionary<int, pb_Tuple<Vector3, Vector3, List<int>>>();
List<pb_WingedEdge> wingedEdges = pb_WingedEdge.GetWingedEdges(pb, faces, true, dictionary);
List<HashSet<pb_Face>> faceGroups = pb_Extrude.GetFaceGroups(wingedEdges);
foreach (HashSet<pb_Face> hashSet in faceGroups)
{
Dictionary<pb_EdgeLookup, pb_Face> perimeterEdges = pb_Extrude.GetPerimeterEdges(hashSet, dictionary);
dictionary4.Clear();
dictionary3.Clear();
foreach (KeyValuePair<pb_EdgeLookup, pb_Face> keyValuePair in perimeterEdges)
{
pb_EdgeLookup key = keyValuePair.Key;
pb_Face value = keyValuePair.Value;
int count = list.Count;
int x = key.local.x;
int y = key.local.y;
if (!dictionary3.ContainsKey(x))
{
dictionary3.Add(x, dictionary[x]);
int num3 = -1;
if (dictionary4.TryGetValue(dictionary[x], out num3))
{
dictionary[x] = num3;
}
else
{
num3 = num + num2++;
dictionary4.Add(dictionary[x], num3);
dictionary[x] = num3;
}
}
if (!dictionary3.ContainsKey(y))
{
dictionary3.Add(y, dictionary[y]);
int num4 = -1;
if (dictionary4.TryGetValue(dictionary[y], out num4))
{
dictionary[y] = num4;
}
else
{
num4 = num + num2++;
dictionary4.Add(dictionary[y], num4);
dictionary[y] = num4;
}
}
dictionary.Add(count, dictionary3[x]);
dictionary.Add(count + 1, dictionary3[y]);
dictionary.Add(count + 2, dictionary[x]);
dictionary.Add(count + 3, dictionary[y]);
dictionary5.Add(count + 2, x);
dictionary5.Add(count + 3, y);
list.Add(new pb_Vertex(list[x]));
list.Add(new pb_Vertex(list[y]));
list.Add(null);
list.Add(null);
pb_Face pb_Face = new pb_Face(new int[]
{
count,
count + 1,
count + 2,
count + 1,
count + 3,
count + 2
}, value.material, new pb_UV(value.uv), value.smoothingGroup, -1, -1, false);
list2.Add(pb_Face);
}
foreach (pb_Face pb_Face2 in hashSet)
{
pb_Face2.textureGroup = -1;
Vector3 vector = pb_Math.Normal(pb, pb_Face2);
for (int i = 0; i < pb_Face2.distinctIndices.Length; i++)
{
int num5 = pb_Face2.distinctIndices[i];
if (!dictionary3.ContainsKey(num5) && dictionary4.ContainsKey(dictionary[num5]))
{
dictionary[num5] = dictionary4[dictionary[num5]];
}
int num6 = dictionary[num5];
if (dictionary2 != null && dictionary2.ContainsKey(pb_Face2.distinctIndices[i]))
{
dictionary2.Remove(pb_Face2.distinctIndices[i]);
}
pb_Tuple<Vector3, Vector3, List<int>> pb_Tuple = null;
if (dictionary6.TryGetValue(num6, out pb_Tuple))
{
pb_Tuple<Vector3, Vector3, List<int>> pb_Tuple2 = pb_Tuple;
pb_Tuple2.Item1.x = pb_Tuple2.Item1.x + vector.x;
pb_Tuple<Vector3, Vector3, List<int>> pb_Tuple3 = pb_Tuple;
pb_Tuple3.Item1.y = pb_Tuple3.Item1.y + vector.y;
pb_Tuple<Vector3, Vector3, List<int>> pb_Tuple4 = pb_Tuple;
pb_Tuple4.Item1.z = pb_Tuple4.Item1.z + vector.z;
pb_Tuple.Item3.Add(num5);
}
else
{
dictionary6.Add(num6, new pb_Tuple<Vector3, Vector3, List<int>>(vector, vector, new List<int> { num5 }));
}
}
}
}
foreach (KeyValuePair<int, pb_Tuple<Vector3, Vector3, List<int>>> keyValuePair2 in dictionary6)
{
Vector3 vector2 = keyValuePair2.Value.Item1 / (float)keyValuePair2.Value.Item3.Count;
vector2.Normalize();
float num7 = ((!compensateAngleVertexDistance) ? 1f : pb_Math.Secant(Vector3.Angle(vector2, keyValuePair2.Value.Item2) * 0.017453292f));
vector2.x *= distance * num7;
vector2.y *= distance * num7;
vector2.z *= distance * num7;
foreach (int num8 in keyValuePair2.Value.Item3)
{
pb_Vertex pb_Vertex = list[num8];
pb_Vertex.position.x = pb_Vertex.position.x + vector2.x;
pb_Vertex pb_Vertex2 = list[num8];
pb_Vertex2.position.y = pb_Vertex2.position.y + vector2.y;
pb_Vertex pb_Vertex3 = list[num8];
pb_Vertex3.position.z = pb_Vertex3.position.z + vector2.z;
}
}
foreach (KeyValuePair<int, int> keyValuePair3 in dictionary5)
{
list[keyValuePair3.Key] = new pb_Vertex(list[keyValuePair3.Value]);
}
pb.SetVertices(list, false);
pb.SetFaces(list2.ToArray());
pb.SetSharedIndices(dictionary);
pb.SetSharedIndicesUV(dictionary2);
return true;
}
// Token: 0x06000091 RID: 145 RVA: 0x0000C528 File Offset: 0x0000A928
private static List<HashSet<pb_Face>> GetFaceGroups(List<pb_WingedEdge> wings)
{
HashSet<pb_Face> hashSet = new HashSet<pb_Face>();
List<HashSet<pb_Face>> list = new List<HashSet<pb_Face>>();
foreach (pb_WingedEdge pb_WingedEdge in wings)
{
if (hashSet.Add(pb_WingedEdge.face))
{
HashSet<pb_Face> hashSet2 = new HashSet<pb_Face> { pb_WingedEdge.face };
pb_GrowShrink.Flood(pb_WingedEdge, hashSet2);
foreach (pb_Face pb_Face in hashSet2)
{
hashSet.Add(pb_Face);
}
list.Add(hashSet2);
}
}
return list;
}
// Token: 0x06000092 RID: 146 RVA: 0x0000C60C File Offset: 0x0000AA0C
private static Dictionary<pb_EdgeLookup, pb_Face> GetPerimeterEdges(HashSet<pb_Face> faces, Dictionary<int, int> lookup)
{
Dictionary<pb_EdgeLookup, pb_Face> dictionary = new Dictionary<pb_EdgeLookup, pb_Face>();
HashSet<pb_EdgeLookup> hashSet = new HashSet<pb_EdgeLookup>();
foreach (pb_Face pb_Face in faces)
{
foreach (pb_Edge pb_Edge in pb_Face.edges)
{
pb_EdgeLookup pb_EdgeLookup = new pb_EdgeLookup(lookup[pb_Edge.x], lookup[pb_Edge.y], pb_Edge.x, pb_Edge.y);
if (!hashSet.Add(pb_EdgeLookup))
{
if (dictionary.ContainsKey(pb_EdgeLookup))
{
dictionary.Remove(pb_EdgeLookup);
}
}
else
{
dictionary.Add(pb_EdgeLookup, pb_Face);
}
}
}
return dictionary;
}
}
}