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

182 lines
5.9 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace ProBuilder2.Common
{
// Token: 0x02000040 RID: 64
public static class pb_Spline
{
// Token: 0x06000218 RID: 536 RVA: 0x0001CD08 File Offset: 0x0001B108
public static pb_Object Extrude(IList<pb_BezierPoint> points, float radius = 0.5f, int columns = 32, int rows = 16, bool closeLoop = false, bool smooth = true)
{
pb_Object pb_Object = null;
pb_Spline.Extrude(points, radius, columns, rows, closeLoop, smooth, ref pb_Object);
return pb_Object;
}
// Token: 0x06000219 RID: 537 RVA: 0x0001CD28 File Offset: 0x0001B128
public static void Extrude(IList<pb_BezierPoint> bezierPoints, float radius, int columns, int rows, bool closeLoop, bool smooth, ref pb_Object target)
{
List<Quaternion> list = new List<Quaternion>();
List<Vector3> controlPoints = pb_Spline.GetControlPoints(bezierPoints, columns, closeLoop, list);
pb_Spline.Extrude(controlPoints, radius, rows, closeLoop, smooth, ref target, list);
}
// Token: 0x0600021A RID: 538 RVA: 0x0001CD58 File Offset: 0x0001B158
public static List<Vector3> GetControlPoints(IList<pb_BezierPoint> bezierPoints, int subdivisionsPerSegment, bool closeLoop, List<Quaternion> rotations)
{
int count = bezierPoints.Count;
List<Vector3> list = new List<Vector3>(subdivisionsPerSegment * count);
if (rotations != null)
{
rotations.Clear();
rotations.Capacity = subdivisionsPerSegment * count;
}
int num = ((!closeLoop) ? (count - 1) : count);
for (int i = 0; i < num; i++)
{
int num2 = ((closeLoop || i < count - 2) ? subdivisionsPerSegment : (subdivisionsPerSegment + 1));
for (int j = 0; j < num2; j++)
{
float num3 = (float)subdivisionsPerSegment;
list.Add(pb_BezierPoint.CubicPosition(bezierPoints[i], bezierPoints[(i + 1) % count], (float)j / num3));
if (rotations != null)
{
rotations.Add(Quaternion.Slerp(bezierPoints[i].rotation, bezierPoints[(i + 1) % count].rotation, (float)j / (float)(num2 - 1)));
}
}
}
return list;
}
// Token: 0x0600021B RID: 539 RVA: 0x0001CE50 File Offset: 0x0001B250
public static void Extrude(IList<Vector3> points, float radius, int radiusRows, bool closeLoop, bool smooth, ref pb_Object target, IList<Quaternion> pointRotations = null)
{
if (points == null || points.Count < 2)
{
return;
}
int count = points.Count;
int num = Math.Max(3, radiusRows);
int num2 = num + 1;
int num3 = num * 2;
int num4 = ((!closeLoop) ? (count - 1) : count) * 2 * num3;
bool flag = false;
bool flag2 = pointRotations != null && pointRotations.Count == points.Count;
Vector3[] array = new Vector3[num4];
pb_Face[] array2 = ((!flag) ? new pb_Face[((!closeLoop) ? (count - 1) : count) * num] : null);
int num5 = 0;
int num6 = 0;
int num7 = 0;
int num8 = ((!closeLoop) ? (count - 1) : count);
for (int i = 0; i < num8; i++)
{
float num9;
Quaternion quaternion = pb_Spline.GetRingRotation(points, i, closeLoop, out num9);
float num10;
Quaternion quaternion2 = pb_Spline.GetRingRotation(points, (i + 1) % count, closeLoop, out num10);
if (flag2)
{
quaternion *= pointRotations[i];
quaternion2 *= pointRotations[(i + 1) % count];
}
Vector3[] array3 = pb_Spline.VertexRing(quaternion, points[i], radius, num2);
Vector3[] array4 = pb_Spline.VertexRing(quaternion2, points[(i + 1) % count], radius, num2);
Array.Copy(array3, 0, array, num7, num3);
num7 += num3;
Array.Copy(array4, 0, array, num7, num3);
num7 += num3;
if (!flag)
{
for (int j = 0; j < num3; j += 2)
{
array2[num6] = new pb_Face(new int[]
{
num5,
num5 + 1,
num5 + num3,
num5 + num3,
num5 + 1,
num5 + num3 + 1
});
if (smooth)
{
array2[num6].smoothingGroup = 2;
}
num6++;
num5 += 2;
}
num5 += num3;
}
}
if (target != null)
{
if (array2 != null)
{
target.GeometryWithVerticesFaces(array, array2);
}
else
{
target.SetVertices(array);
target.ToMesh();
target.Refresh(RefreshMask.UV | RefreshMask.Colors | RefreshMask.Normals | RefreshMask.Tangents);
}
}
else
{
target = pb_Object.CreateInstanceWithVerticesFaces(array, array2);
}
}
// Token: 0x0600021C RID: 540 RVA: 0x0001D084 File Offset: 0x0001B484
private static Quaternion GetRingRotation(IList<Vector3> points, int i, bool closeLoop, out float secant)
{
int count = points.Count;
Vector3 vector;
if (closeLoop || (i > 0 && i < count - 1))
{
int num = ((i >= 1) ? (i - 1) : (count - 1));
int num2 = (i + 1) % count;
Vector3 normalized = (points[i] - points[num]).normalized;
Vector3 normalized2 = (points[num2] - points[i]).normalized;
vector = (normalized + normalized2) * 0.5f;
secant = pb_Math.Secant(Vector3.Angle(normalized, vector) * 0.017453292f);
}
else
{
if (i < 1)
{
vector = points[i + 1] - points[i];
}
else
{
vector = points[i] - points[i - 1];
}
secant = 1f;
}
vector.Normalize();
if (vector.Approx3(Vector3.up, 0.0001f) || vector.Approx3(Vector3.zero, 0.0001f))
{
return Quaternion.identity;
}
return Quaternion.LookRotation(vector);
}
// Token: 0x0600021D RID: 541 RVA: 0x0001D1B4 File Offset: 0x0001B5B4
private static Vector3[] VertexRing(Quaternion orientation, Vector3 offset, float radius, int segments)
{
Vector3[] array = new Vector3[segments * 2];
for (int i = 0; i < segments; i++)
{
float num = (float)i / (float)(segments - 1) * 360f * 0.017453292f;
int num2 = (i + 1) % segments;
float num3 = (float)num2 / (float)(segments - 1) * 360f * 0.017453292f;
array[i * 2] = offset + orientation * new Vector3(Mathf.Cos(num) * radius, Mathf.Sin(num) * radius, 0f);
array[i * 2 + 1] = offset + orientation * new Vector3(Mathf.Cos(num3) * radius, Mathf.Sin(num3) * radius, 0f);
}
return array;
}
}
}