294 lines
10 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|