1
This commit is contained in:
@@ -5,41 +5,41 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 计算位置到边上最近的点
|
/// 计算位置到边上最近的点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AlgorithmSidePoint : ModuleAlgorithm<DataIntersect> {
|
//public class AlgorithmSidePoint : ModuleAlgorithm<DataIntersect> {
|
||||||
|
|
||||||
protected override void Awake() => ModuleCore.AlgorithmSidePoint = this;
|
// protected override void Awake() => ModuleCore.AlgorithmSidePoint = this;
|
||||||
|
|
||||||
public override void Compute(DataIntersect data) {
|
// public override void Compute(DataIntersect data) {
|
||||||
Vector3 position = data.position - data.side.plate.designPosition;
|
// Vector3 position = data.position - data.side.plate.designPosition;
|
||||||
for (int i = 0; i < data.side.lines.Length; i++) {
|
// for (int i = 0; i < data.side.lines.Length; i++) {
|
||||||
DataLine line = data.side.lines[i];
|
// DataLine line = data.side.lines[i];
|
||||||
if (!Compute(line, position, out Vector3 intersectPoint)) { continue; }
|
// if (!Compute(line, position, out Vector3 intersectPoint)) { continue; }
|
||||||
data.isIntersect = true;
|
// data.isIntersect = true;
|
||||||
data.intersectPoint = intersectPoint + data.side.plate.designPosition;
|
// data.intersectPoint = intersectPoint + data.side.plate.designPosition;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary> 查询匹配的边 </summary>
|
// /// <summary> 查询匹配的边 </summary>
|
||||||
private bool Compute(DataLine line, Vector3 position, out Vector3 intersectPoint) {
|
// private bool Compute(DataLine line, Vector3 position, out Vector3 intersectPoint) {
|
||||||
return ProjectDistance(line.a, line.b, position, out intersectPoint);
|
// return ProjectDistance(line.a, line.b, position, out intersectPoint);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 向量投影法
|
// /// 向量投影法
|
||||||
/// 计算点c到线段ab最近的点
|
// /// 计算点c到线段ab最近的点
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="a"></param>
|
// /// <param name="a"></param>
|
||||||
/// <param name="b"></param>
|
// /// <param name="b"></param>
|
||||||
/// <param name="c"></param>
|
// /// <param name="c"></param>
|
||||||
/// <returns>如果不在线段上返回 false</returns>
|
// /// <returns>如果不在线段上返回 false</returns>
|
||||||
public static bool ProjectDistance(Vector3 a, Vector3 b, Vector3 c, out Vector3 intersectPoint) {
|
// public static bool ProjectDistance(Vector3 a, Vector3 b, Vector3 c, out Vector3 intersectPoint) {
|
||||||
Vector3 ab = b - a;
|
// Vector3 ab = b - a;
|
||||||
Vector3 ac = c - a;
|
// Vector3 ac = c - a;
|
||||||
Vector3 p = Vector3.Project(ac, ab.normalized);
|
// Vector3 p = Vector3.Project(ac, ab.normalized);
|
||||||
intersectPoint = p + a;
|
// intersectPoint = p + a;
|
||||||
if (ab.normalized != p.normalized) { return false; }
|
// if (ab.normalized != p.normalized) { return false; }
|
||||||
if (ab.magnitude < p.magnitude) { return false; }
|
// if (ab.magnitude < p.magnitude) { return false; }
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ using UnityEngine;
|
|||||||
/// 散列点生成简单多边形算法
|
/// 散列点生成简单多边形算法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AlgorithmSimplePolygon : ModuleAlgorithm<DataPlate> {
|
public class AlgorithmSimplePolygon : ModuleAlgorithm<DataPlate> {
|
||||||
private UnitAlgorithm<DataPlate> AlgorithmSideSubdivision = new UnitAlgorithmBezier();
|
private UnitAlgorithm<DataPlateDesign> AlgorithmSideSubdivision = new UnitAlgorithmJobsSideSubdivision();
|
||||||
private UnitAlgorithm<DataPlate> AlgorithmTriangle = new UnitAlgorithmEarCutting();
|
private UnitAlgorithm<DataPlateDesign> AlgorithmTriangle = new UnitAlgorithmEarCutting();
|
||||||
private UnitAlgorithm<DataPlate> AlgorithmMergeTriangle = new UnitAlgorithmMergeTriangle();
|
private UnitAlgorithm<DataPlateDesign> AlgorithmMergeTriangle = new UnitAlgorithmMergeTriangle();
|
||||||
|
|
||||||
protected override void Awake() => ModuleCore.AlgorithmSimplePolygon = this;
|
protected override void Awake() => ModuleCore.AlgorithmSimplePolygon = this;
|
||||||
|
|
||||||
public override void Compute(DataPlate data) {
|
public override void Compute(DataPlate plate) {
|
||||||
//遍历计算边(DataSide)上的细分点(positions)和线(lines)
|
//遍历计算边(DataSide)上的细分点(positions)和线(lines)
|
||||||
AlgorithmSideSubdivision.Compute(data);
|
AlgorithmSideSubdivision.Compute(plate.dataDesign);
|
||||||
//计算三角面
|
//计算三角面
|
||||||
AlgorithmTriangle.Compute(data);
|
AlgorithmTriangle.Compute(plate.dataDesign);
|
||||||
//三角面列表转换网格
|
//三角面列表转换网格
|
||||||
AlgorithmMergeTriangle.Compute(data);
|
AlgorithmMergeTriangle.Compute(plate.dataDesign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缝合边算法模块
|
||||||
|
/// </summary>
|
||||||
|
public class AlgorithmSuture : ModuleAlgorithm<DataSuture> {
|
||||||
|
/// <summary> 设计的缝合线 </summary>
|
||||||
|
public UnitAlgorithm<DataSutureSide> SutureDesign = new UnitAlgorithmSutureDesign();
|
||||||
|
/// <summary> 烘焙的缝合线 </summary>
|
||||||
|
public UnitAlgorithm<DataSutureSide> SutureBaking = new UnitAlgorithmSutureBaking();
|
||||||
|
|
||||||
|
protected override void Awake() => ModuleCore.AlgorithmSuture = this;
|
||||||
|
|
||||||
|
public override void Compute(DataSuture suture) {
|
||||||
|
//缝合边长
|
||||||
|
float aLength = suture.a.plateSide.dataDesign.length;
|
||||||
|
float bLength = suture.b.plateSide.dataDesign.length;
|
||||||
|
suture.length = aLength < bLength ? aLength : bLength;
|
||||||
|
//设计缝合顶点
|
||||||
|
SutureDesign.Compute(suture.a);
|
||||||
|
SutureDesign.Compute(suture.b);
|
||||||
|
//烘焙缝合顶点
|
||||||
|
SutureBaking.Compute(suture.a);
|
||||||
|
SutureBaking.Compute(suture.b);
|
||||||
|
//缝合锚点
|
||||||
|
suture.points = new List<DataSuturePoint>();
|
||||||
|
suture.points.AddRange(Compute(suture.a, suture.b));
|
||||||
|
suture.points.AddRange(Compute(suture.b, suture.a));
|
||||||
|
}
|
||||||
|
private List<DataSuturePoint> Compute(DataSutureSide a, DataSutureSide b) {
|
||||||
|
DataSutureSideVertex[] vertexs = a.dataBaking.vertexs;
|
||||||
|
DataSutureSideVertex[] allVertexs = b.dataBaking.allVertexs;
|
||||||
|
List<DataSuturePoint> suturePoints = new List<DataSuturePoint>();
|
||||||
|
for (int i = 0; i < vertexs.Length; i++) {
|
||||||
|
DataSutureSideVertex vertex = vertexs[i];
|
||||||
|
for (int j = 0; j < allVertexs.Length; j++) {
|
||||||
|
DataSutureSideVertex anchor = allVertexs[j];
|
||||||
|
if (anchor.MaxDistance < vertex.origin) { continue; }
|
||||||
|
DataSuturePoint suturePoint = new DataSuturePoint();
|
||||||
|
suturePoint.distance = vertex.origin - anchor.origin;
|
||||||
|
suturePoint.vertex = vertex.a;
|
||||||
|
suturePoint.aAnchor = anchor.a;
|
||||||
|
suturePoint.bAnchor = anchor.b;
|
||||||
|
suturePoints.Add(suturePoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return suturePoints;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bc0a831375a5abe418c790ae74a19376
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -6,62 +6,62 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 缝合边算法模块
|
/// 缝合边算法模块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AlgorithmSutureSide : ModuleAlgorithm<DataSutureSide> {
|
//public class AlgorithmSutureSide : ModuleAlgorithm<DataSutureSide> {
|
||||||
public class VertexPosition : IComparable<VertexPosition> {
|
// public class VertexPosition : IComparable<VertexPosition> {
|
||||||
public Vector3 designPosition;
|
// public Vector3 designPosition;
|
||||||
public Vector3 bakingPosition;
|
// public Vector3 bakingPosition;
|
||||||
public float distance;
|
// public float distance;
|
||||||
public int CompareTo(VertexPosition other) {
|
// public int CompareTo(VertexPosition other) {
|
||||||
return other.distance >= distance ? 1 : -1;
|
// return other.distance >= distance ? 1 : -1;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
protected override void Awake() => ModuleCore.AlgorithmSutureSide = this;
|
// protected override void Awake() => ModuleCore.AlgorithmSutureSide = this;
|
||||||
|
|
||||||
public override void Compute(DataSutureSide data) {
|
// public override void Compute(DataSutureSide data) {
|
||||||
//List<VertexPosition> vertexPositions = VertexPositions(data);
|
// //List<VertexPosition> vertexPositions = VertexPositions(data);
|
||||||
data.designPositions = VertexToDesignPositions(data).ToArray();
|
// data.designPositions = VertexToDesignPositions(data).ToArray();
|
||||||
data.bakingPositions = VertexToBakingPositions(data).ToArray();
|
// data.bakingPositions = VertexToBakingPositions(data).ToArray();
|
||||||
}
|
// }
|
||||||
|
|
||||||
private List<VertexPosition> VertexPositions(DataSutureSide sutureSide) {
|
// private List<VertexPosition> VertexPositions(DataSutureSide sutureSide) {
|
||||||
List<VertexPosition> vertexPositions = new List<VertexPosition>();
|
// List<VertexPosition> vertexPositions = new List<VertexPosition>();
|
||||||
for (int i = 0; i < sutureSide.Vertices.Length; i++) {
|
// for (int i = 0; i < sutureSide.Vertices.Length; i++) {
|
||||||
Vector3 design = sutureSide.Vertices[i].design;
|
// Vector3 design = sutureSide.Vertices[i].design;
|
||||||
Quaternion quaternion = Quaternion.Euler(sutureSide.PlateBakingEulerAngles);
|
// Quaternion quaternion = Quaternion.Euler(sutureSide.PlateBakingEulerAngles);
|
||||||
Vector3 baking = quaternion * sutureSide.Vertices[i].design;
|
// Vector3 baking = quaternion * sutureSide.Vertices[i].design;
|
||||||
VertexPosition vertexPosition = new VertexPosition();
|
// VertexPosition vertexPosition = new VertexPosition();
|
||||||
vertexPosition.designPosition = design + sutureSide.PlateDesignPosition;
|
// vertexPosition.designPosition = design + sutureSide.PlateDesignPosition;
|
||||||
vertexPosition.bakingPosition = baking + sutureSide.PlateBakingPosition;
|
// vertexPosition.bakingPosition = baking + sutureSide.PlateBakingPosition;
|
||||||
vertexPosition.distance = Vector3.Distance(design, sutureSide.side.aPoint.position);
|
// vertexPosition.distance = Vector3.Distance(design, sutureSide.side.aPoint.position);
|
||||||
vertexPositions.Add(vertexPosition);
|
// vertexPositions.Add(vertexPosition);
|
||||||
}
|
// }
|
||||||
//按距离从小到大排序
|
// //按距离从小到大排序
|
||||||
vertexPositions.Sort();
|
// vertexPositions.Sort();
|
||||||
//是否颠倒
|
// //是否颠倒
|
||||||
if (sutureSide.isReversal) { vertexPositions.Reverse(); }
|
// if (sutureSide.isReversal) { vertexPositions.Reverse(); }
|
||||||
return vertexPositions;
|
// return vertexPositions;
|
||||||
}
|
// }
|
||||||
private List<Vector3> VertexToDesignPositions(DataSutureSide data) {
|
// private List<Vector3> VertexToDesignPositions(DataSutureSide data) {
|
||||||
//转换列表
|
// //转换列表
|
||||||
List<Vector3> positions = new List<Vector3>();
|
// List<Vector3> positions = new List<Vector3>();
|
||||||
for (int i = 0; i < data.Vertices.Length; i++) {
|
// for (int i = 0; i < data.Vertices.Length; i++) {
|
||||||
Vector3 position = data.Vertices[i].design + data.PlateDesignPosition;
|
// Vector3 position = data.Vertices[i].design + data.PlateDesignPosition;
|
||||||
positions.Add(position);
|
// positions.Add(position);
|
||||||
}
|
// }
|
||||||
if (data.isReversal) { positions.Reverse(); }
|
// if (data.isReversal) { positions.Reverse(); }
|
||||||
return positions;
|
// return positions;
|
||||||
}
|
// }
|
||||||
private List<Vector3> VertexToBakingPositions(DataSutureSide data) {
|
// private List<Vector3> VertexToBakingPositions(DataSutureSide data) {
|
||||||
//转换列表
|
// //转换列表
|
||||||
List<Vector3> positions = new List<Vector3>();
|
// List<Vector3> positions = new List<Vector3>();
|
||||||
for (int i = 0; i < data.Vertices.Length; i++) {
|
// for (int i = 0; i < data.Vertices.Length; i++) {
|
||||||
Quaternion quaternion = Quaternion.Euler(data.PlateBakingEulerAngles);
|
// Quaternion quaternion = Quaternion.Euler(data.PlateBakingEulerAngles);
|
||||||
Vector3 baking = quaternion * data.Vertices[i].design;
|
// Vector3 baking = quaternion * data.Vertices[i].design;
|
||||||
Vector3 position = baking + data.PlateBakingPosition;
|
// Vector3 position = baking + data.PlateBakingPosition;
|
||||||
positions.Add(position);
|
// positions.Add(position);
|
||||||
}
|
// }
|
||||||
if (data.isReversal) { positions.Reverse(); }
|
// if (data.isReversal) { positions.Reverse(); }
|
||||||
return positions;
|
// return positions;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class ResetBakingPolygon : MonoBehaviour
|
||||||
|
{
|
||||||
|
// Start is called before the first frame update
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is called once per frame
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f24a4f73b9925a9478f58b089059ef1e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -17,14 +17,14 @@ public class AssetsPlate : ModuleAssets<DataPlate> {
|
|||||||
|
|
||||||
protected override void Awake() => ModuleCore.AssetsPlate = this;
|
protected override void Awake() => ModuleCore.AssetsPlate = this;
|
||||||
|
|
||||||
public override void Add(DataPlate data) {
|
public override void Add(DataPlate plate) {
|
||||||
if (dataPlates.Contains(data)) { return; }
|
if (dataPlates.Contains(plate)) { return; }
|
||||||
dataPlates.Add(data);
|
dataPlates.Add(plate);
|
||||||
//初始化参数
|
//初始化参数
|
||||||
data.designPosition = ViewCameraDesign.CameraPosition;
|
plate.dataDesign.position = ViewCameraDesign.CameraPosition;
|
||||||
data.bakingPosition = ViewCameraDesign.CameraPosition;
|
plate.dataBaking.position = ViewCameraDesign.CameraPosition;
|
||||||
//生成可视化内容
|
//生成可视化内容
|
||||||
data.UpdateVisual();
|
plate.UpdateVisual();
|
||||||
}
|
}
|
||||||
public override void Remove(DataPlate data) {
|
public override void Remove(DataPlate data) {
|
||||||
if (!dataPlates.Contains(data)) { return; }
|
if (!dataPlates.Contains(data)) { return; }
|
||||||
|
|||||||
@@ -5,37 +5,37 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 插入点(DataInsertPoint) 转换 点(DataPoint)
|
/// 插入点(DataInsertPoint) 转换 点(DataPoint)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BuilderInsertPointToPoint : ModuleBuilder<DataInsertPoint, DataPoint> {
|
//public class BuilderInsertPointToPoint : ModuleBuilder<DataInsertPoint, DataPoint> {
|
||||||
|
|
||||||
protected override void Awake() => ModuleCore.InsertPointToPoint = this;
|
// protected override void Awake() => ModuleCore.InsertPointToPoint = this;
|
||||||
|
|
||||||
public override DataPoint To(DataInsertPoint insertPoint) {
|
// public override DataPoint To(DataInsertPoint insertPoint) {
|
||||||
DataPlate plate = insertPoint.plate;
|
// DataPlate plate = insertPoint.plate;
|
||||||
Vector3 position = insertPoint.position;
|
// Vector3 position = insertPoint.position;
|
||||||
//创建新的点
|
// //创建新的点
|
||||||
DataPoint point = new DataPoint(insertPoint.plate);
|
// DataPoint point = new DataPoint(insertPoint.plate);
|
||||||
point.position = position;
|
// point.position = position;
|
||||||
//改变关联的边B点,重置贝塞尔曲线
|
// //改变关联的边B点,重置贝塞尔曲线
|
||||||
insertPoint.side.bPoint = point;
|
// insertPoint.side.bPoint = point;
|
||||||
insertPoint.side.OneRankBezier();
|
// insertPoint.side.OneRankBezier();
|
||||||
//创建新的边
|
// //创建新的边
|
||||||
DataSide side = CreateDataSide(plate, point, insertPoint.bPoint);
|
// DataSide side = CreateDataSide(plate, point, insertPoint.bPoint);
|
||||||
//插入边
|
// //插入边
|
||||||
int sideIndex = plate.sides.IndexOf(insertPoint.side);
|
// int sideIndex = plate.sides.IndexOf(insertPoint.side);
|
||||||
plate.sides.Insert(sideIndex + 1, side);
|
// plate.sides.Insert(sideIndex + 1, side);
|
||||||
//插入点
|
// //插入点
|
||||||
int pointIndex = plate.points.IndexOf(insertPoint.aPoint);
|
// int pointIndex = plate.points.IndexOf(insertPoint.aPoint);
|
||||||
plate.points.Insert(pointIndex + 1, point);
|
// plate.points.Insert(pointIndex + 1, point);
|
||||||
//更新数据
|
// //更新数据
|
||||||
plate.UpdateVisual();
|
// plate.UpdateVisual();
|
||||||
return point;
|
// return point;
|
||||||
}
|
// }
|
||||||
|
|
||||||
private DataSide CreateDataSide(DataPlate plate, DataPoint a, DataPoint b) {
|
// private DataSide CreateDataSide(DataPlate plate, DataPoint a, DataPoint b) {
|
||||||
DataSide side = new DataSide(plate);
|
// DataSide side = new DataSide(plate);
|
||||||
side.aPoint = a;
|
// side.aPoint = a;
|
||||||
side.bPoint = b;
|
// side.bPoint = b;
|
||||||
side.OneRankBezier();
|
// side.OneRankBezier();
|
||||||
return side;
|
// return side;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -11,24 +11,24 @@ public class BuilderPlatePresetsToPlate : ModuleBuilder<DataPlatePresets, DataPl
|
|||||||
|
|
||||||
public override DataPlate To(DataPlatePresets origin) {
|
public override DataPlate To(DataPlatePresets origin) {
|
||||||
DataPlate dataPlate = new DataPlate();
|
DataPlate dataPlate = new DataPlate();
|
||||||
dataPlate.points = ToDataPoint(dataPlate, origin.designPoints);
|
dataPlate.platePoints = ToDataPoint(dataPlate, origin.designPoints);
|
||||||
dataPlate.sides = ToDataSide(dataPlate, dataPlate.points);
|
dataPlate.plateSides = ToDataSide(dataPlate, dataPlate.platePoints);
|
||||||
return dataPlate;
|
return dataPlate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DataPoint> ToDataPoint(DataPlate dataPlate, List<Vector3> list) {
|
private List<DataPlatePoint> ToDataPoint(DataPlate dataPlate, List<Vector3> list) {
|
||||||
List<DataPoint> points = new List<DataPoint>();
|
List<DataPlatePoint> points = new List<DataPlatePoint>();
|
||||||
for (int i = 0; i < list.Count; i++) {
|
for (int i = 0; i < list.Count; i++) {
|
||||||
DataPoint point = new DataPoint(dataPlate);
|
DataPlatePoint point = new DataPlatePoint(dataPlate);
|
||||||
point.position = list[i];
|
point.position = list[i];
|
||||||
points.Add(point);
|
points.Add(point);
|
||||||
}
|
}
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
private List<DataSide> ToDataSide(DataPlate dataPlate, List<DataPoint> list) {
|
private List<DataPlateSide> ToDataSide(DataPlate dataPlate, List<DataPlatePoint> list) {
|
||||||
List<DataSide> sides = new List<DataSide>();
|
List<DataPlateSide> sides = new List<DataPlateSide>();
|
||||||
for (int i = 0; i < list.Count; i++) {
|
for (int i = 0; i < list.Count; i++) {
|
||||||
DataSide side = new DataSide(dataPlate);
|
DataPlateSide side = new DataPlateSide(dataPlate);
|
||||||
side.aPoint = list.LoopIndex(i + 0);
|
side.aPoint = list.LoopIndex(i + 0);
|
||||||
side.bPoint = list.LoopIndex(i + 1);
|
side.bPoint = list.LoopIndex(i + 1);
|
||||||
side.OneRankBezier();
|
side.OneRankBezier();
|
||||||
|
|||||||
@@ -46,37 +46,37 @@ public class ModuleCore : Module<ModuleCore> {
|
|||||||
public ModuleBuilder<DataPlatePresets, DataPlate> PlatePresetsToPlate;
|
public ModuleBuilder<DataPlatePresets, DataPlate> PlatePresetsToPlate;
|
||||||
/// <summary> 板片数据(DataPlate) 转换 多边形数据(DataPolygon) </summary>
|
/// <summary> 板片数据(DataPlate) 转换 多边形数据(DataPolygon) </summary>
|
||||||
public ModuleBuilder<DataPlate, DataPolygon> PlateToPolygon;
|
public ModuleBuilder<DataPlate, DataPolygon> PlateToPolygon;
|
||||||
/// <summary> 插入点(DataInsertPoint) 转换 点(DataPoint) </summary>
|
|
||||||
public ModuleBuilder<DataInsertPoint, DataPoint> InsertPointToPoint;
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 可视模块
|
#region 可视模块
|
||||||
/// <summary> 设计可视化内容生成模块 </summary>
|
/// <summary> 板片设计 可视化内容生成模块 </summary>
|
||||||
public ModuleVisual<DataPlate> VisualDesign;
|
public ModuleVisual<DataPlate> VisualPlateDesign;
|
||||||
/// <summary> 烘焙可视化内容生成模块 </summary>
|
/// <summary> 板片烘焙 可视化内容生成模块 </summary>
|
||||||
public ModuleVisual<DataPlate> VisualBaking;
|
public ModuleVisual<DataPlate> VisualPlateBaking;
|
||||||
/// <summary> 连接可视化内容生成模块 </summary>
|
/// <summary> 缝合设计 可视化内容生成模块 </summary>
|
||||||
|
public ModuleVisual<DataSuture> VisualSutureDesign;
|
||||||
|
/// <summary> 缝合烘焙 可视化内容生成模块 </summary>
|
||||||
|
public ModuleVisual<DataSuture> VisualSutureBaking;
|
||||||
|
/// <summary> 连接器 可视化内容生成模块 </summary>
|
||||||
public ModuleVisual<DataConnector> VisualConnector;
|
public ModuleVisual<DataConnector> VisualConnector;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 查询模块
|
#region 查询模块
|
||||||
/// <summary> 查询点模块 </summary>
|
/// <summary> 查询点模块 </summary>
|
||||||
public ModuleFind<DataPoint> FindPoint;
|
public ModuleFind<DataPlatePoint> FindPoint;
|
||||||
/// <summary> 查询边模块 </summary>
|
/// <summary> 查询边模块 </summary>
|
||||||
public ModuleFind<DataSide> FindSide;
|
public ModuleFind<DataPlateSide> FindSide;
|
||||||
/// <summary> 查询贝塞尔点模块 </summary>
|
/// <summary> 查询贝塞尔点模块 </summary>
|
||||||
public ModuleFind<DataBezier> FindBezier;
|
public ModuleFind<DataBezier> FindBezier;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 算法模块
|
#region 算法模块
|
||||||
/// <summary> 计算位置到边上最近的点 </summary>
|
|
||||||
public ModuleAlgorithm<DataIntersect> AlgorithmSidePoint;
|
|
||||||
/// <summary> 简单多边形算法模块 </summary>
|
/// <summary> 简单多边形算法模块 </summary>
|
||||||
public ModuleAlgorithm<DataPlate> AlgorithmSimplePolygon;
|
public ModuleAlgorithm<DataPlate> AlgorithmSimplePolygon;
|
||||||
/// <summary> 细分多边形算法模块 </summary>
|
/// <summary> 细分多边形算法模块 </summary>
|
||||||
public ModuleAlgorithm<DataPlate> AlgorithmSubdivisionPolygon;
|
public ModuleAlgorithm<DataPlate> AlgorithmSubdivisionPolygon;
|
||||||
/// <summary> 缝合边算法模块 </summary>
|
/// <summary> 缝合边算法模块 </summary>
|
||||||
public ModuleAlgorithm<DataSutureSide> AlgorithmSutureSide;
|
public ModuleAlgorithm<DataSuture> AlgorithmSuture;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 事件定义
|
#region 事件定义
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class FindBezier : ModuleFind<DataBezier> {
|
|||||||
public override bool Find(Vector3 position, out DataBezier bezier) {
|
public override bool Find(Vector3 position, out DataBezier bezier) {
|
||||||
List<DataPlate> plates = AssetsPlate.Datas;
|
List<DataPlate> plates = AssetsPlate.Datas;
|
||||||
for (int i = 0; i < plates.Count; i++) {
|
for (int i = 0; i < plates.Count; i++) {
|
||||||
Vector3 localPosition = position - plates[i].designPosition;
|
Vector3 localPosition = position - plates[i].dataDesign.position;
|
||||||
bezier = Find(plates[i], localPosition);
|
bezier = Find(plates[i], localPosition);
|
||||||
if (bezier != null) { return true; }
|
if (bezier != null) { return true; }
|
||||||
}
|
}
|
||||||
@@ -24,14 +24,14 @@ public class FindBezier : ModuleFind<DataBezier> {
|
|||||||
|
|
||||||
/// <summary> 查询匹配的边 </summary>
|
/// <summary> 查询匹配的边 </summary>
|
||||||
private DataBezier Find(DataPlate plate, Vector3 localPosition) {
|
private DataBezier Find(DataPlate plate, Vector3 localPosition) {
|
||||||
for (int i = 0; i < plate.sides.Count; i++) {
|
for (int i = 0; i < plate.plateSides.Count; i++) {
|
||||||
DataBezier bezier = Find(plate.sides[i], localPosition);
|
DataBezier bezier = Find(plate.plateSides[i], localPosition);
|
||||||
if (bezier != null) { return bezier; }
|
if (bezier != null) { return bezier; }
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
/// <summary> 查询匹配的边 </summary>
|
/// <summary> 查询匹配的边 </summary>
|
||||||
private DataBezier Find(DataSide side, Vector3 localPosition) {
|
private DataBezier Find(DataPlateSide side, Vector3 localPosition) {
|
||||||
if (side.bezier == Bezier.一阶) { return null; }
|
if (side.bezier == Bezier.一阶) { return null; }
|
||||||
float aDis = Vector3.Distance(side.aBezier, localPosition);
|
float aDis = Vector3.Distance(side.aBezier, localPosition);
|
||||||
if (aDis < FindRange) { return new DataBezier() { isA = true, side = side }; }
|
if (aDis < FindRange) { return new DataBezier() { isA = true, side = side }; }
|
||||||
|
|||||||
@@ -5,17 +5,17 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找点
|
/// 查找点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FindPoint : ModuleFind<DataPoint> {
|
public class FindPoint : ModuleFind<DataPlatePoint> {
|
||||||
public readonly float FindRange = 0.01f;
|
public readonly float FindRange = 0.01f;
|
||||||
/// <summary> 板片资产 </summary>
|
/// <summary> 板片资产 </summary>
|
||||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||||
|
|
||||||
protected override void Awake() => ModuleCore.FindPoint = this;
|
protected override void Awake() => ModuleCore.FindPoint = this;
|
||||||
|
|
||||||
public override bool Find(Vector3 position, out DataPoint point) {
|
public override bool Find(Vector3 position, out DataPlatePoint point) {
|
||||||
List<DataPlate> plates = AssetsPlate.Datas;
|
List<DataPlate> plates = AssetsPlate.Datas;
|
||||||
for (int i = 0; i < plates.Count; i++) {
|
for (int i = 0; i < plates.Count; i++) {
|
||||||
Vector3 localPosition = position - plates[i].designPosition;
|
Vector3 localPosition = position - plates[i].dataDesign.position;
|
||||||
point = Find(plates[i], localPosition);
|
point = Find(plates[i], localPosition);
|
||||||
if (point != null) { return true; }
|
if (point != null) { return true; }
|
||||||
}
|
}
|
||||||
@@ -23,8 +23,8 @@ public class FindPoint : ModuleFind<DataPoint> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> 查询匹配的点 </summary>
|
/// <summary> 查询匹配的点 </summary>
|
||||||
private DataPoint Find(DataPlate plate, Vector3 localPosition) {
|
private DataPlatePoint Find(DataPlate plate, Vector3 localPosition) {
|
||||||
List<DataPoint> points = plate.points;
|
List<DataPlatePoint> points = plate.platePoints;
|
||||||
for (int i = 0; i < points.Count; i++) {
|
for (int i = 0; i < points.Count; i++) {
|
||||||
float distance = Vector3.Distance(points[i].position, localPosition);
|
float distance = Vector3.Distance(points[i].position, localPosition);
|
||||||
if (distance > FindRange) { continue; }
|
if (distance > FindRange) { continue; }
|
||||||
|
|||||||
@@ -5,17 +5,17 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找边
|
/// 查找边
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FindSide : ModuleFind<DataSide> {
|
public class FindSide : ModuleFind<DataPlateSide> {
|
||||||
public readonly float FindRange = 0.01f;
|
public readonly float FindRange = 0.01f;
|
||||||
/// <summary> 板片资产 </summary>
|
/// <summary> 板片资产 </summary>
|
||||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||||
|
|
||||||
protected override void Awake() => ModuleCore.FindSide = this;
|
protected override void Awake() => ModuleCore.FindSide = this;
|
||||||
|
|
||||||
public override bool Find(Vector3 position, out DataSide side) {
|
public override bool Find(Vector3 position, out DataPlateSide side) {
|
||||||
List<DataPlate> plates = AssetsPlate.Datas;
|
List<DataPlate> plates = AssetsPlate.Datas;
|
||||||
for (int i = 0; i < plates.Count; i++) {
|
for (int i = 0; i < plates.Count; i++) {
|
||||||
Vector3 localPosition = position - plates[i].designPosition;
|
Vector3 localPosition = position - plates[i].dataDesign.position;
|
||||||
side = Find(plates[i], localPosition);
|
side = Find(plates[i], localPosition);
|
||||||
if (side != null) { return true; }
|
if (side != null) { return true; }
|
||||||
}
|
}
|
||||||
@@ -23,20 +23,20 @@ public class FindSide : ModuleFind<DataSide> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> 查询匹配的边 </summary>
|
/// <summary> 查询匹配的边 </summary>
|
||||||
private DataSide Find(DataPlate plate, Vector3 localPosition) {
|
private DataPlateSide Find(DataPlate plate, Vector3 localPosition) {
|
||||||
for (int i = 0; i < plate.sides.Count; i++) {
|
for (int i = 0; i < plate.plateSides.Count; i++) {
|
||||||
DataSide side = Find(plate.sides[i], localPosition);
|
DataPlateSide side = Find(plate.plateSides[i], localPosition);
|
||||||
if (side != null) { return side; }
|
if (side != null) { return side; }
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
/// <summary> 查询匹配的边 </summary>
|
/// <summary> 查询匹配的边 </summary>
|
||||||
private DataSide Find(DataSide side, Vector3 localPosition) {
|
private DataPlateSide Find(DataPlateSide side, Vector3 localPosition) {
|
||||||
for (int i = 0; i < side.lines.Length; i++) {
|
DataPlateSideDesign design = side.dataDesign;
|
||||||
Vector3 a = side.lines[i].a;
|
for (int i = 0; i < design.lines.Length; i++) {
|
||||||
Vector3 b = side.lines[i].b;
|
Vector3 a = design.lines[i].a;
|
||||||
|
Vector3 b = design.lines[i].b;
|
||||||
float distance = ProjectDistance(a, b, localPosition);
|
float distance = ProjectDistance(a, b, localPosition);
|
||||||
//Debug.Log($"{a} , {b} , {localPosition}");
|
|
||||||
if (distance < FindRange) { return side; }
|
if (distance < FindRange) { return side; }
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -2,45 +2,45 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class VisualBaking : ModuleVisual<DataPlate> {
|
//public class VisualBaking : ModuleVisual<DataPlate> {
|
||||||
public Transform viewSpace;
|
// public Transform viewSpace;
|
||||||
public Transform platePrefab;//板片
|
// public Transform platePrefab;//板片
|
||||||
public Transform suturePrefab;//缝合
|
// public Transform suturePrefab;//缝合
|
||||||
public Transform sutureSidePrefab;//缝合边
|
// public Transform sutureSidePrefab;//缝合边
|
||||||
|
|
||||||
protected override void Awake() => ModuleCore.VisualBaking = this;
|
// protected override void Awake() => ModuleCore.VisualBaking = this;
|
||||||
|
|
||||||
public override void UpdateVisual(DataPlate plate) {
|
// public override void UpdateVisual(DataPlate plate) {
|
||||||
//更新板片
|
// //更新板片
|
||||||
Create(ref plate.baking, platePrefab, viewSpace);
|
// Create(ref plate.baking, platePrefab, viewSpace);
|
||||||
plate.baking.UpdateVisual(plate);
|
// plate.baking.UpdateVisual(plate);
|
||||||
//子数据父对象
|
// //子数据父对象
|
||||||
Transform parent = plate.design.transform;
|
// Transform parent = plate.design.transform;
|
||||||
//更新线段
|
// //更新线段
|
||||||
plate.sides.ForEach(obj => UpdateVisual(obj, parent));
|
// plate.sides.ForEach(obj => UpdateVisual(obj, parent));
|
||||||
}
|
// }
|
||||||
public override void ReleaseVisual(DataPlate data) {
|
// public override void ReleaseVisual(DataPlate data) {
|
||||||
throw new System.NotImplementedException();
|
// throw new System.NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void UpdateVisual(DataSide side, Transform parent) {
|
// private void UpdateVisual(DataSide side, Transform parent) {
|
||||||
//Create(ref side.design, sidePrefab, parent);
|
// //Create(ref side.design, sidePrefab, parent);
|
||||||
//side.design.UpdateVisual(side);
|
// //side.design.UpdateVisual(side);
|
||||||
//更新缝合线
|
// //更新缝合线
|
||||||
if (side.suture == null) { return; }
|
// if (side.suture == null) { return; }
|
||||||
//side.suture.Update();
|
// //side.suture.Update();
|
||||||
UpdateVisual(side.suture, viewSpace);
|
// UpdateVisual(side.suture, viewSpace);
|
||||||
}
|
// }
|
||||||
/// <summary> 更新缝合数据 </summary>
|
// /// <summary> 更新缝合数据 </summary>
|
||||||
private void UpdateVisual(DataSuture suture, Transform parent) {
|
// private void UpdateVisual(DataSuture suture, Transform parent) {
|
||||||
Create(ref suture.baking, suturePrefab, parent);
|
// Create(ref suture.baking, suturePrefab, parent);
|
||||||
UpdateVisual(suture.a, suture.baking.transform);
|
// UpdateVisual(suture.a, suture.baking.transform);
|
||||||
UpdateVisual(suture.b, suture.baking.transform);
|
// UpdateVisual(suture.b, suture.baking.transform);
|
||||||
suture.baking.UpdateVisual(suture);
|
// suture.baking.UpdateVisual(suture);
|
||||||
}
|
// }
|
||||||
/// <summary> 更新缝合边 </summary>
|
// /// <summary> 更新缝合边 </summary>
|
||||||
private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
// private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
||||||
Create(ref sutureSide.baking, sutureSidePrefab, parent);
|
// Create(ref sutureSide.baking, sutureSidePrefab, parent);
|
||||||
sutureSide.baking.UpdateVisual(sutureSide);
|
// sutureSide.baking.UpdateVisual(sutureSide);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -5,53 +5,53 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 版片可视化模块
|
/// 版片可视化模块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class VisualDesign : ModuleVisual<DataPlate> {
|
//public class VisualDesign : ModuleVisual<DataPlate> {
|
||||||
public Transform viewSpace;
|
// public Transform viewSpace;
|
||||||
public Transform platePrefab;//板片
|
// public Transform platePrefab;//板片
|
||||||
public Transform pointPrefab;//点
|
// public Transform pointPrefab;//点
|
||||||
public Transform sidePrefab;//边
|
// public Transform sidePrefab;//边
|
||||||
public Transform suturePrefab;//缝合
|
// public Transform suturePrefab;//缝合
|
||||||
public Transform sutureSidePrefab;//缝合边
|
// public Transform sutureSidePrefab;//缝合边
|
||||||
|
|
||||||
protected override void Awake() => ModuleCore.VisualDesign = this;
|
// protected override void Awake() => ModuleCore.VisualDesign = this;
|
||||||
|
|
||||||
public override void UpdateVisual(DataPlate plate) {
|
// public override void UpdateVisual(DataPlate plate) {
|
||||||
//更新板片
|
// //更新板片
|
||||||
Create(ref plate.design, platePrefab, viewSpace);
|
// Create(ref plate.design, platePrefab, viewSpace);
|
||||||
plate.design.UpdateVisual(plate);
|
// plate.design.UpdateVisual(plate);
|
||||||
//子数据父对象
|
// //子数据父对象
|
||||||
Transform parent = plate.design.transform;
|
// Transform parent = plate.design.transform;
|
||||||
//更新点
|
// //更新点
|
||||||
plate.points.ForEach(obj => UpdateVisual(obj, parent));
|
// plate.points.ForEach(obj => UpdateVisual(obj, parent));
|
||||||
//更新线段
|
// //更新线段
|
||||||
plate.sides.ForEach(obj => UpdateVisual(obj, parent));
|
// plate.sides.ForEach(obj => UpdateVisual(obj, parent));
|
||||||
}
|
// }
|
||||||
public override void ReleaseVisual(DataPlate data) {
|
// public override void ReleaseVisual(DataPlate data) {
|
||||||
throw new System.NotImplementedException();
|
// throw new System.NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void UpdateVisual(DataPoint point, Transform parent) {
|
// private void UpdateVisual(DataPoint point, Transform parent) {
|
||||||
Create(ref point.visual, pointPrefab, parent);
|
// Create(ref point.visual, pointPrefab, parent);
|
||||||
point.visual.UpdateVisual(point);
|
// point.visual.UpdateVisual(point);
|
||||||
}
|
// }
|
||||||
private void UpdateVisual(DataSide side, Transform parent) {
|
// private void UpdateVisual(DataSide side, Transform parent) {
|
||||||
Create(ref side.design, sidePrefab, parent);
|
// Create(ref side.design, sidePrefab, parent);
|
||||||
side.design.UpdateVisual(side);
|
// side.design.UpdateVisual(side);
|
||||||
//更新缝合线
|
// //更新缝合线
|
||||||
if (side.suture == null) { return; }
|
// if (side.suture == null) { return; }
|
||||||
side.suture.Update();
|
// side.suture.Update();
|
||||||
UpdateVisual(side.suture, viewSpace);
|
// UpdateVisual(side.suture, viewSpace);
|
||||||
}
|
// }
|
||||||
/// <summary> 更新缝合数据 </summary>
|
// /// <summary> 更新缝合数据 </summary>
|
||||||
private void UpdateVisual(DataSuture suture, Transform parent) {
|
// private void UpdateVisual(DataSuture suture, Transform parent) {
|
||||||
Create(ref suture.design, suturePrefab, parent);
|
// Create(ref suture.design, suturePrefab, parent);
|
||||||
UpdateVisual(suture.a, suture.design.transform);
|
// UpdateVisual(suture.a, suture.design.transform);
|
||||||
UpdateVisual(suture.b, suture.design.transform);
|
// UpdateVisual(suture.b, suture.design.transform);
|
||||||
suture.design.UpdateVisual(suture);
|
// suture.design.UpdateVisual(suture);
|
||||||
}
|
// }
|
||||||
/// <summary> 更新缝合边 </summary>
|
// /// <summary> 更新缝合边 </summary>
|
||||||
private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
// private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
||||||
Create(ref sutureSide.design, sutureSidePrefab, parent);
|
// Create(ref sutureSide.design, sutureSidePrefab, parent);
|
||||||
sutureSide.design.UpdateVisual(sutureSide);
|
// sutureSide.design.UpdateVisual(sutureSide);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class VisualPlateBaking : ModuleVisual<DataPlate> {
|
||||||
|
public Transform viewSpace;
|
||||||
|
public Transform platePrefab;//板片
|
||||||
|
public Transform suturePrefab;//缝合
|
||||||
|
public Transform sutureSidePrefab;//缝合边
|
||||||
|
|
||||||
|
protected override void Awake() => ModuleCore.VisualPlateBaking = this;
|
||||||
|
|
||||||
|
public override void UpdateVisual(DataPlate plate) {
|
||||||
|
//更新板片
|
||||||
|
Create(ref plate.bakingPrefab, platePrefab, viewSpace);
|
||||||
|
plate.bakingPrefab.UpdateVisual(plate);
|
||||||
|
//子数据父对象
|
||||||
|
Transform parent = plate.designPrefab.transform;
|
||||||
|
//更新线段
|
||||||
|
plate.plateSides.ForEach(obj => UpdateVisual(obj, parent));
|
||||||
|
}
|
||||||
|
public override void ReleaseVisual(DataPlate data) {
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVisual(DataPlateSide side, Transform parent) {
|
||||||
|
//Create(ref side.design, sidePrefab, parent);
|
||||||
|
//side.design.UpdateVisual(side);
|
||||||
|
//更新缝合线
|
||||||
|
//if (side.suture == null) { return; }
|
||||||
|
//side.suture.Update();
|
||||||
|
//UpdateVisual(side.suture, viewSpace);
|
||||||
|
}
|
||||||
|
/// <summary> 更新缝合数据 </summary>
|
||||||
|
private void UpdateVisual(DataSuture suture, Transform parent) {
|
||||||
|
Create(ref suture.baking, suturePrefab, parent);
|
||||||
|
UpdateVisual(suture.a, suture.baking.transform);
|
||||||
|
UpdateVisual(suture.b, suture.baking.transform);
|
||||||
|
suture.baking.UpdateVisual(suture);
|
||||||
|
}
|
||||||
|
/// <summary> 更新缝合边 </summary>
|
||||||
|
private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
||||||
|
Create(ref sutureSide.baking, sutureSidePrefab, parent);
|
||||||
|
sutureSide.baking.UpdateVisual(sutureSide);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ef4a839345dfb344382e257d374ca3ed
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 版片可视化模块
|
||||||
|
/// </summary>
|
||||||
|
public class VisualPlateDesign : ModuleVisual<DataPlate> {
|
||||||
|
public Transform viewSpace;
|
||||||
|
public Transform platePrefab;//板片
|
||||||
|
public Transform pointPrefab;//点
|
||||||
|
public Transform sidePrefab;//边
|
||||||
|
|
||||||
|
protected override void Awake() => ModuleCore.VisualPlateDesign = this;
|
||||||
|
|
||||||
|
public override void UpdateVisual(DataPlate plate) {
|
||||||
|
//更新板片
|
||||||
|
Create(ref plate.designPrefab, platePrefab, viewSpace);
|
||||||
|
plate.designPrefab.UpdateVisual(plate);
|
||||||
|
//子数据父对象
|
||||||
|
Transform parent = plate.designPrefab.transform;
|
||||||
|
//更新点
|
||||||
|
plate.platePoints.ForEach(obj => UpdateVisual(obj, parent));
|
||||||
|
//更新线段
|
||||||
|
plate.plateSides.ForEach(obj => UpdateVisual(obj, parent));
|
||||||
|
}
|
||||||
|
public override void ReleaseVisual(DataPlate data) {
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVisual(DataPlatePoint point, Transform parent) {
|
||||||
|
Create(ref point.visual, pointPrefab, parent);
|
||||||
|
point.visual.UpdateVisual(point);
|
||||||
|
}
|
||||||
|
private void UpdateVisual(DataPlateSide side, Transform parent) {
|
||||||
|
Create(ref side.designPrefab, sidePrefab, parent);
|
||||||
|
side.designPrefab.UpdateVisual(side);
|
||||||
|
//更新缝合线
|
||||||
|
if (side.suture != null) { side.suture.UpdateVisual(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f9827f83f79c2af42b2a06bdc3c80719
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缝合烘焙可视化模块
|
||||||
|
/// </summary>
|
||||||
|
public class VisualSutureBaking : ModuleVisual<DataSuture> {
|
||||||
|
public Transform viewSpace;
|
||||||
|
public Transform suturePrefab;//缝合
|
||||||
|
public Transform sutureSidePrefab;//缝合边
|
||||||
|
|
||||||
|
protected override void Awake() => ModuleCore.VisualSutureBaking = this;
|
||||||
|
|
||||||
|
public override void UpdateVisual(DataSuture suture) {
|
||||||
|
Create(ref suture.baking, suturePrefab, viewSpace);
|
||||||
|
suture.baking.UpdateVisual(suture);
|
||||||
|
|
||||||
|
UpdateVisual(suture.a, suture.baking.transform);
|
||||||
|
UpdateVisual(suture.b, suture.baking.transform);
|
||||||
|
}
|
||||||
|
public override void ReleaseVisual(DataSuture data) {
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 更新缝合边 </summary>
|
||||||
|
private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
||||||
|
Create(ref sutureSide.baking, sutureSidePrefab, parent);
|
||||||
|
sutureSide.baking.UpdateVisual(sutureSide);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 06ff2a0f351be2d41aa7c8dfc23798e0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缝合设计可视化模块
|
||||||
|
/// </summary>
|
||||||
|
public class VisualSutureDesign : ModuleVisual<DataSuture> {
|
||||||
|
public Transform viewSpace;
|
||||||
|
public Transform suturePrefab;//缝合
|
||||||
|
public Transform sutureSidePrefab;//缝合边
|
||||||
|
|
||||||
|
protected override void Awake() => ModuleCore.VisualSutureDesign = this;
|
||||||
|
|
||||||
|
public override void UpdateVisual(DataSuture suture) {
|
||||||
|
Create(ref suture.design, suturePrefab, viewSpace);
|
||||||
|
suture.design.UpdateVisual(suture);
|
||||||
|
|
||||||
|
UpdateVisual(suture.a, suture.design.transform);
|
||||||
|
UpdateVisual(suture.b, suture.design.transform);
|
||||||
|
}
|
||||||
|
public override void ReleaseVisual(DataSuture data) {
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 更新缝合边 </summary>
|
||||||
|
private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
||||||
|
Create(ref sutureSide.design, sutureSidePrefab, parent);
|
||||||
|
sutureSide.design.UpdateVisual(sutureSide);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a43eabbe6a52df943b5157da8933dd33
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -6,7 +6,7 @@ public class DataBezier {
|
|||||||
/// <summary> 是否是a </summary>
|
/// <summary> 是否是a </summary>
|
||||||
public bool isA;
|
public bool isA;
|
||||||
/// <summary> 关联的边 </summary>
|
/// <summary> 关联的边 </summary>
|
||||||
public DataSide side;
|
public DataPlateSide side;
|
||||||
/// <summary> 位置 </summary>
|
/// <summary> 位置 </summary>
|
||||||
public Vector3 position => isA ? side.aBezier : side.bBezier;
|
public Vector3 position => isA ? side.aBezier : side.bBezier;
|
||||||
|
|
||||||
|
|||||||
@@ -2,21 +2,34 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
/// <summary> 2D边界数据 </summary>
|
/// <summary> 边界数据 </summary>
|
||||||
public class DataBorder {
|
public class DataBorder {
|
||||||
|
/// <summary> 网格细分 </summary>
|
||||||
|
public readonly float smooth = 0.01f;
|
||||||
|
/// <summary> minX </summary>
|
||||||
public readonly float minX = 0;
|
public readonly float minX = 0;
|
||||||
|
/// <summary> maxX </summary>
|
||||||
public readonly float maxX = 0;
|
public readonly float maxX = 0;
|
||||||
|
/// <summary> minY </summary>
|
||||||
public readonly float minY = 0;
|
public readonly float minY = 0;
|
||||||
|
/// <summary> maxY </summary>
|
||||||
public readonly float maxY = 0;
|
public readonly float maxY = 0;
|
||||||
/// <summary> 2D边界数据 </summary>
|
/// <summary> 多边形边缘点 </summary>
|
||||||
public DataBorder(float minX, float maxX, float minY, float maxY) {
|
public readonly Vector3[] points;
|
||||||
|
/// <summary> 边界数据 </summary>
|
||||||
|
public DataBorder(float minX, float maxX, float minY, float maxY, Vector3[] points) {
|
||||||
this.minX = minX; this.maxX = maxX;
|
this.minX = minX; this.maxX = maxX;
|
||||||
this.minY = minY; this.maxY = maxY;
|
this.minY = minY; this.maxY = maxY;
|
||||||
|
this.points = points;
|
||||||
}
|
}
|
||||||
/// <summary> 边界宽 </summary>
|
/// <summary> 边界宽 </summary>
|
||||||
public float Wide => maxX - minX;
|
public float Wide => maxX - minX;
|
||||||
/// <summary> 边界高 </summary>
|
/// <summary> 边界高 </summary>
|
||||||
public float High => maxY - minY;
|
public float High => maxY - minY;
|
||||||
|
/// <summary> 网格宽 </summary>
|
||||||
|
public int GridWide => Mathf.FloorToInt(Wide / smooth) + 1;
|
||||||
|
/// <summary> 网格高 </summary>
|
||||||
|
public int GridHigh => Mathf.FloorToInt(High / smooth) + 1;
|
||||||
/// <summary> 最小点 </summary>
|
/// <summary> 最小点 </summary>
|
||||||
public Vector3 MinPoint => new Vector3(minX, minY, 0);
|
public Vector3 MinPoint => new Vector3(minX, minY, 0);
|
||||||
/// <summary> 最大点 </summary>
|
/// <summary> 最大点 </summary>
|
||||||
|
|||||||
@@ -7,18 +7,22 @@ public class DataPlate {
|
|||||||
/// <summary> 核心模块 </summary>
|
/// <summary> 核心模块 </summary>
|
||||||
private ModuleCore ModuleCore => ModuleCore.I;
|
private ModuleCore ModuleCore => ModuleCore.I;
|
||||||
/// <summary> 设计可视化模块 </summary>
|
/// <summary> 设计可视化模块 </summary>
|
||||||
private ModuleVisual<DataPlate> VisualDesign => ModuleCore.VisualDesign;
|
private ModuleVisual<DataPlate> VisualDesign => ModuleCore.VisualPlateDesign;
|
||||||
/// <summary> 烘焙可视化模块 </summary>
|
/// <summary> 烘焙可视化模块 </summary>
|
||||||
private ModuleVisual<DataPlate> VisualBaking => ModuleCore.VisualBaking;
|
private ModuleVisual<DataPlate> VisualBaking => ModuleCore.VisualPlateBaking;
|
||||||
/// <summary> 简单多边形算法模块 </summary>
|
/// <summary> 简单多边形算法模块 </summary>
|
||||||
private ModuleAlgorithm<DataPlate> AlgorithmSimplePolygon => ModuleCore.AlgorithmSimplePolygon;
|
private ModuleAlgorithm<DataPlate> AlgorithmSimplePolygon => ModuleCore.AlgorithmSimplePolygon;
|
||||||
/// <summary> 细分多边形算法模块 </summary>
|
/// <summary> 细分多边形算法模块 </summary>
|
||||||
private ModuleAlgorithm<DataPlate> AlgorithmSubdivisionPolygon => ModuleCore.AlgorithmSubdivisionPolygon;
|
private ModuleAlgorithm<DataPlate> AlgorithmSubdivisionPolygon => ModuleCore.AlgorithmSubdivisionPolygon;
|
||||||
|
|
||||||
|
public DataPlate() {
|
||||||
|
dataDesign = new DataPlateDesign(this);
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateVisual(bool recalculate = true) {
|
public void UpdateVisual(bool recalculate = true) {
|
||||||
if (recalculate) {
|
if (recalculate) {
|
||||||
//简单多边形计算
|
//简单多边形计算
|
||||||
//AlgorithmSimplePolygon.Compute(this);
|
AlgorithmSimplePolygon.Compute(this);
|
||||||
//细分多边形计算
|
//细分多边形计算
|
||||||
AlgorithmSubdivisionPolygon.Compute(this);
|
AlgorithmSubdivisionPolygon.Compute(this);
|
||||||
}
|
}
|
||||||
@@ -29,42 +33,55 @@ public class DataPlate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region 核心数据
|
#region 核心数据
|
||||||
/// <summary> 边缘平滑度 </summary>
|
|
||||||
public float smooth = 0.01f;
|
|
||||||
/// <summary> 板片设计视图的位置(本地坐标系) </summary>
|
|
||||||
public Vector3 designPosition;
|
|
||||||
/// <summary> 板片烘焙视图的位置(本地坐标系) </summary>
|
|
||||||
public Vector3 bakingPosition;
|
|
||||||
/// <summary> 板片烘焙视图的旋转(本地坐标系) </summary>
|
|
||||||
public Vector3 bakingEulerAngles;
|
|
||||||
/// <summary> 点 </summary>
|
/// <summary> 点 </summary>
|
||||||
public List<DataPoint> points = new List<DataPoint>();
|
public List<DataPlatePoint> platePoints = new List<DataPlatePoint>();
|
||||||
/// <summary> 边 </summary>
|
/// <summary> 边 </summary>
|
||||||
public List<DataSide> sides = new List<DataSide>();
|
public List<DataPlateSide> plateSides = new List<DataPlateSide>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 次要数据
|
#region 次要数据
|
||||||
/// <summary> 边界数据 </summary>
|
/// <summary> 设计缓存数据 </summary>
|
||||||
public DataBorder border;
|
public DataPlateDesign dataDesign;
|
||||||
/// <summary> 边缘点 </summary>
|
/// <summary> 烘焙缓存数据 </summary>
|
||||||
public List<Vector3> edgePoints;
|
public DataPlateBaking dataBaking = new DataPlateBaking();
|
||||||
/// <summary> 设计网格 </summary>
|
|
||||||
public Mesh designMesh;
|
|
||||||
|
|
||||||
/// <summary> 三角形数据 </summary>
|
|
||||||
public List<DataTriangle> triangles;
|
|
||||||
|
|
||||||
/// <summary> 顶点网格 </summary>
|
|
||||||
public GridTool<DataVertex> vertexGrid;
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 可视化数据
|
#region 可视化数据
|
||||||
/// <summary> 可视化对象 </summary>
|
/// <summary> 可视化对象 </summary>
|
||||||
public ModulePrefab<DataPlate> design;
|
public ModulePrefab<DataPlate> designPrefab;
|
||||||
/// <summary> 可视化对象 </summary>
|
/// <summary> 可视化对象 </summary>
|
||||||
public ModulePrefab<DataPlate> baking;
|
public ModulePrefab<DataPlate> bakingPrefab;
|
||||||
/// <summary> 安排点 </summary>
|
/// <summary> 安排点 </summary>
|
||||||
public FixedArrange arrange;
|
public FixedArrange arrange;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
/// <summary> 设计缓存数据 </summary>
|
||||||
|
public class DataPlateDesign {
|
||||||
|
/// <summary> 板片 </summary>
|
||||||
|
public readonly DataPlate plate;
|
||||||
|
/// <summary> 设计缓存数据 </summary>
|
||||||
|
public DataPlateDesign(DataPlate plate) => this.plate = plate;
|
||||||
|
|
||||||
|
/// <summary> 板片的位置 </summary>
|
||||||
|
public Vector3 position;
|
||||||
|
/// <summary> 网格 </summary>
|
||||||
|
public Mesh mesh;
|
||||||
|
/// <summary> 边缘点 </summary>
|
||||||
|
public Vector3[] points;
|
||||||
|
/// <summary> 三角形数据 </summary>
|
||||||
|
public List<DataTriangle> triangles;
|
||||||
|
}
|
||||||
|
/// <summary> 烘焙缓存数据 </summary>
|
||||||
|
public class DataPlateBaking {
|
||||||
|
/// <summary> 网格 </summary>
|
||||||
|
public Mesh mesh;
|
||||||
|
/// <summary> 板片的位置 </summary>
|
||||||
|
public Vector3 position;
|
||||||
|
/// <summary> 板片的旋转 </summary>
|
||||||
|
public Vector3 eulerAngles;
|
||||||
|
/// <summary> 边界数据 </summary>
|
||||||
|
public DataBorder border;
|
||||||
|
/// <summary> 全部顶点 </summary>
|
||||||
|
public DataPlateVertex[] vertexs;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary> 线段 </summary>
|
||||||
|
public class DataPlateLine {
|
||||||
|
/// <summary> 线段起点a </summary>
|
||||||
|
public Vector3 a;
|
||||||
|
/// <summary> 线段终点b </summary>
|
||||||
|
public Vector3 b;
|
||||||
|
/// <summary> 原始距离 </summary>
|
||||||
|
public float origin;
|
||||||
|
/// <summary> 线段距离 </summary>
|
||||||
|
public float Distance => Vector3.Distance(a, b);
|
||||||
|
/// <summary> 线段方向 </summary>
|
||||||
|
public Vector3 Direction => b - a;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c7e8d3e741e703d49b33431b75a3a001
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class DataPlatePoint {
|
||||||
|
/// <summary> 绑定的板片 </summary>
|
||||||
|
public readonly DataPlate plate;
|
||||||
|
/// <summary> 初始化 </summary>
|
||||||
|
public DataPlatePoint(DataPlate plate) => this.plate = plate;
|
||||||
|
|
||||||
|
#region 核心数据
|
||||||
|
/// <summary> 设计点位置(本地坐标系) </summary>
|
||||||
|
public Vector3 position;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 可视化数据
|
||||||
|
/// <summary> 可视化对象 </summary>
|
||||||
|
public ModulePrefab<DataPlatePoint> visual;
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6c2af0d32eea37f408900226b81e8e8a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Unity.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public enum Bezier {
|
||||||
|
一阶 = 0, 二阶 = 1, 三阶 = 2
|
||||||
|
}
|
||||||
|
/// <summary> 边 </summary>
|
||||||
|
public class DataPlateSide {
|
||||||
|
/// <summary> 绑定的板片 </summary>
|
||||||
|
public readonly DataPlate plate;
|
||||||
|
/// <summary> 初始化 </summary>
|
||||||
|
public DataPlateSide(DataPlate plate) => this.plate = plate;
|
||||||
|
|
||||||
|
#region 核心数据
|
||||||
|
/// <summary> 贝塞尔曲线阶数 </summary>
|
||||||
|
public Bezier bezier;
|
||||||
|
/// <summary> 起点 </summary>
|
||||||
|
public DataPlatePoint aPoint;
|
||||||
|
/// <summary> 终点 </summary>
|
||||||
|
public DataPlatePoint bPoint;
|
||||||
|
/// <summary> 贝塞尔曲线前(-) </summary>
|
||||||
|
public Vector3 aBezier;
|
||||||
|
/// <summary> 贝塞尔曲线后(+) </summary>
|
||||||
|
public Vector3 bBezier;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 次要数据
|
||||||
|
/// <summary> 缝合数据 </summary>
|
||||||
|
public DataSuture suture;
|
||||||
|
/// <summary> 设计缓存数据 </summary>
|
||||||
|
public DataPlateSideDesign dataDesign = new DataPlateSideDesign();
|
||||||
|
/// <summary> 烘焙缓存数据 </summary>
|
||||||
|
public DataPlateSideBaking dataBaking = new DataPlateSideBaking();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 可视化内容
|
||||||
|
/// <summary> 可视化边缘线 </summary>
|
||||||
|
public ModulePrefab<DataPlateSide> designPrefab;
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
/// <summary> 设计缓存数据 </summary>
|
||||||
|
public class DataPlateSideDesign {
|
||||||
|
/// <summary> 总长度 </summary>
|
||||||
|
public float length;
|
||||||
|
/// <summary> 点 </summary>
|
||||||
|
public Vector3[] positions = new Vector3[0];
|
||||||
|
/// <summary> 线 </summary>
|
||||||
|
public DataPlateLine[] lines = new DataPlateLine[0];
|
||||||
|
}
|
||||||
|
/// <summary> 烘焙缓存数据 </summary>
|
||||||
|
public class DataPlateSideBaking {
|
||||||
|
/// <summary> 总长度 </summary>
|
||||||
|
public float length;
|
||||||
|
/// <summary> 点 </summary>
|
||||||
|
public Vector3[] positions = new Vector3[0];
|
||||||
|
/// <summary> 线 </summary>
|
||||||
|
public DataPlateLine[] lines = new DataPlateLine[0];
|
||||||
|
/// <summary> 关联的网格顶点 </summary>
|
||||||
|
public DataPlateVertex[] vertexs = new DataPlateVertex[0];
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d0a57f0098d07ca4da0ca6e08c25662c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class DataPlateVertex {
|
||||||
|
/// <summary> 是否是有效顶点 </summary>
|
||||||
|
public bool isValid;
|
||||||
|
/// <summary> 设计视图中位置 </summary>
|
||||||
|
public Vector3 position;
|
||||||
|
|
||||||
|
/// <summary> 上 </summary>
|
||||||
|
public DataPlateVertex above;
|
||||||
|
/// <summary> 下 </summary>
|
||||||
|
public DataPlateVertex below;
|
||||||
|
/// <summary> 左 </summary>
|
||||||
|
public DataPlateVertex left;
|
||||||
|
/// <summary> 右 </summary>
|
||||||
|
public DataPlateVertex right;
|
||||||
|
|
||||||
|
/// <summary> 左上 </summary>
|
||||||
|
public DataPlateVertex leftAbove;
|
||||||
|
/// <summary> 左下 </summary>
|
||||||
|
public DataPlateVertex leftBelow;
|
||||||
|
/// <summary> 右上 </summary>
|
||||||
|
public DataPlateVertex rightAbove;
|
||||||
|
/// <summary> 右下 </summary>
|
||||||
|
public DataPlateVertex rightBelow;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9842037a7f0169b4bb8a4b70047f7739
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -2,9 +2,9 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public enum Bezier {
|
//public enum Bezier {
|
||||||
一阶 = 0, 二阶 = 1, 三阶 = 2
|
// 一阶 = 0, 二阶 = 1, 三阶 = 2
|
||||||
}
|
//}
|
||||||
public class DataSide {
|
public class DataSide {
|
||||||
/// <summary> 绑定的板片 </summary>
|
/// <summary> 绑定的板片 </summary>
|
||||||
public readonly DataPlate plate;
|
public readonly DataPlate plate;
|
||||||
|
|||||||
@@ -5,24 +5,33 @@ using UnityEngine;
|
|||||||
public class DataSuture {
|
public class DataSuture {
|
||||||
/// <summary> 核心模块 </summary>
|
/// <summary> 核心模块 </summary>
|
||||||
private ModuleCore ModuleCore => ModuleCore.I;
|
private ModuleCore ModuleCore => ModuleCore.I;
|
||||||
/// <summary> 简单多边形算法模块 </summary>
|
/// <summary> 设计可视化模块 </summary>
|
||||||
private ModuleAlgorithm<DataSutureSide> AlgorithmSutureSide => ModuleCore.AlgorithmSutureSide;
|
private ModuleVisual<DataSuture> VisualDesign => ModuleCore.VisualSutureDesign;
|
||||||
|
/// <summary> 烘焙可视化模块 </summary>
|
||||||
|
private ModuleVisual<DataSuture> VisualBaking => ModuleCore.VisualSutureBaking;
|
||||||
|
/// <summary> 缝合线算法模块 </summary>
|
||||||
|
private ModuleAlgorithm<DataSuture> AlgorithmSuture => ModuleCore.AlgorithmSuture;
|
||||||
|
|
||||||
public readonly DataSutureSide a;
|
public readonly DataSutureSide a;
|
||||||
public readonly DataSutureSide b;
|
public readonly DataSutureSide b;
|
||||||
public DataSuture(DataSide aSide, DataSide bSide) {
|
public DataSuture(DataPlateSide aSide, DataPlateSide bSide) {
|
||||||
a = new DataSutureSide(aSide, this);
|
a = new DataSutureSide(aSide, this);
|
||||||
b = new DataSutureSide(bSide, this);
|
b = new DataSutureSide(bSide, this);
|
||||||
Update();
|
UpdateVisual();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update() {
|
public void UpdateVisual() {
|
||||||
AlgorithmSutureSide.Compute(a);
|
AlgorithmSuture.Compute(this);
|
||||||
AlgorithmSutureSide.Compute(b);
|
VisualDesign.UpdateVisual(this);
|
||||||
|
VisualBaking.UpdateVisual(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region 次要数据
|
||||||
/// <summary> 缝合长度 </summary>
|
/// <summary> 缝合长度 </summary>
|
||||||
public float length => this.SutureLength();
|
public float length;
|
||||||
|
/// <summary> 缝合点 </summary>
|
||||||
|
public List<DataSuturePoint> points;
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region 可视化内容
|
#region 可视化内容
|
||||||
/// <summary> 可视化内容 </summary>
|
/// <summary> 可视化内容 </summary>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class DataSuturePoint {
|
||||||
|
/// <summary> aAnchor到vertex的距离 </summary>
|
||||||
|
public float distance;
|
||||||
|
/// <summary> 绑定的顶点 </summary>
|
||||||
|
public DataPlateVertex vertex;
|
||||||
|
/// <summary> 锚点a </summary>
|
||||||
|
public DataPlateVertex aAnchor;
|
||||||
|
/// <summary> 锚点b </summary>
|
||||||
|
public DataPlateVertex bAnchor;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fab08a6f4689d1c4b94d2fd7f05fedbe
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -7,12 +7,12 @@ using UnityEngine;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataSutureSide {
|
public class DataSutureSide {
|
||||||
/// <summary> 关联的边 </summary>
|
/// <summary> 关联的边 </summary>
|
||||||
public readonly DataSide side;
|
public readonly DataPlateSide plateSide;
|
||||||
/// <summary> 关联的缝合数据 </summary>
|
/// <summary> 关联的缝合数据 </summary>
|
||||||
public readonly DataSuture suture;
|
public readonly DataSuture suture;
|
||||||
/// <summary> 缝合边 </summary>
|
/// <summary> 缝合边 </summary>
|
||||||
public DataSutureSide(DataSide side, DataSuture suture) {
|
public DataSutureSide(DataPlateSide side, DataSuture suture) {
|
||||||
this.side = side;
|
this.plateSide = side;
|
||||||
this.suture = suture;
|
this.suture = suture;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,32 +22,10 @@ public class DataSutureSide {
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 次要数据
|
#region 次要数据
|
||||||
|
/// <summary> 设计缓存数据 </summary>
|
||||||
/// <summary> 边最大长度 </summary>
|
public DataSutureSideDesign dataDesign = new DataSutureSideDesign();
|
||||||
public float MaxLength => side.length;
|
/// <summary> 烘焙缓存数据 </summary>
|
||||||
/// <summary> 边缘顶点数据 </summary>
|
public DataSutureSideBaking dataBaking = new DataSutureSideBaking();
|
||||||
public DataVertex[] Vertices => side.vertices;
|
|
||||||
/// <summary> 设计视图板片位置 </summary>
|
|
||||||
public Vector3 PlateDesignPosition => side.plate.designPosition;
|
|
||||||
/// <summary> 烘焙视图板片位置 </summary>
|
|
||||||
public Vector3 PlateBakingPosition => side.plate.bakingPosition;
|
|
||||||
/// <summary> 烘焙视图板片位置 </summary>
|
|
||||||
public Vector3 PlateBakingEulerAngles => side.plate.bakingEulerAngles;
|
|
||||||
|
|
||||||
/// <summary> 设计视图顶点位置 </summary>
|
|
||||||
public Vector3[] designPositions;
|
|
||||||
/// <summary> 设计视图A点位置 </summary>
|
|
||||||
public Vector3 DesignPosintA => designPositions[0];
|
|
||||||
/// <summary> 设计视图B点位置 </summary>
|
|
||||||
public Vector3 DesignPosintB => designPositions[designPositions.Length - 1];
|
|
||||||
|
|
||||||
/// <summary> 烘焙视图顶点位置 </summary>
|
|
||||||
public Vector3[] bakingPositions;
|
|
||||||
/// <summary> 烘焙视图A点位置 </summary>
|
|
||||||
public Vector3 BakingPosintA => bakingPositions[0];
|
|
||||||
/// <summary> 烘焙视图B点位置 </summary>
|
|
||||||
public Vector3 BakingPosintB => bakingPositions[bakingPositions.Length - 1];
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 可视化数据
|
#region 可视化数据
|
||||||
@@ -57,3 +35,43 @@ public class DataSutureSide {
|
|||||||
public ModulePrefab<DataSutureSide> baking;
|
public ModulePrefab<DataSutureSide> baking;
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
/// <summary> 设计缓存数据 </summary>
|
||||||
|
public class DataSutureSideDesign {
|
||||||
|
/// <summary> 位置列表 </summary>
|
||||||
|
public Vector3[] positions;
|
||||||
|
/// <summary> A点位置 </summary>
|
||||||
|
public Vector3 PointA => positions[0];
|
||||||
|
/// <summary> B点位置 </summary>
|
||||||
|
public Vector3 PointB => positions[positions.Length - 1];
|
||||||
|
}
|
||||||
|
/// <summary> 烘焙缓存数据 </summary>
|
||||||
|
public class DataSutureSideBaking {
|
||||||
|
/// <summary> 位置列表 </summary>
|
||||||
|
public Vector3[] positions;
|
||||||
|
/// <summary> 全部顶点列表 </summary>
|
||||||
|
public DataSutureSideVertex[] allVertexs;
|
||||||
|
/// <summary> 关联的顶点列表 </summary>
|
||||||
|
public DataSutureSideVertex[] vertexs;
|
||||||
|
/// <summary> A点位置 </summary>
|
||||||
|
public Vector3 PointA => positions[0];
|
||||||
|
/// <summary> B点位置 </summary>
|
||||||
|
public Vector3 PointB => positions[positions.Length - 1];
|
||||||
|
}
|
||||||
|
public class DataSutureSideVertex {
|
||||||
|
/// <summary> 边起点到a点的距离 </summary>
|
||||||
|
public float origin;
|
||||||
|
/// <summary> a点 </summary>
|
||||||
|
public DataPlateVertex a;
|
||||||
|
/// <summary> a点的下一个点 </summary>
|
||||||
|
public DataPlateVertex b;
|
||||||
|
/// <summary> 缝合边顶点 </summary>
|
||||||
|
public DataSutureSideVertex(float origin, DataPlateVertex a, DataPlateVertex b) {
|
||||||
|
this.origin = origin;
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
/// <summary> 最大距离 origin + a - b </summary>
|
||||||
|
public float MaxDistance => origin + Distance;
|
||||||
|
/// <summary> 分段距离 a-b </summary>
|
||||||
|
public float Distance => Vector3.Distance(a.position, b.position);
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ public struct DataTriangle {
|
|||||||
public Vector3 a;
|
public Vector3 a;
|
||||||
public Vector3 b;
|
public Vector3 b;
|
||||||
public Vector3 c;
|
public Vector3 c;
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return $"{a} , {b} , {c}";
|
return $"{a} , {b} , {c}";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ public class PrefabPlateBaking : ModulePrefab<DataPlate> {
|
|||||||
|
|
||||||
public override void UpdateVisual(DataPlate plate) {
|
public override void UpdateVisual(DataPlate plate) {
|
||||||
this.plate = plate;
|
this.plate = plate;
|
||||||
transform.localPosition = plate.bakingPosition;
|
DataPlateBaking baking = plate.dataBaking;
|
||||||
transform.localEulerAngles = plate.bakingEulerAngles;
|
//transform.localPosition = baking.position;
|
||||||
|
//transform.localEulerAngles = baking.eulerAngles;
|
||||||
meshFilter.mesh = plate.designMesh;
|
meshFilter.mesh = baking.mesh;
|
||||||
meshCollider.sharedMesh = plate.designMesh;
|
meshCollider.sharedMesh = baking.mesh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ public class PrefabPlateDesign : ModulePrefab<DataPlate> {
|
|||||||
|
|
||||||
public override void UpdateVisual(DataPlate plate) {
|
public override void UpdateVisual(DataPlate plate) {
|
||||||
this.plate = plate;
|
this.plate = plate;
|
||||||
transform.localPosition = plate.designPosition;
|
DataPlateDesign design = plate.dataDesign;
|
||||||
meshFilter.mesh = plate.designMesh;
|
transform.localPosition = design.position;
|
||||||
meshCollider.sharedMesh = plate.designMesh;
|
meshFilter.mesh = design.mesh;
|
||||||
|
meshCollider.sharedMesh = design.mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class PrefabPoint : ModulePrefab<DataPoint> {
|
public class PrefabPoint : ModulePrefab<DataPlatePoint> {
|
||||||
private DataPoint point;
|
private DataPlatePoint point;
|
||||||
|
|
||||||
public override DataPoint Value => point;
|
public override DataPlatePoint Value => point;
|
||||||
|
|
||||||
public override void UpdateVisual(DataPoint point) {
|
public override void UpdateVisual(DataPlatePoint point) {
|
||||||
this.point = point;
|
this.point = point;
|
||||||
transform.localPosition = point.position;
|
transform.localPosition = point.position;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,20 +3,20 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class PrefabSide : ModulePrefab<DataSide> {
|
public class PrefabSide : ModulePrefab<DataPlateSide> {
|
||||||
public Transform aPoint;
|
public Transform aPoint;
|
||||||
public Transform bPoint;
|
public Transform bPoint;
|
||||||
public LineRenderer lineRenderer;
|
public LineRenderer lineRenderer;
|
||||||
public LineRenderer aBezier;
|
public LineRenderer aBezier;
|
||||||
public LineRenderer bBezier;
|
public LineRenderer bBezier;
|
||||||
private DataSide side;
|
private DataPlateSide side;
|
||||||
|
|
||||||
#region 引用模块
|
#region 引用模块
|
||||||
/// <summary> 设计UI输入模块 </summary>
|
/// <summary> 设计UI输入模块 </summary>
|
||||||
public ModuleUIInput<UnitMouseInput> UIInputDesign => ModuleCore.I.UIInputDesign;
|
public ModuleUIInput<UnitMouseInput> UIInputDesign => ModuleCore.I.UIInputDesign;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public override DataSide Value => side;
|
public override DataPlateSide Value => side;
|
||||||
|
|
||||||
private void Awake() {
|
private void Awake() {
|
||||||
UIInputDesign.OnChangeInput += UIInputDesign_OnChangeInput;
|
UIInputDesign.OnChangeInput += UIInputDesign_OnChangeInput;
|
||||||
@@ -34,11 +34,12 @@ public class PrefabSide : ModulePrefab<DataSide> {
|
|||||||
aBezier.gameObject.SetActive(false);
|
aBezier.gameObject.SetActive(false);
|
||||||
bBezier.gameObject.SetActive(false);
|
bBezier.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
public override void UpdateVisual(DataSide side) {
|
public override void UpdateVisual(DataPlateSide side) {
|
||||||
this.side = side;
|
this.side = side;
|
||||||
|
|
||||||
lineRenderer.positionCount = side.positions.Length;
|
DataPlateSideDesign design = side.dataDesign;
|
||||||
lineRenderer.SetPositions(side.positions);
|
lineRenderer.positionCount = design.positions.Length;
|
||||||
|
lineRenderer.SetPositions(design.positions);
|
||||||
|
|
||||||
Type type = UIInputDesign.Current.GetType();
|
Type type = UIInputDesign.Current.GetType();
|
||||||
if (type != typeof(DesignBezier)) { ActiveGameObject(false); return; }
|
if (type != typeof(DesignBezier)) { ActiveGameObject(false); return; }
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ public class PrefabSutureBaking : ModulePrefab<DataSuture> {
|
|||||||
public override void UpdateVisual(DataSuture suture) {
|
public override void UpdateVisual(DataSuture suture) {
|
||||||
this.suture = suture;
|
this.suture = suture;
|
||||||
|
|
||||||
aLineRenderer.SetPosition(0, suture.a.BakingPosintA);
|
DataSutureSideBaking aBaking = suture.a.dataBaking;
|
||||||
aLineRenderer.SetPosition(1, suture.b.BakingPosintA);
|
DataSutureSideBaking bBaking = suture.b.dataBaking;
|
||||||
|
aLineRenderer.SetPosition(0, aBaking.PointA);
|
||||||
|
aLineRenderer.SetPosition(1, bBaking.PointA);
|
||||||
|
|
||||||
bLineRenderer.SetPosition(0, suture.a.BakingPosintB);
|
bLineRenderer.SetPosition(0, aBaking.PointB);
|
||||||
bLineRenderer.SetPosition(1, suture.b.BakingPosintB);
|
bLineRenderer.SetPosition(1, bBaking.PointB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ public class PrefabSutureDesign : ModulePrefab<DataSuture> {
|
|||||||
public override void UpdateVisual(DataSuture suture) {
|
public override void UpdateVisual(DataSuture suture) {
|
||||||
this.suture = suture;
|
this.suture = suture;
|
||||||
|
|
||||||
aLineRenderer.SetPosition(0, suture.a.DesignPosintA);
|
DataSutureSideDesign aDesign = suture.a.dataDesign;
|
||||||
aLineRenderer.SetPosition(1, suture.b.DesignPosintA);
|
DataSutureSideDesign bDesign = suture.b.dataDesign;
|
||||||
|
aLineRenderer.SetPosition(0, aDesign.PointA);
|
||||||
|
aLineRenderer.SetPosition(1, bDesign.PointA);
|
||||||
|
|
||||||
bLineRenderer.SetPosition(0, suture.a.DesignPosintB);
|
bLineRenderer.SetPosition(0, aDesign.PointB);
|
||||||
bLineRenderer.SetPosition(1, suture.b.DesignPosintB);
|
bLineRenderer.SetPosition(1, bDesign.PointB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ public class PrefabSutureSideBaking : ModulePrefab<DataSutureSide> {
|
|||||||
public override void UpdateVisual(DataSutureSide sutureSide) {
|
public override void UpdateVisual(DataSutureSide sutureSide) {
|
||||||
this.sutureSide = sutureSide;
|
this.sutureSide = sutureSide;
|
||||||
|
|
||||||
lineRenderer.positionCount = sutureSide.bakingPositions.Length;
|
DataSutureSideBaking baking = sutureSide.dataBaking;
|
||||||
lineRenderer.SetPositions(sutureSide.bakingPositions);
|
lineRenderer.positionCount = baking.positions.Length;
|
||||||
|
lineRenderer.SetPositions(baking.positions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ public class PrefabSutureSideDesign : ModulePrefab<DataSutureSide> {
|
|||||||
public override void UpdateVisual(DataSutureSide sutureSide) {
|
public override void UpdateVisual(DataSutureSide sutureSide) {
|
||||||
this.sutureSide = sutureSide;
|
this.sutureSide = sutureSide;
|
||||||
|
|
||||||
lineRenderer.positionCount = sutureSide.designPositions.Length;
|
DataSutureSideDesign design = sutureSide.dataDesign;
|
||||||
lineRenderer.SetPositions(sutureSide.designPositions);
|
lineRenderer.positionCount = design.positions.Length;
|
||||||
|
lineRenderer.SetPositions(design.positions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,30 +3,30 @@ using System.Collections.Generic;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public static class DataSideTool {
|
public static class DataSideTool {
|
||||||
public static void SetBezierPositionA(this DataSide side, Vector3 position) {
|
public static void SetBezierPositionA(this DataPlateSide side, Vector3 position) {
|
||||||
if (side.bezier == Bezier.一阶) { return; }
|
if (side.bezier == Bezier.一阶) { return; }
|
||||||
if (side.bezier == Bezier.二阶) { side.bBezier = position; }
|
if (side.bezier == Bezier.二阶) { side.bBezier = position; }
|
||||||
side.aBezier = position;
|
side.aBezier = position;
|
||||||
}
|
}
|
||||||
public static void SetBezierPositionB(this DataSide side, Vector3 position) {
|
public static void SetBezierPositionB(this DataPlateSide side, Vector3 position) {
|
||||||
if (side.bezier == Bezier.一阶) { return; }
|
if (side.bezier == Bezier.一阶) { return; }
|
||||||
if (side.bezier == Bezier.二阶) { side.aBezier = position; }
|
if (side.bezier == Bezier.二阶) { side.aBezier = position; }
|
||||||
side.bBezier = position;
|
side.bBezier = position;
|
||||||
}
|
}
|
||||||
public static void OneRankBezier(this DataSide side) {
|
public static void OneRankBezier(this DataPlateSide side) {
|
||||||
side.bezier = Bezier.一阶;
|
side.bezier = Bezier.一阶;
|
||||||
}
|
}
|
||||||
public static void TwoRankBezier(this DataSide side) {
|
public static void TwoRankBezier(this DataPlateSide side) {
|
||||||
side.bezier = Bezier.二阶;
|
side.bezier = Bezier.二阶;
|
||||||
DataPoint a = side.aPoint;
|
DataPlatePoint a = side.aPoint;
|
||||||
DataPoint b = side.bPoint;
|
DataPlatePoint b = side.bPoint;
|
||||||
side.aBezier = a.position + (b.position - a.position) * 0.5f;
|
side.aBezier = a.position + (b.position - a.position) * 0.5f;
|
||||||
side.bBezier = a.position + (b.position - a.position) * 0.5f;
|
side.bBezier = a.position + (b.position - a.position) * 0.5f;
|
||||||
}
|
}
|
||||||
public static void ThreeRankBezier(this DataSide side) {
|
public static void ThreeRankBezier(this DataPlateSide side) {
|
||||||
side.bezier = Bezier.三阶;
|
side.bezier = Bezier.三阶;
|
||||||
DataPoint a = side.aPoint;
|
DataPlatePoint a = side.aPoint;
|
||||||
DataPoint b = side.bPoint;
|
DataPlatePoint b = side.bPoint;
|
||||||
side.aBezier = a.position + (b.position - a.position) * 0.3f;
|
side.aBezier = a.position + (b.position - a.position) * 0.3f;
|
||||||
side.bBezier = a.position + (b.position - a.position) * 0.7f;
|
side.bBezier = a.position + (b.position - a.position) * 0.7f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public static class DataSutureTool {
|
public static class DataSutureTool {
|
||||||
public static float SutureLength(this DataSuture suture) {
|
//public static float SutureLength(this DataSuture suture) {
|
||||||
if (suture.a.MaxLength < suture.b.MaxLength) {
|
// if (suture.a.MaxLength < suture.b.MaxLength) {
|
||||||
return suture.a.MaxLength;
|
// return suture.a.MaxLength;
|
||||||
}
|
// }
|
||||||
else { return suture.b.MaxLength; }
|
// else { return suture.b.MaxLength; }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 烘焙顶点计算
|
||||||
|
/// </summary>
|
||||||
|
public class UnitAlgorithmBakingVertex : UnitAlgorithm<DataPlateBaking> {
|
||||||
|
|
||||||
|
/// <summary> 烘焙顶点计算 </summary>
|
||||||
|
public UnitAlgorithmBakingVertex() { }
|
||||||
|
|
||||||
|
public void Compute(DataPlateBaking plateBaking) {
|
||||||
|
DataBorder border = plateBaking.border;
|
||||||
|
Vector3[] points = border.points;
|
||||||
|
|
||||||
|
//计算内部顶点
|
||||||
|
//plateBaking.grid = new GridTool<DataPlateVertex>(border.GridWide, border.GridHigh, (x, y) => {
|
||||||
|
// Vector3 position = border.MinPoint + new Vector3(x * border.smooth, y * border.smooth);
|
||||||
|
// DataPlateVertex vertex = new DataPlateVertex();
|
||||||
|
// vertex.isValid = FindPlateInside(points, position);
|
||||||
|
// vertex.position = position;
|
||||||
|
// return vertex;
|
||||||
|
//});
|
||||||
|
|
||||||
|
//List<DataPlateSide> plateSides = plateBaking.plate.plateSides;
|
||||||
|
//边缘所有的线段
|
||||||
|
//for (int i = 0; i < plateSides.Count; i++) {
|
||||||
|
//Compute(plateSides[i], border.GridWide, border.GridHigh, border, border.smooth, plateBaking.grid);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
/// <summary> 向网格和边缘写入顶点数据 </summary>
|
||||||
|
private void Compute(DataPlateSide side, int wide, int high, DataBorder border, float smooth, GridTool<DataPlateVertex> grid) {
|
||||||
|
DataPlateLine[] lines = side.dataBaking.lines;
|
||||||
|
List<SideVertex> sideVertices = new List<SideVertex>();
|
||||||
|
//计算水平线段顶点
|
||||||
|
for (int x = 0; x < wide; x++) {
|
||||||
|
Vector3 a = new Vector3(border.minX + x * smooth, border.minY - 1);
|
||||||
|
Vector3 b = new Vector3(border.minX + x * smooth, border.maxY + 1);
|
||||||
|
for (int i = 0; i < lines.Length; i++) {
|
||||||
|
DataPlateVertex vertex = Compute(a, b, lines[i], smooth, border, grid);
|
||||||
|
if (vertex == null) { continue; }
|
||||||
|
float distance = Vector3.Distance(lines[i].a, vertex.position) + lines[i].origin;
|
||||||
|
SideVertex sideVertex = new SideVertex();
|
||||||
|
sideVertex.distance = distance;
|
||||||
|
sideVertex.vertex = vertex;
|
||||||
|
sideVertices.Add(sideVertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//计算垂直线段顶点
|
||||||
|
for (int y = 0; y < high; y++) {
|
||||||
|
Vector3 a = new Vector3(border.minX - 1, border.minY + y * smooth);
|
||||||
|
Vector3 b = new Vector3(border.maxX + 1, border.minY + y * smooth);
|
||||||
|
for (int i = 0; i < lines.Length; i++) {
|
||||||
|
DataPlateVertex vertex = Compute(a, b, lines[i], smooth, border, grid);
|
||||||
|
if (vertex == null) { continue; }
|
||||||
|
float distance = Vector3.Distance(lines[i].a, vertex.position) + lines[i].origin;
|
||||||
|
SideVertex sideVertex = new SideVertex();
|
||||||
|
sideVertex.distance = distance;
|
||||||
|
sideVertex.vertex = vertex;
|
||||||
|
sideVertices.Add(sideVertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sideVertices.Sort();
|
||||||
|
List<DataPlateVertex> vertices = new List<DataPlateVertex>();
|
||||||
|
for (int i = 0; i < sideVertices.Count; i++) {
|
||||||
|
vertices.Add(sideVertices[i].vertex);
|
||||||
|
}
|
||||||
|
//side.vertices = vertices.ToArray();
|
||||||
|
}
|
||||||
|
/// <summary> 向网格写入边缘顶点数据 </summary>
|
||||||
|
private DataPlateVertex Compute(Vector3 a, Vector3 b, DataPlateLine line, float smooth, DataBorder border, GridTool<DataPlateVertex> grid) {
|
||||||
|
//计算交点
|
||||||
|
if (!TryGetIntersectPoint(a, b, line.a, line.b, out Vector3 IntersectPoint)) { return null; }
|
||||||
|
//计算顶点xy
|
||||||
|
Vector3 offset = new Vector3(smooth, smooth, 0) * 0.3f;
|
||||||
|
Vector3 position = IntersectPoint - border.MinPoint + offset;
|
||||||
|
int vertexX = Mathf.FloorToInt(position.x / smooth);
|
||||||
|
int vertexY = Mathf.FloorToInt(position.y / smooth);
|
||||||
|
//填充数据
|
||||||
|
DataPlateVertex vertex = grid.Get(vertexX, vertexY);
|
||||||
|
vertex.isValid = true;
|
||||||
|
vertex.position = IntersectPoint;
|
||||||
|
return vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SideVertex : IComparable<SideVertex> {
|
||||||
|
public float distance;
|
||||||
|
public DataPlateVertex vertex;
|
||||||
|
|
||||||
|
public int CompareTo(SideVertex other) {
|
||||||
|
return other.distance >= distance ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 转角法查询位置是否在板片内 </summary>
|
||||||
|
public static bool FindPlateInside(Vector3[] points, Vector3 position) {
|
||||||
|
double angles = 0;
|
||||||
|
for (int i = 0; i < points.Length; i++) {
|
||||||
|
Vector3 a = points.LoopIndex(i + 0) - position;
|
||||||
|
Vector3 b = points.LoopIndex(i + 1) - position;
|
||||||
|
float angle = Vector2.SignedAngle(a, b);
|
||||||
|
angles += angle;
|
||||||
|
}
|
||||||
|
int normal = (int)(angles * 1000);
|
||||||
|
return normal > 1000;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 计算AB与CD两条线段的交点.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">A点</param>
|
||||||
|
/// <param name="b">B点</param>
|
||||||
|
/// <param name="c">C点</param>
|
||||||
|
/// <param name="d">D点</param>
|
||||||
|
/// <param name="intersectPos">AB与CD的交点</param>
|
||||||
|
/// <returns>是否相交 true:相交 false:未相交</returns>
|
||||||
|
private bool TryGetIntersectPoint(Vector3 a, Vector3 b, Vector3 c, Vector3 d, out Vector3 intersectPos) {
|
||||||
|
intersectPos = Vector3.zero;
|
||||||
|
|
||||||
|
Vector3 ab = b - a;
|
||||||
|
Vector3 ca = a - c;
|
||||||
|
Vector3 cd = d - c;
|
||||||
|
|
||||||
|
Vector3 v1 = Vector3.Cross(ca, cd);
|
||||||
|
// 不共面
|
||||||
|
if (Mathf.Abs(Vector3.Dot(v1, ab)) > 1e-6) { return false; }
|
||||||
|
// 平行
|
||||||
|
if (Vector3.Cross(ab, cd).sqrMagnitude <= 1e-6) { return false; }
|
||||||
|
|
||||||
|
Vector3 ad = d - a;
|
||||||
|
Vector3 cb = b - c;
|
||||||
|
// 快速排斥
|
||||||
|
if (Mathf.Min(a.x, b.x) > Mathf.Max(c.x, d.x) || Mathf.Max(a.x, b.x) < Mathf.Min(c.x, d.x)
|
||||||
|
|| Mathf.Min(a.y, b.y) > Mathf.Max(c.y, d.y) || Mathf.Max(a.y, b.y) < Mathf.Min(c.y, d.y)
|
||||||
|
|| Mathf.Min(a.z, b.z) > Mathf.Max(c.z, d.z) || Mathf.Max(a.z, b.z) < Mathf.Min(c.z, d.z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跨立试验
|
||||||
|
if (Vector3.Dot(Vector3.Cross(-ca, ab), Vector3.Cross(ab, ad)) > 0
|
||||||
|
&& Vector3.Dot(Vector3.Cross(ca, cd), Vector3.Cross(cd, cb)) > 0) {
|
||||||
|
Vector3 v2 = Vector3.Cross(cd, ab);
|
||||||
|
float ratio = Vector3.Dot(v1, v2) / v2.sqrMagnitude;
|
||||||
|
intersectPos = a + ab * ratio;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e8b300a54238da848b5628cef749aeb2
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -11,6 +11,32 @@ public class UnitAlgorithmBezier : UnitAlgorithm<DataPlate> {
|
|||||||
/// <summary> 贝塞尔算法 </summary>
|
/// <summary> 贝塞尔算法 </summary>
|
||||||
public UnitAlgorithmBezier() { }
|
public UnitAlgorithmBezier() { }
|
||||||
|
|
||||||
|
public void Compute(DataPlate data) {
|
||||||
|
List<Vector3> points = new List<Vector3>();
|
||||||
|
for (int i = 0; i < data.plateSides.Count; i++) {
|
||||||
|
Compute(data.plateSides[i]);
|
||||||
|
//points.AddRange(data.plateSides[i].positions);
|
||||||
|
}
|
||||||
|
//去除重复边缘点
|
||||||
|
points = points.Distinct().ToList();
|
||||||
|
//data.edgePoints = points;
|
||||||
|
}
|
||||||
|
public void Compute(DataPlateSide data) {
|
||||||
|
DataBezier dataBezier = new DataBezier();
|
||||||
|
dataBezier.bezier = data.bezier;
|
||||||
|
//dataBezier.smooth = data.plate.smooth;
|
||||||
|
dataBezier.aPoint = data.aPoint.position;
|
||||||
|
dataBezier.bPoint = data.bPoint.position;
|
||||||
|
dataBezier.aBezier = data.aBezier;
|
||||||
|
dataBezier.bBezier = data.bBezier;
|
||||||
|
|
||||||
|
dataBezier.Compute();
|
||||||
|
|
||||||
|
//data.length = dataBezier.length;
|
||||||
|
//data.positions = dataBezier.positions.ToArray();
|
||||||
|
//data.lines = dataBezier.lines.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
public class DataBezier {
|
public class DataBezier {
|
||||||
//输入
|
//输入
|
||||||
public float smooth;
|
public float smooth;
|
||||||
@@ -22,97 +48,57 @@ public class UnitAlgorithmBezier : UnitAlgorithm<DataPlate> {
|
|||||||
//输出
|
//输出
|
||||||
public float length;
|
public float length;
|
||||||
public List<Vector3> positions = new List<Vector3>();
|
public List<Vector3> positions = new List<Vector3>();
|
||||||
public List<DataLine> lines = new List<DataLine>();
|
public List<DataPlateLine> lines = new List<DataPlateLine>();
|
||||||
}
|
/// <summary> 计算曲线细分点 </summary>
|
||||||
|
public void Compute() {
|
||||||
public void Compute(DataPlate data) {
|
//细分点
|
||||||
List<Vector3> points = new List<Vector3>();
|
if (bezier == Bezier.一阶) { positions = new List<Vector3> { aPoint, bPoint }; }
|
||||||
for (int i = 0; i < data.sides.Count; i++) {
|
if (bezier == Bezier.二阶) { positions = Compute(aPoint, aBezier, bPoint); }
|
||||||
Compute(data.sides[i]);
|
if (bezier == Bezier.三阶) { positions = Compute(aPoint, aBezier, bBezier, bPoint); }
|
||||||
points.AddRange(data.sides[i].positions);
|
//线段
|
||||||
|
lines = new List<DataPlateLine>();
|
||||||
|
for (int i = 0; i < positions.Count - 1; i++) {
|
||||||
|
DataPlateLine line = new DataPlateLine();
|
||||||
|
line.a = positions.LoopIndex(i + 0);
|
||||||
|
line.b = positions.LoopIndex(i + 1);
|
||||||
|
line.origin = length;
|
||||||
|
lines.Add(line);
|
||||||
|
length += line.Distance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//去除重复边缘点
|
/// <summary> 二阶贝塞尔线段 </summary>
|
||||||
points = points.Distinct().ToList();
|
private List<Vector3> Compute(Vector3 a, Vector3 b, Vector3 c) {
|
||||||
data.edgePoints = points;
|
List<Vector3> points = new List<Vector3>();
|
||||||
}
|
//方向,距离
|
||||||
public void Compute(DataSide data) {
|
float distance = Vector2.Distance(c, a);
|
||||||
DataBezier dataBezier = new DataBezier();
|
//求余,得商数
|
||||||
dataBezier.bezier = data.bezier;
|
int quotient = Quotient(distance, smooth);
|
||||||
dataBezier.smooth = data.plate.smooth;
|
//贝塞尔曲线点
|
||||||
dataBezier.aPoint = data.aPoint.position;
|
for (int i = 0; i < quotient; i++) {
|
||||||
dataBezier.bPoint = data.bPoint.position;
|
float t = i * (distance / quotient) / distance;
|
||||||
dataBezier.aBezier = data.aBezier;
|
Vector2 position = ComputeBezier(a, b, c, t);
|
||||||
dataBezier.bBezier = data.bBezier;
|
points.Add(position);
|
||||||
|
}
|
||||||
Compute(dataBezier);
|
points.Add(c);
|
||||||
|
return points;
|
||||||
data.length = dataBezier.length;
|
|
||||||
data.positions = dataBezier.positions.ToArray();
|
|
||||||
data.lines = dataBezier.lines.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> 计算曲线细分点 </summary>
|
|
||||||
private void Compute(DataBezier data) {
|
|
||||||
//细分点
|
|
||||||
if (data.bezier == Bezier.一阶) {
|
|
||||||
data.positions = Compute(data.aPoint, data.bPoint);
|
|
||||||
}
|
}
|
||||||
if (data.bezier == Bezier.二阶) {
|
/// <summary> 三阶贝塞尔线段 </summary>
|
||||||
data.positions = Compute(data.aPoint, data.aBezier, data.bPoint, data.smooth);
|
private List<Vector3> Compute(Vector3 a, Vector3 b, Vector3 c, Vector3 d) {
|
||||||
|
List<Vector3> points = new List<Vector3>();
|
||||||
|
//方向,距离
|
||||||
|
Vector2 direction = (d - a).normalized;
|
||||||
|
float distance = Vector2.Distance(d, a);
|
||||||
|
//求余,得商数
|
||||||
|
int quotient = Quotient(distance, smooth);
|
||||||
|
//贝塞尔曲线点
|
||||||
|
for (int i = 0; i < quotient; i++) {
|
||||||
|
float t = i * (distance / quotient) / distance;
|
||||||
|
Vector2 position = ComputeBezier(a, b, c, d, t);
|
||||||
|
points.Add(position);
|
||||||
|
}
|
||||||
|
points.Add(d);
|
||||||
|
return points;
|
||||||
}
|
}
|
||||||
if (data.bezier == Bezier.三阶) {
|
|
||||||
data.positions = Compute(data.aPoint, data.aBezier, data.bBezier, data.bPoint, data.smooth);
|
|
||||||
}
|
|
||||||
//线段
|
|
||||||
data.lines = new List<DataLine>();
|
|
||||||
float origin = 0;
|
|
||||||
for (int i = 0; i < data.positions.Count - 1; i++) {
|
|
||||||
DataLine line = new DataLine();
|
|
||||||
line.a = data.positions.LoopIndex(i + 0);
|
|
||||||
line.b = data.positions.LoopIndex(i + 1);
|
|
||||||
line.origin = origin;
|
|
||||||
data.lines.Add(line);
|
|
||||||
data.length += line.Distance;
|
|
||||||
origin += line.Distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// <summary> 二阶贝塞尔线段 </summary>
|
|
||||||
private List<Vector3> Compute(Vector3 aPoint, Vector3 bPoint) {
|
|
||||||
return new List<Vector3> { aPoint, bPoint };
|
|
||||||
}
|
|
||||||
/// <summary> 二阶贝塞尔线段 </summary>
|
|
||||||
private List<Vector3> Compute(Vector3 a, Vector3 b, Vector3 c, float smooth) {
|
|
||||||
List<Vector3> points = new List<Vector3>();
|
|
||||||
//方向,距离
|
|
||||||
Vector2 direction = (c - a).normalized;
|
|
||||||
float distance = Vector2.Distance(c, a);
|
|
||||||
//求余,得商数
|
|
||||||
int quotient = Quotient(distance, smooth);
|
|
||||||
//贝塞尔曲线点
|
|
||||||
for (int i = 0; i < quotient; i++) {
|
|
||||||
float t = i * (distance / quotient) / distance;
|
|
||||||
Vector2 position = ComputeBezier(a, b, c, t);
|
|
||||||
points.Add(position);
|
|
||||||
}
|
|
||||||
points.Add(c);
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
/// <summary> 三阶贝塞尔线段 </summary>
|
|
||||||
private List<Vector3> Compute(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float smooth) {
|
|
||||||
List<Vector3> points = new List<Vector3>();
|
|
||||||
//方向,距离
|
|
||||||
Vector2 direction = (d - a).normalized;
|
|
||||||
float distance = Vector2.Distance(d, a);
|
|
||||||
//求余,得商数
|
|
||||||
int quotient = Quotient(distance, smooth);
|
|
||||||
//贝塞尔曲线点
|
|
||||||
for (int i = 0; i < quotient; i++) {
|
|
||||||
float t = i * (distance / quotient) / distance;
|
|
||||||
Vector2 position = ComputeBezier(a, b, c, d, t);
|
|
||||||
points.Add(position);
|
|
||||||
}
|
|
||||||
points.Add(d);
|
|
||||||
return points;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> 商数 </summary>
|
/// <summary> 商数 </summary>
|
||||||
|
|||||||
@@ -1,28 +1,35 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 散点边界算法
|
/// 散点边界算法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UnitAlgorithmBorder : UnitAlgorithm<DataPlate> {
|
public class UnitAlgorithmBorder : UnitAlgorithm<DataPlateBaking> {
|
||||||
/// <summary> 散点边界算法 </summary>
|
/// <summary> 散点边界算法 </summary>
|
||||||
public UnitAlgorithmBorder() { }
|
public UnitAlgorithmBorder() { }
|
||||||
|
|
||||||
public void Compute(DataPlate plate) {
|
public void Compute(DataPlateBaking plateBaking) {
|
||||||
List<Vector3> edgePoints = new List<Vector3>(plate.edgePoints);
|
//List<DataPlateSide> plateSides = plateBaking.plate.plateSides;
|
||||||
plate.border = Border(edgePoints);
|
|
||||||
|
//List<Vector3> points = new List<Vector3>();
|
||||||
|
//for (int i = 0; i < plateSides.Count; i++) {
|
||||||
|
// points.AddRange(plateSides[i].dataBaking.positions);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//plateBaking.border = Border(points.Distinct().ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DataBorder Border(List<Vector3> points) {
|
public static DataBorder Border(Vector3[] points) {
|
||||||
float minX = 0; float minY = 0;
|
float minX = 0; float minY = 0;
|
||||||
float maxX = 0; float maxY = 0;
|
float maxX = 0; float maxY = 0;
|
||||||
for (int i = 0; i < points.Count; i++) {
|
for (int i = 0; i < points.Length; i++) {
|
||||||
if (points[i].x < minX) { minX = points[i].x; }
|
if (points[i].x < minX) { minX = points[i].x; }
|
||||||
if (points[i].x > maxX) { maxX = points[i].x; }
|
if (points[i].x > maxX) { maxX = points[i].x; }
|
||||||
if (points[i].y < minY) { minY = points[i].y; }
|
if (points[i].y < minY) { minY = points[i].y; }
|
||||||
if (points[i].y > maxY) { maxY = points[i].y; }
|
if (points[i].y > maxY) { maxY = points[i].y; }
|
||||||
}
|
}
|
||||||
return new DataBorder(minX, maxX, minY, maxY);
|
return new DataBorder(minX, maxX, minY, maxY, points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 多边形耳切法
|
/// 多边形耳切法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UnitAlgorithmEarCutting : UnitAlgorithm<DataPlate> {
|
public class UnitAlgorithmEarCutting : UnitAlgorithm<DataPlateDesign> {
|
||||||
/// <summary> 多边形耳切法 </summary>
|
/// <summary> 多边形耳切法 </summary>
|
||||||
public UnitAlgorithmEarCutting() { }
|
public UnitAlgorithmEarCutting() { }
|
||||||
|
|
||||||
@@ -17,27 +17,27 @@ public class UnitAlgorithmEarCutting : UnitAlgorithm<DataPlate> {
|
|||||||
public Vector3 cPoint;//+1
|
public Vector3 cPoint;//+1
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Compute(DataPlate data) {
|
public void Compute(DataPlateDesign plateDesign) {
|
||||||
List<Vector3> points = new List<Vector3>(data.edgePoints);
|
List<Vector3> points = new List<Vector3>(plateDesign.points);
|
||||||
//判断散列点排序方向
|
//判断散列点排序方向
|
||||||
Vector3[] allArray = points.ToArray();
|
Vector3[] allPoints = plateDesign.points;
|
||||||
bool isClockWise = IsClockWise(allArray);
|
bool isClockWise = IsClockWise(allPoints);
|
||||||
//耳切法生成三角形
|
//耳切法生成三角形
|
||||||
List<DataTriangle> triangles = new List<DataTriangle>();
|
List<DataTriangle> triangles = new List<DataTriangle>();
|
||||||
ComputeAuriculare(triangles, points, allArray, isClockWise);
|
ComputeAuriculare(triangles, points, allPoints, isClockWise);
|
||||||
data.triangles = triangles;
|
plateDesign.triangles = triangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 函数
|
#region 函数
|
||||||
/// <summary> 循环计算有效的耳点 </summary>
|
/// <summary> 循环计算有效的耳点 </summary>
|
||||||
public static void ComputeAuriculare(List<DataTriangle> triangles, List<Vector3> edgePoints, Vector3[] allArray, bool isClockWise) {
|
public static void ComputeAuriculare(List<DataTriangle> triangles, List<Vector3> edgePoints, Vector3[] allPoints, bool isClockWise) {
|
||||||
List<DataTriangle> temp = ComputeAuriculare(edgePoints, allArray, isClockWise);
|
List<DataTriangle> temp = ComputeAuriculare(edgePoints, allPoints, isClockWise);
|
||||||
if (temp.Count == 0) { return; }
|
if (temp.Count == 0) { return; }
|
||||||
triangles.AddRange(temp);
|
triangles.AddRange(temp);
|
||||||
ComputeAuriculare(triangles, edgePoints, allArray, isClockWise);
|
ComputeAuriculare(triangles, edgePoints, allPoints, isClockWise);
|
||||||
}
|
}
|
||||||
/// <summary> 计算一个有效的耳点 </summary>
|
/// <summary> 计算一个有效的耳点 </summary>
|
||||||
public static List<DataTriangle> ComputeAuriculare(List<Vector3> edgePoints, Vector3[] allArray, bool isClockWise) {
|
public static List<DataTriangle> ComputeAuriculare(List<Vector3> edgePoints, Vector3[] allPoints, bool isClockWise) {
|
||||||
Vector3[] array = edgePoints.ToArray();
|
Vector3[] array = edgePoints.ToArray();
|
||||||
List<DataTriangle> polygons = new List<DataTriangle>();
|
List<DataTriangle> polygons = new List<DataTriangle>();
|
||||||
for (int i = 0; i < array.Length; i++) {
|
for (int i = 0; i < array.Length; i++) {
|
||||||
@@ -45,7 +45,7 @@ public class UnitAlgorithmEarCutting : UnitAlgorithm<DataPlate> {
|
|||||||
// 等于180,大于180,不可能为耳点
|
// 等于180,大于180,不可能为耳点
|
||||||
if (!GetAngleType(auriculare, isClockWise)) { continue; }
|
if (!GetAngleType(auriculare, isClockWise)) { continue; }
|
||||||
// 包含其他点,不可能为耳点
|
// 包含其他点,不可能为耳点
|
||||||
if (IsInsideTriangle(auriculare, allArray)) { continue; }
|
if (IsInsideTriangle(auriculare, allPoints)) { continue; }
|
||||||
// 包含其他耳点,不可能成为耳点
|
// 包含其他耳点,不可能成为耳点
|
||||||
if (!IsInsideAuriculare(auriculare, edgePoints)) { continue; }
|
if (!IsInsideAuriculare(auriculare, edgePoints)) { continue; }
|
||||||
edgePoints.Remove(auriculare.aPoint);
|
edgePoints.Remove(auriculare.aPoint);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class UnitAlgorithmEdgePoint : UnitAlgorithm<DataPolygon> {
|
|||||||
|
|
||||||
#region 函数
|
#region 函数
|
||||||
/// <summary> 二阶贝塞尔线段 </summary>
|
/// <summary> 二阶贝塞尔线段 </summary>
|
||||||
public List<Vector3> CreateLine(DataPoint aPoint, DataPoint bPoint, Vector3 b, float smooth) {
|
public List<Vector3> CreateLine(DataPlatePoint aPoint, DataPlatePoint bPoint, Vector3 b, float smooth) {
|
||||||
List<Vector3> points = new List<Vector3>();
|
List<Vector3> points = new List<Vector3>();
|
||||||
//方向,距离
|
//方向,距离
|
||||||
Vector2 direction = (bPoint.position - aPoint.position).normalized;
|
Vector2 direction = (bPoint.position - aPoint.position).normalized;
|
||||||
@@ -53,7 +53,7 @@ public class UnitAlgorithmEdgePoint : UnitAlgorithm<DataPolygon> {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
/// <summary> 三阶贝塞尔线段 </summary>
|
/// <summary> 三阶贝塞尔线段 </summary>
|
||||||
public List<Vector3> CreateLine(DataPoint aPoint, DataPoint bPoint, float smooth) {
|
public List<Vector3> CreateLine(DataPlatePoint aPoint, DataPlatePoint bPoint, float smooth) {
|
||||||
List<Vector3> points = new List<Vector3>();
|
List<Vector3> points = new List<Vector3>();
|
||||||
//方向,距离
|
//方向,距离
|
||||||
Vector2 direction = (bPoint.position - aPoint.position).normalized;
|
Vector2 direction = (bPoint.position - aPoint.position).normalized;
|
||||||
|
|||||||
@@ -0,0 +1,239 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Unity.Burst;
|
||||||
|
using Unity.Collections;
|
||||||
|
using Unity.Jobs;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 贝塞尔算法 边缘细分 Jobs
|
||||||
|
/// </summary>
|
||||||
|
public class UnitAlgorithmJobsSideSubdivision : UnitAlgorithm<DataPlateDesign>, UnitAlgorithm<DataPlateBaking> {
|
||||||
|
|
||||||
|
/// <summary> 贝塞尔算法 边缘细分 Jobs </summary>
|
||||||
|
public UnitAlgorithmJobsSideSubdivision() { }
|
||||||
|
|
||||||
|
public void Compute(DataPlateDesign plateDesign) {
|
||||||
|
int count = plateDesign.plate.plateSides.Count;
|
||||||
|
List<DataPlateSide> plateSides = plateDesign.plate.plateSides;
|
||||||
|
NativeArray<JobSubdivision> jobSubdivisions = new NativeArray<JobSubdivision>(count, Allocator.TempJob);
|
||||||
|
NativeArray<JobHandle> jobHandles = new NativeArray<JobHandle>(count, Allocator.TempJob);
|
||||||
|
//创建作业任务
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
jobSubdivisions[i] = ToJob(plateSides[i]);
|
||||||
|
jobHandles[i] = jobSubdivisions[i].Schedule();
|
||||||
|
}
|
||||||
|
//执行作业
|
||||||
|
JobHandle.CompleteAll(jobHandles);
|
||||||
|
//作业结果转换
|
||||||
|
List<Vector3> points = new List<Vector3>();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
DataPlateSideDesign design = plateSides[i].dataDesign;
|
||||||
|
JobToDesign(design, jobSubdivisions[i]);
|
||||||
|
points.AddRange(design.positions);
|
||||||
|
}
|
||||||
|
plateDesign.points = points.Distinct().ToArray();
|
||||||
|
//释放作业
|
||||||
|
jobSubdivisions.Dispose();
|
||||||
|
jobHandles.Dispose();
|
||||||
|
}
|
||||||
|
public void Compute(DataPlateBaking plateBaking) {
|
||||||
|
//int count = plateBaking.plate.plateSides.Count;
|
||||||
|
//List<DataPlateSide> plateSides = plateBaking.plate.plateSides;
|
||||||
|
//NativeArray<JobSubdivision> jobSubdivisions = new NativeArray<JobSubdivision>(count, Allocator.Temp);
|
||||||
|
//NativeArray<JobHandle> jobHandles = new NativeArray<JobHandle>(count, Allocator.Temp);
|
||||||
|
////创建作业任务
|
||||||
|
//for (int i = 0; i < count; i++) {
|
||||||
|
// jobSubdivisions[i] = ToJob(plateSides[i]);
|
||||||
|
// jobHandles[i] = jobSubdivisions[i].Schedule();
|
||||||
|
//}
|
||||||
|
////执行作业
|
||||||
|
//JobHandle.CompleteAll(jobHandles);
|
||||||
|
////作业结果转换
|
||||||
|
////List<Vector3> points = new List<Vector3>();
|
||||||
|
//for (int i = 0; i < count; i++) {
|
||||||
|
// DataPlateSideBaking sideBaking = plateSides[i].dataBaking;
|
||||||
|
// JobToBaking(sideBaking, jobSubdivisions[i]);
|
||||||
|
// //points.AddRange(sideBaking.positions);
|
||||||
|
//}
|
||||||
|
////plateBaking.points = points.Distinct().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 转换作业系统数据 </summary>
|
||||||
|
public JobSubdivision ToJob(DataPlateSide side) {
|
||||||
|
JobSubdivision jobSubdivision = new JobSubdivision();
|
||||||
|
jobSubdivision.bezier = side.bezier;
|
||||||
|
jobSubdivision.aPoint = side.aPoint.position;
|
||||||
|
jobSubdivision.bPoint = side.bPoint.position;
|
||||||
|
jobSubdivision.aBezier = side.aBezier;
|
||||||
|
jobSubdivision.bBezier = side.bBezier;
|
||||||
|
//距离
|
||||||
|
float distance = Vector2.Distance(jobSubdivision.aPoint, jobSubdivision.bPoint);
|
||||||
|
jobSubdivision.distance = distance;
|
||||||
|
//求余,得商数
|
||||||
|
jobSubdivision.quotient = side.bezier == Bezier.一阶 ? 2 : 10;
|
||||||
|
|
||||||
|
jobSubdivision.length = new NativeArray<float>(1, Allocator.TempJob);
|
||||||
|
jobSubdivision.positions = new NativeArray<Vector3>(jobSubdivision.quotient, Allocator.TempJob);
|
||||||
|
jobSubdivision.lines = new NativeArray<JobDataLine>(jobSubdivision.quotient - 1, Allocator.TempJob);
|
||||||
|
|
||||||
|
return jobSubdivision;
|
||||||
|
}
|
||||||
|
/// <summary> 作业系统数据转换设计数据 </summary>
|
||||||
|
public void JobToDesign(DataPlateSideDesign design, JobSubdivision job) {
|
||||||
|
design.length = job.length[0];
|
||||||
|
design.positions = job.positions.ToArray();
|
||||||
|
DataPlateLine[] lines = new DataPlateLine[job.lines.Length];
|
||||||
|
for (int i = 0; i < job.lines.Length; i++) {
|
||||||
|
lines[i] = ToData(job.lines[i]);
|
||||||
|
}
|
||||||
|
design.lines = lines;
|
||||||
|
job.length.Dispose();
|
||||||
|
job.positions.Dispose();
|
||||||
|
job.lines.Dispose();
|
||||||
|
}
|
||||||
|
/// <summary> 作业系统数据转换烘焙数据 </summary>
|
||||||
|
public void JobToBaking(DataPlateSideBaking baking, JobSubdivision job) {
|
||||||
|
baking.length = job.length[0];
|
||||||
|
baking.positions = job.positions.ToArray();
|
||||||
|
DataPlateLine[] lines = new DataPlateLine[job.lines.Length];
|
||||||
|
for (int i = 0; i < job.lines.Length; i++) {
|
||||||
|
lines[i] = ToData(job.lines[i]);
|
||||||
|
}
|
||||||
|
baking.lines = lines;
|
||||||
|
job.length.Dispose();
|
||||||
|
job.positions.Dispose();
|
||||||
|
job.lines.Dispose();
|
||||||
|
}
|
||||||
|
/// <summary> 转换托管数据 </summary>
|
||||||
|
public DataPlateLine ToData(JobDataLine jobDataLine) {
|
||||||
|
DataPlateLine line = new DataPlateLine();
|
||||||
|
line.a = jobDataLine.a;
|
||||||
|
line.b = jobDataLine.b;
|
||||||
|
line.origin = jobDataLine.origin;
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 作业系统数据 </summary>
|
||||||
|
public struct JobDataLine {
|
||||||
|
/// <summary> 线段起点a </summary>
|
||||||
|
public Vector3 a;
|
||||||
|
/// <summary> 线段终点b </summary>
|
||||||
|
public Vector3 b;
|
||||||
|
/// <summary> 原始距离 </summary>
|
||||||
|
public float origin;
|
||||||
|
}
|
||||||
|
[BurstCompile]
|
||||||
|
public struct JobSubdivision : IJob {
|
||||||
|
|
||||||
|
#region 输入
|
||||||
|
/// <summary> 贝塞尔类型 </summary>
|
||||||
|
public Bezier bezier;
|
||||||
|
/// <summary> a点 </summary>
|
||||||
|
public Vector3 aPoint;
|
||||||
|
/// <summary> b点 </summary>
|
||||||
|
public Vector3 bPoint;
|
||||||
|
/// <summary> a点贝塞尔点 </summary>
|
||||||
|
public Vector3 aBezier;
|
||||||
|
/// <summary> b点贝塞尔点 </summary>
|
||||||
|
public Vector3 bBezier;
|
||||||
|
/// <summary> a-b距离 </summary>
|
||||||
|
public float distance;
|
||||||
|
/// <summary> 细分数 </summary>
|
||||||
|
public int quotient;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 输出
|
||||||
|
/// <summary> 总长度 </summary>
|
||||||
|
public NativeArray<float> length;
|
||||||
|
/// <summary> 点 </summary>
|
||||||
|
public NativeArray<Vector3> positions;
|
||||||
|
/// <summary> 线 </summary>
|
||||||
|
public NativeArray<JobDataLine> lines;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void Execute() {
|
||||||
|
//细分点
|
||||||
|
if (bezier == Bezier.一阶) { ComputeBezierA(); }
|
||||||
|
if (bezier == Bezier.二阶) { ComputeBezierB(); }
|
||||||
|
if (bezier == Bezier.三阶) { ComputeBezierC(); }
|
||||||
|
//线段
|
||||||
|
for (int i = 0; i < quotient - 1; i++) {
|
||||||
|
JobDataLine line = new JobDataLine();
|
||||||
|
line.a = positions[i];
|
||||||
|
line.b = positions[i + 1];
|
||||||
|
line.origin = length[0];
|
||||||
|
lines[i] = line;
|
||||||
|
length[0] += Vector3.Distance(line.a, line.b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void ComputeBezierA() {
|
||||||
|
positions[0] = aPoint;
|
||||||
|
positions[1] = bPoint;
|
||||||
|
}
|
||||||
|
public void ComputeBezierB() {
|
||||||
|
for (int i = 0; i < quotient; i++) {
|
||||||
|
float t = i * (distance / quotient) / distance;
|
||||||
|
Vector2 position = ComputeBezier(aPoint, aBezier, bPoint, t);
|
||||||
|
positions[i] = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void ComputeBezierC() {
|
||||||
|
for (int i = 0; i < quotient; i++) {
|
||||||
|
float t = i * (distance / quotient) / distance;
|
||||||
|
Vector2 position = ComputeBezier(aPoint, aBezier, bBezier, bPoint, t);
|
||||||
|
positions[i] = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> 商数 </summary>
|
||||||
|
public static int Quotient(float distance, float smooth) {
|
||||||
|
int a = (int)(distance * 1000);
|
||||||
|
int b = (int)(smooth * 1000);
|
||||||
|
return Math.DivRem(a, b, out int remainder);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 一阶贝塞尔算法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">起点</param>
|
||||||
|
/// <param name="b">终点</param>
|
||||||
|
/// <param name="t">进度</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Vector3 ComputeBezier(Vector3 a, Vector3 b, float t) {
|
||||||
|
return a + (b - a) * t;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 二阶贝塞尔算法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">起点</param>
|
||||||
|
/// <param name="b">贝塞尔点</param>
|
||||||
|
/// <param name="c">终点</param>
|
||||||
|
/// <param name="t">进度</param>
|
||||||
|
/// <returns>当前进度的曲线点</returns>
|
||||||
|
public static Vector3 ComputeBezier(Vector3 a, Vector3 b, Vector3 c, float t) {
|
||||||
|
Vector3 aa = a + (b - a) * t;
|
||||||
|
Vector3 bb = b + (c - b) * t;
|
||||||
|
return aa + (bb - aa) * t;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 三阶贝塞尔算法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">起点</param>
|
||||||
|
/// <param name="b">起点的贝塞尔点</param>
|
||||||
|
/// <param name="c">终点的贝塞尔点</param>
|
||||||
|
/// <param name="d">终点</param>
|
||||||
|
/// <param name="t">进度</param>
|
||||||
|
/// <returns>当前进度的曲线点</returns>
|
||||||
|
public static Vector3 ComputeBezier(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float t) {
|
||||||
|
Vector3 aa = a + (b - a) * t;
|
||||||
|
Vector3 bb = b + (c - b) * t;
|
||||||
|
Vector3 cc = c + (d - c) * t;
|
||||||
|
|
||||||
|
Vector3 aaa = aa + (bb - aa) * t;
|
||||||
|
Vector3 bbb = bb + (cc - bb) * t;
|
||||||
|
return aaa + (bbb - aaa) * t;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 39a35ef3408d163469eb7c66d1df96ac
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -10,12 +10,12 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 三角形合并网格
|
/// 三角形合并网格
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlate> {
|
public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlateDesign>, UnitAlgorithm<DataPlateBaking> {
|
||||||
/// <summary> 三角形合并网格 </summary>
|
/// <summary> 三角形合并网格 </summary>
|
||||||
public UnitAlgorithmMergeTriangle() { }
|
public UnitAlgorithmMergeTriangle() { }
|
||||||
|
|
||||||
public void Compute(DataPlate data) {
|
public void Compute(DataPlateDesign plateDesign) {
|
||||||
List<DataTriangle> polygons = data.triangles;
|
List<DataTriangle> polygons = plateDesign.triangles;
|
||||||
//三角形合并
|
//三角形合并
|
||||||
List<Vector3> vertices = vertices = MergeVertices(polygons);
|
List<Vector3> vertices = vertices = MergeVertices(polygons);
|
||||||
List<int> triangles = JobFindTriangleIndex(polygons, vertices);
|
List<int> triangles = JobFindTriangleIndex(polygons, vertices);
|
||||||
@@ -23,12 +23,28 @@ public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlate> {
|
|||||||
List<Vector2> uv = new List<Vector2>();
|
List<Vector2> uv = new List<Vector2>();
|
||||||
for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
|
for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
|
||||||
//附加数据
|
//附加数据
|
||||||
data.designMesh = new Mesh();
|
plateDesign.mesh = new Mesh();
|
||||||
data.designMesh.vertices = vertices.ToArray();
|
plateDesign.mesh.vertices = vertices.ToArray();
|
||||||
data.designMesh.uv = uv.ToArray();
|
plateDesign.mesh.uv = uv.ToArray();
|
||||||
data.designMesh.triangles = triangles.ToArray();
|
plateDesign.mesh.triangles = triangles.ToArray();
|
||||||
data.designMesh.RecalculateBounds();
|
plateDesign.mesh.RecalculateBounds();
|
||||||
data.designMesh.RecalculateNormals();
|
plateDesign.mesh.RecalculateNormals();
|
||||||
|
}
|
||||||
|
public void Compute(DataPlateBaking plateBaking) {
|
||||||
|
//List<DataTriangle> polygons = plateBaking.triangles;
|
||||||
|
////三角形合并
|
||||||
|
//List<Vector3> vertices = vertices = MergeVertices(polygons);
|
||||||
|
//List<int> triangles = JobFindTriangleIndex(polygons, vertices);
|
||||||
|
////展开uv (顶点去掉z坐标就是未缩放的平面UV)
|
||||||
|
//List<Vector2> uv = new List<Vector2>();
|
||||||
|
//for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
|
||||||
|
////附加数据
|
||||||
|
//plateBaking.mesh = new Mesh();
|
||||||
|
//plateBaking.mesh.vertices = vertices.ToArray();
|
||||||
|
//plateBaking.mesh.uv = uv.ToArray();
|
||||||
|
//plateBaking.mesh.triangles = triangles.ToArray();
|
||||||
|
//plateBaking.mesh.RecalculateBounds();
|
||||||
|
//plateBaking.mesh.RecalculateNormals();
|
||||||
}
|
}
|
||||||
/// <summary> 合并顶点 </summary>
|
/// <summary> 合并顶点 </summary>
|
||||||
private List<Vector3> MergeVertices(List<DataTriangle> polygons) {
|
private List<Vector3> MergeVertices(List<DataTriangle> polygons) {
|
||||||
@@ -54,7 +70,7 @@ public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlate> {
|
|||||||
triangleIndex.triangles = trianglesArray;
|
triangleIndex.triangles = trianglesArray;
|
||||||
|
|
||||||
JobHandle dependency = new JobHandle();
|
JobHandle dependency = new JobHandle();
|
||||||
JobHandle handle = triangleIndex.ScheduleParallel(polygons.Count, 2048, dependency);
|
JobHandle handle = triangleIndex.ScheduleParallel(polygons.Count, 32, dependency);
|
||||||
handle.Complete();
|
handle.Complete();
|
||||||
|
|
||||||
List<int> triangles = new List<int>();
|
List<int> triangles = new List<int>();
|
||||||
|
|||||||
@@ -5,55 +5,58 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 菱形绘制三角形算法
|
/// 菱形绘制三角形算法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UnitAlgorithmRhombus : UnitAlgorithm<DataPlate> {
|
public class UnitAlgorithmRhombus : UnitAlgorithm<DataPlateBaking> {
|
||||||
|
|
||||||
public void Compute(DataPlate data) {
|
public void Compute(DataPlateBaking plateBaking) {
|
||||||
List<DataTriangle> triangles = new List<DataTriangle>();
|
List<DataTriangle> triangles = new List<DataTriangle>();
|
||||||
data.vertexGrid.Loop((x, y) => {
|
List<DataPlateVertex> vertexs = new List<DataPlateVertex>();
|
||||||
DataVertex vertex = data.vertexGrid.Get(x, y);
|
//plateBaking.grid.Loop((x, y) => {
|
||||||
if (!vertex.isValid) { return; }
|
// DataPlateVertex vertex = plateBaking.grid.Get(x, y);
|
||||||
|
// if (!vertex.isValid) { return; }
|
||||||
|
|
||||||
TryGet(data.vertexGrid, x, y + 1, ref vertex.above);
|
// TryGet(plateBaking.grid, x, y + 1, ref vertex.above);
|
||||||
TryGet(data.vertexGrid, x, y - 1, ref vertex.below);
|
// TryGet(plateBaking.grid, x, y - 1, ref vertex.below);
|
||||||
TryGet(data.vertexGrid, x - 1, y, ref vertex.left);
|
// TryGet(plateBaking.grid, x - 1, y, ref vertex.left);
|
||||||
TryGet(data.vertexGrid, x + 1, y, ref vertex.right);
|
// TryGet(plateBaking.grid, x + 1, y, ref vertex.right);
|
||||||
|
|
||||||
TryGet(data.vertexGrid, x - 1, y + 1, ref vertex.leftAbove);
|
// TryGet(plateBaking.grid, x - 1, y + 1, ref vertex.leftAbove);
|
||||||
TryGet(data.vertexGrid, x - 1, y - 1, ref vertex.leftBelow);
|
// TryGet(plateBaking.grid, x - 1, y - 1, ref vertex.leftBelow);
|
||||||
TryGet(data.vertexGrid, x + 1, y + 1, ref vertex.rightAbove);
|
// TryGet(plateBaking.grid, x + 1, y + 1, ref vertex.rightAbove);
|
||||||
TryGet(data.vertexGrid, x + 1, y - 1, ref vertex.rightBelow);
|
// TryGet(plateBaking.grid, x + 1, y - 1, ref vertex.rightBelow);
|
||||||
//默认绘制左上角
|
// //默认绘制左上角
|
||||||
if (vertex.above != null && vertex.left != null) {
|
// if (vertex.above != null && vertex.left != null) {
|
||||||
triangles.Add(CreateDataTriangle(vertex, vertex.left, vertex.above));
|
// triangles.Add(CreateDataTriangle(vertex, vertex.left, vertex.above));
|
||||||
}
|
// }
|
||||||
//默认绘制右下角
|
// //默认绘制右下角
|
||||||
if (vertex.below != null && vertex.right != null) {
|
// if (vertex.below != null && vertex.right != null) {
|
||||||
triangles.Add(CreateDataTriangle(vertex, vertex.right, vertex.below));
|
// triangles.Add(CreateDataTriangle(vertex, vertex.right, vertex.below));
|
||||||
}
|
// }
|
||||||
//如果右上角点不存在,则尝试绘制右上角
|
// //如果右上角点不存在,则尝试绘制右上角
|
||||||
if (vertex.rightAbove == null && vertex.above != null && vertex.right != null) {
|
// if (vertex.rightAbove == null && vertex.above != null && vertex.right != null) {
|
||||||
triangles.Add(CreateDataTriangle(vertex, vertex.above, vertex.right));
|
// triangles.Add(CreateDataTriangle(vertex, vertex.above, vertex.right));
|
||||||
}
|
// }
|
||||||
//如果左下角点不存在,则尝试绘制左下角
|
// //如果左下角点不存在,则尝试绘制左下角
|
||||||
if (vertex.leftBelow == null && vertex.below != null && vertex.left != null) {
|
// if (vertex.leftBelow == null && vertex.below != null && vertex.left != null) {
|
||||||
triangles.Add(CreateDataTriangle(vertex, vertex.below, vertex.left));
|
// triangles.Add(CreateDataTriangle(vertex, vertex.below, vertex.left));
|
||||||
}
|
// }
|
||||||
});
|
// vertexs.Add(vertex);
|
||||||
data.triangles = triangles;
|
//});
|
||||||
|
//plateBaking.triangles = triangles;
|
||||||
|
//plateBaking.vertexs = vertexs.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> 校验性获取网格上的点 </summary>
|
/// <summary> 校验性获取网格上的点 </summary>
|
||||||
private void TryGet(GridTool<DataVertex> grid, int x, int y, ref DataVertex vertex) {
|
private void TryGet(GridTool<DataPlateVertex> grid, int x, int y, ref DataPlateVertex vertex) {
|
||||||
vertex = null;
|
vertex = null;
|
||||||
if (!grid.TryGet(x, y, out DataVertex data)) { return; }
|
if (!grid.TryGet(x, y, out DataPlateVertex data)) { return; }
|
||||||
if (data.isValid) { vertex = data; }
|
if (data.isValid) { vertex = data; }
|
||||||
}
|
}
|
||||||
/// <summary> 创建三角形 </summary>
|
/// <summary> 创建三角形 </summary>
|
||||||
private DataTriangle CreateDataTriangle(DataVertex a, DataVertex b, DataVertex c) {
|
private DataTriangle CreateDataTriangle(DataPlateVertex a, DataPlateVertex b, DataPlateVertex c) {
|
||||||
DataTriangle triangle = new DataTriangle();
|
DataTriangle triangle = new DataTriangle();
|
||||||
triangle.b = a.design;
|
triangle.b = a.position;
|
||||||
triangle.c = b.design;
|
triangle.c = b.position;
|
||||||
triangle.a = c.design;
|
triangle.a = c.position;
|
||||||
return triangle;
|
return triangle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 烘焙的缝合线
|
||||||
|
/// </summary>
|
||||||
|
public class UnitAlgorithmSutureBaking : UnitAlgorithm<DataSutureSide> {
|
||||||
|
/// <summary> 烘焙的缝合线 </summary>
|
||||||
|
public UnitAlgorithmSutureBaking() { }
|
||||||
|
|
||||||
|
public void Compute(DataSutureSide sutureSide) {
|
||||||
|
AllVertexs(sutureSide);
|
||||||
|
//缝合范围内的顶点
|
||||||
|
SetVertex(sutureSide);
|
||||||
|
//顶点转换位置
|
||||||
|
SetPositions(sutureSide);
|
||||||
|
}
|
||||||
|
/// <summary> 顶点距离数据 </summary>
|
||||||
|
private List<DataSutureSideVertex> GetVertex(DataPlateVertex[] vertexsArray, bool isReversal) {
|
||||||
|
float length = 0;
|
||||||
|
List<DataSutureSideVertex> vertexs = new List<DataSutureSideVertex>();
|
||||||
|
List<DataPlateVertex> sideVertexs = new List<DataPlateVertex>(vertexsArray);
|
||||||
|
if (isReversal) { sideVertexs.Reverse(); }
|
||||||
|
for (int i = 0; i < sideVertexs.Count - 1; i++) {
|
||||||
|
DataSutureSideVertex vertex = new DataSutureSideVertex(length, sideVertexs[i], sideVertexs[i + 1]);
|
||||||
|
vertexs.Add(vertex); length += vertex.Distance;
|
||||||
|
}
|
||||||
|
return vertexs;
|
||||||
|
}
|
||||||
|
/// <summary> 全部顶点 </summary>
|
||||||
|
private void AllVertexs(DataSutureSide sutureSide) {
|
||||||
|
DataPlateVertex[] vertexsArray = sutureSide.plateSide.dataBaking.vertexs;
|
||||||
|
List<DataSutureSideVertex> allVertexs = GetVertex(vertexsArray, false);
|
||||||
|
sutureSide.dataBaking.allVertexs = allVertexs.ToArray();
|
||||||
|
}
|
||||||
|
/// <summary> 缝合范围内的顶点 </summary>
|
||||||
|
private void SetVertex(DataSutureSide sutureSide) {
|
||||||
|
//全部顶点
|
||||||
|
List<DataSutureSideVertex> allVertexs = GetVertex(sutureSide.plateSide.dataBaking.vertexs, sutureSide.isReversal);
|
||||||
|
//缝合范围内的顶点
|
||||||
|
float maxLength = sutureSide.suture.length;
|
||||||
|
List<DataSutureSideVertex> vertexs = new List<DataSutureSideVertex>();
|
||||||
|
for (int i = 0; i < allVertexs.Count; i++) {
|
||||||
|
if (allVertexs[i].origin <= maxLength) { vertexs.Add(allVertexs[i]); }
|
||||||
|
}
|
||||||
|
sutureSide.dataBaking.vertexs = vertexs.ToArray();
|
||||||
|
}
|
||||||
|
/// <summary> 顶点转换位置 </summary>
|
||||||
|
private void SetPositions(DataSutureSide sutureSide) {
|
||||||
|
Vector3 platePosition = sutureSide.plateSide.plate.dataBaking.position;
|
||||||
|
Vector3 plateEulerAngles = sutureSide.plateSide.plate.dataBaking.eulerAngles;
|
||||||
|
List<Vector3> positions = new List<Vector3>();
|
||||||
|
DataSutureSideVertex[] vertexs = sutureSide.dataBaking.vertexs;
|
||||||
|
for (int i = 0; i < vertexs.Length; i++) {
|
||||||
|
Quaternion quaternion = Quaternion.Euler(plateEulerAngles);
|
||||||
|
Vector3 baking = quaternion * vertexs[i].a.position;
|
||||||
|
Vector3 position = baking + platePosition;
|
||||||
|
positions.Add(position);
|
||||||
|
}
|
||||||
|
sutureSide.dataBaking.positions = positions.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9735cc247f76e0b42b50f8b7956d3c8a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计的缝合线
|
||||||
|
/// </summary>
|
||||||
|
public class UnitAlgorithmSutureDesign : UnitAlgorithm<DataSutureSide> {
|
||||||
|
/// <summary> 设计的缝合线 </summary>
|
||||||
|
public UnitAlgorithmSutureDesign() { }
|
||||||
|
|
||||||
|
public class Line {
|
||||||
|
public float origin;
|
||||||
|
public Vector3 a;
|
||||||
|
public Vector3 b;
|
||||||
|
public Line(float origin, Vector3 a, Vector3 b) {
|
||||||
|
this.origin = origin;
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
public float Distance => Vector3.Distance(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Compute(DataSutureSide sutureSide) {
|
||||||
|
float maxLength = sutureSide.suture.length;
|
||||||
|
Vector3 platePosition = sutureSide.plateSide.plate.dataDesign.position;
|
||||||
|
List<Vector3> sidePositions = new List<Vector3>(sutureSide.plateSide.dataDesign.positions);
|
||||||
|
|
||||||
|
float length = 0;
|
||||||
|
List<Line> lines = new List<Line>();
|
||||||
|
if (sutureSide.isReversal) { sidePositions.Reverse(); }
|
||||||
|
for (int i = 0; i < sidePositions.Count - 1; i++) {
|
||||||
|
Line line = new Line(length, sidePositions[i], sidePositions[i + 1]);
|
||||||
|
lines.Add(line);
|
||||||
|
length += line.Distance;
|
||||||
|
}
|
||||||
|
List<Vector3> positions = new List<Vector3>();
|
||||||
|
for (int i = 0; i < lines.Count; i++) {
|
||||||
|
Line line = lines[i];
|
||||||
|
if (line.origin < maxLength) { positions.Add(line.a + platePosition); }
|
||||||
|
float nextDistance = line.origin + line.Distance;
|
||||||
|
if (nextDistance < maxLength) { continue; }
|
||||||
|
if (nextDistance == maxLength) { positions.Add(line.b + platePosition); break; }
|
||||||
|
float distance = maxLength - line.origin;
|
||||||
|
Vector3 direction = (line.b - line.a).normalized;
|
||||||
|
Vector3 position = line.a + direction * distance;
|
||||||
|
positions.Add(position + platePosition);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sutureSide.dataDesign.positions = positions.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b98adb17aebd36b4ab5dfe90020fb902
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -6,97 +6,95 @@ using UnityEngine;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 顶点算法
|
/// 顶点算法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UnitAlgorithmVertex : UnitAlgorithm<DataPlate> {
|
public class UnitAlgorithmVertex : UnitAlgorithm<DataPlateBaking> {
|
||||||
|
|
||||||
public class SideVertex : IComparable<SideVertex> {
|
public class SideVertex : IComparable<SideVertex> {
|
||||||
public float distance;
|
public float distance;
|
||||||
public DataVertex vertex;
|
public Vector3 position;
|
||||||
|
|
||||||
public int CompareTo(SideVertex other) {
|
public int CompareTo(SideVertex other) {
|
||||||
return other.distance >= distance ? 1 : -1;
|
if (other == null || this == null) { return 0; }
|
||||||
|
if (other == this) { return 0; }
|
||||||
|
if (other.distance > distance) { return -1; }
|
||||||
|
if (other.distance < distance) { return 1; }
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Compute(DataPlate data) {
|
public void Compute(DataPlateBaking plateBaking) {
|
||||||
float smooth = data.smooth;
|
DataBorder border = plateBaking.border;
|
||||||
DataBorder border = data.border;
|
Vector3[] points = border.points;
|
||||||
List<Vector3> edgePoints = new List<Vector3>(data.edgePoints);
|
|
||||||
|
|
||||||
int wide = Mathf.FloorToInt(border.Wide / smooth) + 1;
|
|
||||||
int high = Mathf.FloorToInt(border.High / smooth) + 1;
|
|
||||||
//计算内部顶点
|
//计算内部顶点
|
||||||
data.vertexGrid = new GridTool<DataVertex>(wide, high, (x, y) => {
|
//plateBaking.grid = new GridTool<DataPlateVertex>(border.GridWide, border.GridHigh, (x, y) => {
|
||||||
Vector3 position = border.MinPoint + new Vector3(x * smooth, y * smooth);
|
// Vector3 position = new Vector3(x, y) * border.smooth + border.MinPoint;
|
||||||
DataVertex vertex = new DataVertex();
|
// DataPlateVertex vertex = new DataPlateVertex();
|
||||||
vertex.isValid = FindPlateInside(edgePoints, position);
|
// vertex.isValid = FindPlateInside(points, position);
|
||||||
vertex.design = position;
|
// vertex.position = position;
|
||||||
return vertex;
|
// return vertex;
|
||||||
});
|
//});
|
||||||
|
|
||||||
//边缘所有的线段
|
//边缘所有的线段
|
||||||
for (int i = 0; i < data.sides.Count; i++) {
|
//List<DataPlateSide> plateSides = plateBaking.plate.plateSides;
|
||||||
Compute(data.sides[i], wide, high, border, smooth, data.vertexGrid);
|
//for (int i = 0; i < plateSides.Count; i++) {
|
||||||
}
|
// SubdivideSideVertex(plateBaking, plateSides[i]);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> 向网格和边缘写入顶点数据 </summary>
|
private void SubdivideSideVertex(DataPlateBaking plateBaking, DataPlateSide plateSides) {
|
||||||
private void Compute(DataSide side, int wide, int high, DataBorder border, float smooth, GridTool<DataVertex> grid) {
|
DataBorder border = plateBaking.border;
|
||||||
DataLine[] lines = side.lines;
|
DataPlateLine[] lines = plateSides.dataBaking.lines;
|
||||||
List<SideVertex> sideVertices = new List<SideVertex>();
|
|
||||||
//计算水平线段顶点
|
//计算水平线段顶点
|
||||||
for (int x = 0; x < wide; x++) {
|
List<SideVertex> sideVertexs = new List<SideVertex>();
|
||||||
Vector3 a = new Vector3(border.minX + x * smooth, border.minY - 1);
|
for (int x = 0; x < border.GridWide; x++) {
|
||||||
Vector3 b = new Vector3(border.minX + x * smooth, border.maxY + 1);
|
Vector3 a = new Vector3(border.minX + x * border.smooth, border.minY - 1);
|
||||||
|
Vector3 b = new Vector3(border.minX + x * border.smooth, border.maxY + 1);
|
||||||
for (int i = 0; i < lines.Length; i++) {
|
for (int i = 0; i < lines.Length; i++) {
|
||||||
DataVertex vertex = Compute(a, b, lines[i], smooth, border, grid);
|
if (!TryGetIntersectPoint(a, b, lines[i].a, lines[i].b, out Vector3 IntersectPoint)) { continue; }
|
||||||
if (vertex == null) { continue; }
|
float distance = Vector3.Distance(lines[i].a, IntersectPoint) + lines[i].origin;
|
||||||
float distance = Vector3.Distance(lines[i].a, vertex.design) + lines[i].origin;
|
|
||||||
SideVertex sideVertex = new SideVertex();
|
SideVertex sideVertex = new SideVertex();
|
||||||
sideVertex.distance = distance;
|
sideVertex.distance = distance;
|
||||||
sideVertex.vertex = vertex;
|
sideVertex.position = IntersectPoint;
|
||||||
sideVertices.Add(sideVertex);
|
sideVertexs.Add(sideVertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//计算垂直线段顶点
|
//计算垂直线段顶点
|
||||||
for (int y = 0; y < high; y++) {
|
for (int y = 0; y < border.GridHigh; y++) {
|
||||||
Vector3 a = new Vector3(border.minX - 1, border.minY + y * smooth);
|
Vector3 a = new Vector3(border.minX - 1, border.minY + y * border.smooth);
|
||||||
Vector3 b = new Vector3(border.maxX + 1, border.minY + y * smooth);
|
Vector3 b = new Vector3(border.maxX + 1, border.minY + y * border.smooth);
|
||||||
for (int i = 0; i < lines.Length; i++) {
|
for (int i = 0; i < lines.Length; i++) {
|
||||||
DataVertex vertex = Compute(a, b, lines[i], smooth, border, grid);
|
if (!TryGetIntersectPoint(a, b, lines[i].a, lines[i].b, out Vector3 IntersectPoint)) { continue; }
|
||||||
if (vertex == null) { continue; }
|
float distance = Vector3.Distance(lines[i].a, IntersectPoint) + lines[i].origin;
|
||||||
float distance = Vector3.Distance(lines[i].a, vertex.design) + lines[i].origin;
|
|
||||||
SideVertex sideVertex = new SideVertex();
|
SideVertex sideVertex = new SideVertex();
|
||||||
sideVertex.distance = distance;
|
sideVertex.distance = distance;
|
||||||
sideVertex.vertex = vertex;
|
sideVertex.position = IntersectPoint;
|
||||||
sideVertices.Add(sideVertex);
|
sideVertexs.Add(sideVertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sideVertices.Sort();
|
//排序
|
||||||
List<DataVertex> vertices = new List<DataVertex>();
|
sideVertexs.Sort();
|
||||||
for (int i = 0; i < sideVertices.Count; i++) {
|
//写入网格,写入顶点
|
||||||
vertices.Add(sideVertices[i].vertex);
|
Vector3 offset = border.MinPoint - new Vector3(border.smooth, border.smooth, 0) * 0.3f;
|
||||||
|
List<DataPlateVertex> vertexs = new List<DataPlateVertex>();
|
||||||
|
for (int i = 0; i < sideVertexs.Count; i++) {
|
||||||
|
Vector3 position = sideVertexs[i].position;
|
||||||
|
Vector3 gridPosition = position - offset;
|
||||||
|
int vertexX = Mathf.FloorToInt(gridPosition.x / border.smooth);
|
||||||
|
int vertexY = Mathf.FloorToInt(gridPosition.y / border.smooth);
|
||||||
|
//填充数据
|
||||||
|
//DataPlateVertex vertex = plateBaking.grid.Get(vertexX, vertexY);
|
||||||
|
//vertex.isValid = true;
|
||||||
|
//vertex.position = position;
|
||||||
|
////写入顶点
|
||||||
|
//vertexs.Add(vertex);
|
||||||
}
|
}
|
||||||
side.vertices = vertices.ToArray();
|
plateSides.dataBaking.vertexs = vertexs.ToArray();
|
||||||
}
|
|
||||||
/// <summary> 向网格写入边缘顶点数据 </summary>
|
|
||||||
private DataVertex Compute(Vector3 a, Vector3 b, DataLine line, float smooth, DataBorder border, GridTool<DataVertex> grid) {
|
|
||||||
//计算交点
|
|
||||||
if (!TryGetIntersectPoint(a, b, line.a, line.b, out Vector3 IntersectPoint)) { return null; }
|
|
||||||
//计算顶点xy
|
|
||||||
Vector3 offset = new Vector3(smooth, smooth, 0) * 0.3f;
|
|
||||||
Vector3 position = IntersectPoint - border.MinPoint + offset;
|
|
||||||
int vertexX = Mathf.FloorToInt(position.x / smooth);
|
|
||||||
int vertexY = Mathf.FloorToInt(position.y / smooth);
|
|
||||||
//填充数据
|
|
||||||
DataVertex vertex = grid.Get(vertexX, vertexY);
|
|
||||||
vertex.isValid = true;
|
|
||||||
vertex.design = IntersectPoint;
|
|
||||||
return vertex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> 转角法查询位置是否在板片内 </summary>
|
/// <summary> 转角法查询位置是否在板片内 </summary>
|
||||||
public static bool FindPlateInside(List<Vector3> points, Vector3 position) {
|
public static bool FindPlateInside(Vector3[] points, Vector3 position) {
|
||||||
double angles = 0;
|
double angles = 0;
|
||||||
for (int i = 0; i < points.Count; i++) {
|
for (int i = 0; i < points.Length; i++) {
|
||||||
Vector3 a = points.LoopIndex(i + 0) - position;
|
Vector3 a = points.LoopIndex(i + 0) - position;
|
||||||
Vector3 b = points.LoopIndex(i + 1) - position;
|
Vector3 b = points.LoopIndex(i + 1) - position;
|
||||||
float angle = Vector2.SignedAngle(a, b);
|
float angle = Vector2.SignedAngle(a, b);
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3105cf897e8dcb6408a9d5b207fa348e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询边交点
|
||||||
|
/// </summary>
|
||||||
|
public class FindSideIntersectPoint : UnitFind<SideIntersectPoint> {
|
||||||
|
public readonly float FindRange = 0.01f;
|
||||||
|
/// <summary> 板片资产 </summary>
|
||||||
|
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.I.AssetsPlate;
|
||||||
|
|
||||||
|
/// <summary> 查询边交点 </summary>
|
||||||
|
public FindSideIntersectPoint() { }
|
||||||
|
|
||||||
|
public bool Find(Vector3 position, out SideIntersectPoint sip) {
|
||||||
|
sip = new SideIntersectPoint();
|
||||||
|
List<DataPlate> plates = AssetsPlate.Datas;
|
||||||
|
for (int i = 0; i < plates.Count; i++) {
|
||||||
|
Vector3 localPosition = position - plates[i].dataDesign.position;
|
||||||
|
sip.side = Find(plates[i], localPosition, out sip.intersectPoint);
|
||||||
|
sip.intersectPoint += plates[i].dataDesign.position;
|
||||||
|
if (sip.side != null) { return true; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/// <summary> 查询匹配的边 </summary>
|
||||||
|
private DataPlateSide Find(DataPlate plate, Vector3 localPosition, out Vector3 intersectPoint) {
|
||||||
|
intersectPoint = Vector3.zero;
|
||||||
|
for (int i = 0; i < plate.plateSides.Count; i++) {
|
||||||
|
DataPlateSide side = Find(plate.plateSides[i], localPosition, out intersectPoint);
|
||||||
|
if (side != null) { return side; }
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/// <summary> 查询匹配的边 </summary>
|
||||||
|
private DataPlateSide Find(DataPlateSide side, Vector3 localPosition, out Vector3 intersectPoint) {
|
||||||
|
intersectPoint = Vector3.zero;
|
||||||
|
for (int i = 0; i < side.dataDesign.lines.Length; i++) {
|
||||||
|
Vector3 a = side.dataDesign.lines[i].a;
|
||||||
|
Vector3 b = side.dataDesign.lines[i].b;
|
||||||
|
float distance = ProjectDistance(a, b, localPosition, out intersectPoint);
|
||||||
|
if (distance < FindRange) { return side; }
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向量投影法
|
||||||
|
/// 计算点c到线段ab最近的点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a"></param>
|
||||||
|
/// <param name="b"></param>
|
||||||
|
/// <param name="c"></param>
|
||||||
|
/// <returns>如果不在线段上返回 float.MaxValue</returns>
|
||||||
|
public static float ProjectDistance(Vector3 a, Vector3 b, Vector3 c, out Vector3 intersectPoint) {
|
||||||
|
Vector3 ab = b - a;
|
||||||
|
Vector3 ac = c - a;
|
||||||
|
Vector3 p = Vector3.Project(ac, ab);
|
||||||
|
intersectPoint = p + a;
|
||||||
|
if (ab.normalized != p.normalized) { return float.MaxValue; }
|
||||||
|
if (ab.magnitude < p.magnitude) { return float.MaxValue; }
|
||||||
|
return Vector3.Distance(c, p + a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 边交点
|
||||||
|
/// </summary>
|
||||||
|
public class SideIntersectPoint {
|
||||||
|
/// <summary> 匹配的边 </summary>
|
||||||
|
public DataPlateSide side;
|
||||||
|
/// <summary> 交点 </summary>
|
||||||
|
public Vector3 intersectPoint;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 368e1bf20f25d424f8ed16d00323b8b8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public interface UnitFind<Data> {
|
||||||
|
/// <summary> 查询 </summary>
|
||||||
|
public bool Find(Vector3 position, out Data data);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 77073523d35e8fb4bb758404278690c5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -17,15 +17,15 @@ public class BakingMobilePlate : UnitMouseInput {
|
|||||||
if (!ViewCamera.ScreenToWorldObject(data.ScreenPosition, out platePrefab)) { return; }
|
if (!ViewCamera.ScreenToWorldObject(data.ScreenPosition, out platePrefab)) { return; }
|
||||||
mousePosition = data.ScreenPosition;
|
mousePosition = data.ScreenPosition;
|
||||||
originalPosition = platePrefab.transform.localPosition;
|
originalPosition = platePrefab.transform.localPosition;
|
||||||
platePrefab.Value.bakingPosition = originalPosition;
|
platePrefab.Value.dataBaking.position = originalPosition;
|
||||||
ModuleCore.BakingMobilePlate(platePrefab.Value);
|
ModuleCore.BakingMobilePlate(platePrefab.Value);
|
||||||
}
|
}
|
||||||
public override void MouseDrag(DataMouseInput data) {
|
public override void MouseDrag(DataMouseInput data) {
|
||||||
if (platePrefab == null) { return; }
|
if (platePrefab == null) { return; }
|
||||||
if (ViewCamera.ScreenToWorldObjectParent(data.ScreenPosition, out arrange, Arrange)) {
|
if (ViewCamera.ScreenToWorldObjectParent(data.ScreenPosition, out arrange, Arrange)) {
|
||||||
platePrefab.Value.arrange = arrange;
|
platePrefab.Value.arrange = arrange;
|
||||||
platePrefab.Value.bakingPosition = arrange.transform.localPosition;
|
platePrefab.Value.dataBaking.position = arrange.transform.localPosition;
|
||||||
platePrefab.Value.bakingEulerAngles = arrange.transform.localEulerAngles;
|
platePrefab.Value.dataBaking.eulerAngles = arrange.transform.localEulerAngles;
|
||||||
}
|
}
|
||||||
else { Mobile(data.WorldPosition); }
|
else { Mobile(data.WorldPosition); }
|
||||||
platePrefab.Value.UpdateVisual(false);
|
platePrefab.Value.UpdateVisual(false);
|
||||||
@@ -41,6 +41,6 @@ public class BakingMobilePlate : UnitMouseInput {
|
|||||||
Vector3 offset = current - original;
|
Vector3 offset = current - original;
|
||||||
Vector3 up = ViewCamera.Up * offset.y;
|
Vector3 up = ViewCamera.Up * offset.y;
|
||||||
Vector3 right = ViewCamera.Right * offset.x;
|
Vector3 right = ViewCamera.Right * offset.x;
|
||||||
platePrefab.Value.bakingPosition = originalPosition - up - right;
|
platePrefab.Value.dataBaking.position = originalPosition - up - right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ public class DesignBezier : UnitMouseInput {
|
|||||||
/// <summary> 设计视图相机模块 </summary>
|
/// <summary> 设计视图相机模块 </summary>
|
||||||
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
||||||
/// <summary> 查询点算法模块 </summary>
|
/// <summary> 查询点算法模块 </summary>
|
||||||
public ModuleFind<DataSide> FindSide => ModuleCore.FindSide;
|
public ModuleFind<DataPlateSide> FindSide => ModuleCore.FindSide;
|
||||||
|
|
||||||
public override void MouseDown(DataMouseInput data) {
|
public override void MouseDown(DataMouseInput data) {
|
||||||
if (!FindSide.Find(data.WorldPosition, out DataSide side)) { return; }
|
if (!FindSide.Find(data.WorldPosition, out DataPlateSide side)) { return; }
|
||||||
if (side.bezier == Bezier.一阶) { side.TwoRankBezier(); side.plate.UpdateVisual(); return; }
|
if (side.bezier == Bezier.一阶) { side.TwoRankBezier(); side.plate.UpdateVisual(); return; }
|
||||||
if (side.bezier == Bezier.二阶) { side.ThreeRankBezier(); side.plate.UpdateVisual(); return; }
|
if (side.bezier == Bezier.二阶) { side.ThreeRankBezier(); side.plate.UpdateVisual(); return; }
|
||||||
if (side.bezier == Bezier.三阶) { side.OneRankBezier(); side.plate.UpdateVisual(); return; }
|
if (side.bezier == Bezier.三阶) { side.OneRankBezier(); side.plate.UpdateVisual(); return; }
|
||||||
|
|||||||
@@ -3,28 +3,33 @@ using System.Collections.Generic;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class DesignInsert : UnitMouseInput {
|
public class DesignInsert : UnitMouseInput {
|
||||||
/// <summary> 板片资产 </summary>
|
/// <summary> 查询边交点 </summary>
|
||||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
public UnitFind<SideIntersectPoint> find = new FindSideIntersectPoint();
|
||||||
/// <summary> 查询边算法模块 </summary>
|
|
||||||
public ModuleFind<DataSide> FindSide => ModuleCore.FindSide;
|
|
||||||
/// <summary> 计算位置到边上最近的点 </summary>
|
|
||||||
public ModuleAlgorithm<DataIntersect> AlgorithmSidePoint => ModuleCore.AlgorithmSidePoint;
|
|
||||||
/// <summary> 插入点数据转换板片上的点 </summary>
|
|
||||||
public ModuleBuilder<DataInsertPoint, DataPoint> InsertPointToPoint => ModuleCore.InsertPointToPoint;
|
|
||||||
|
|
||||||
public override void MouseDown(DataMouseInput data) {
|
public override void MouseDown(DataMouseInput data) {
|
||||||
if (!FindSide.Find(data.WorldPosition, out DataSide side)) { return; }
|
if (!find.Find(data.WorldPosition, out SideIntersectPoint sip)) { return; }
|
||||||
|
Insert(sip.side, sip.side.plate, sip.side.aPoint, sip.side.bPoint, sip.intersectPoint);
|
||||||
|
}
|
||||||
|
|
||||||
DataIntersect intersect = new DataIntersect(side, data.WorldPosition);
|
private void Insert(DataPlateSide side, DataPlate plate, DataPlatePoint aPoint, DataPlatePoint bPoint, Vector3 position) {
|
||||||
AlgorithmSidePoint.Compute(intersect);
|
//创建新的点
|
||||||
if (!intersect.isIntersect) { return; }
|
DataPlatePoint newPoint = new DataPlatePoint(plate);
|
||||||
|
newPoint.position = position - plate.dataDesign.position;
|
||||||
DataInsertPoint insertPoint = new DataInsertPoint();
|
//改变关联的边B点,重置贝塞尔曲线
|
||||||
insertPoint.position = intersect.intersectPoint - side.plate.designPosition;
|
side.bPoint = newPoint;
|
||||||
insertPoint.plate = side.plate;
|
side.OneRankBezier();
|
||||||
insertPoint.aPoint = side.aPoint;
|
//创建新的边
|
||||||
insertPoint.bPoint = side.bPoint;
|
DataPlateSide newSide = new DataPlateSide(plate);
|
||||||
insertPoint.side = side;
|
newSide.aPoint = newPoint;
|
||||||
InsertPointToPoint.To(insertPoint);
|
newSide.bPoint = bPoint;
|
||||||
|
newSide.OneRankBezier();
|
||||||
|
//插入边
|
||||||
|
int sideIndex = plate.plateSides.IndexOf(side);
|
||||||
|
plate.plateSides.Insert(sideIndex + 1, newSide);
|
||||||
|
//插入点
|
||||||
|
int pointIndex = plate.platePoints.IndexOf(aPoint);
|
||||||
|
plate.platePoints.Insert(pointIndex + 1, newPoint);
|
||||||
|
//更新数据
|
||||||
|
plate.UpdateVisual();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class DesignMobile : UnitMouseInput {
|
|||||||
private DataBezier bezier;
|
private DataBezier bezier;
|
||||||
private Vector3 mousePosition;
|
private Vector3 mousePosition;
|
||||||
private Vector3 originalPosition;
|
private Vector3 originalPosition;
|
||||||
private ModulePrefab<DataPoint> prefabPoint;
|
private ModulePrefab<DataPlatePoint> prefabPoint;
|
||||||
private ModulePrefab<DataPlate> prefabPlate;
|
private ModulePrefab<DataPlate> prefabPlate;
|
||||||
|
|
||||||
public override void MouseDown(DataMouseInput data) {
|
public override void MouseDown(DataMouseInput data) {
|
||||||
@@ -61,10 +61,10 @@ public class DesignMobile : UnitMouseInput {
|
|||||||
//板片
|
//板片
|
||||||
private void RecordPlate(Vector3 screenPosition) {
|
private void RecordPlate(Vector3 screenPosition) {
|
||||||
mousePosition = screenPosition;
|
mousePosition = screenPosition;
|
||||||
originalPosition = prefabPlate.Value.designPosition;
|
originalPosition = prefabPlate.Value.dataDesign.position;
|
||||||
}
|
}
|
||||||
private void MobilePlate(Vector3 offset) {
|
private void MobilePlate(Vector3 offset) {
|
||||||
prefabPlate.Value.designPosition = originalPosition + offset;
|
prefabPlate.Value.dataDesign.position = originalPosition + offset;
|
||||||
prefabPlate.Value.UpdateVisual(false);
|
prefabPlate.Value.UpdateVisual(false);
|
||||||
}
|
}
|
||||||
//相机
|
//相机
|
||||||
|
|||||||
@@ -3,29 +3,30 @@ using System.Collections.Generic;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class DesignSuture : UnitMouseInput {
|
public class DesignSuture : UnitMouseInput {
|
||||||
/// <summary> 设计视图相机模块 </summary>
|
/// <summary> 查询边交点 </summary>
|
||||||
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
public UnitFind<SideIntersectPoint> find = new FindSideIntersectPoint();
|
||||||
/// <summary> 查询点算法模块 </summary>
|
|
||||||
public ModuleFind<DataSide> FindSide => ModuleCore.FindSide;
|
|
||||||
/// <summary> 计算位置到边上最近的点 </summary>
|
|
||||||
public ModuleAlgorithm<DataIntersect> AlgorithmSidePoint => ModuleCore.AlgorithmSidePoint;
|
|
||||||
/// <summary> 连接可视化内容生成模块 </summary>
|
/// <summary> 连接可视化内容生成模块 </summary>
|
||||||
public ModuleVisual<DataConnector> VisualConnector => ModuleCore.VisualConnector;
|
public ModuleVisual<DataConnector> VisualConnector => ModuleCore.VisualConnector;
|
||||||
|
|
||||||
private DataSide aSide;
|
private DataPlateSide aSide;
|
||||||
private DataSide bSide;
|
private DataPlateSide bSide;
|
||||||
private DataConnector connector;
|
private DataConnector connector;
|
||||||
|
|
||||||
public override void MouseDown(DataMouseInput data) {
|
public override void MouseDown(DataMouseInput data) {
|
||||||
if (!FindSide.Find(data.WorldPosition, out aSide)) { return; }
|
|
||||||
if (!Intersect(aSide, data.WorldPosition, out Vector3 intersectPoint)) { return; }
|
|
||||||
connector = new DataConnector();
|
connector = new DataConnector();
|
||||||
connector.aPoint = intersectPoint;
|
connector.aPoint = data.WorldPosition;
|
||||||
connector.bPoint = intersectPoint;
|
if (!find.Find(data.WorldPosition, out SideIntersectPoint sip)) { return; }
|
||||||
|
connector.aPoint = sip.intersectPoint;
|
||||||
|
aSide = sip.side;
|
||||||
}
|
}
|
||||||
public override void MouseDrag(DataMouseInput data) {
|
public override void MouseDrag(DataMouseInput data) {
|
||||||
if (aSide == null) { return; }
|
if (connector == null) { return; }
|
||||||
connector.bPoint = GetPosition(data);
|
connector.bPoint = data.WorldPosition;
|
||||||
|
if (find.Find(data.WorldPosition, out SideIntersectPoint sip)) {
|
||||||
|
connector.bPoint = sip.intersectPoint;
|
||||||
|
bSide = sip.side;
|
||||||
|
}
|
||||||
|
else { connector.bPoint = data.WorldPosition; }
|
||||||
VisualConnector.UpdateVisual(connector);
|
VisualConnector.UpdateVisual(connector);
|
||||||
}
|
}
|
||||||
public override void MouseRelease(DataMouseInput data) {
|
public override void MouseRelease(DataMouseInput data) {
|
||||||
@@ -41,16 +42,16 @@ public class DesignSuture : UnitMouseInput {
|
|||||||
aSide.plate.UpdateVisual();
|
aSide.plate.UpdateVisual();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector3 GetPosition(DataMouseInput data) {
|
//private Vector3 GetPosition(DataMouseInput data) {
|
||||||
if (!FindSide.Find(data.WorldPosition, out bSide)) { return data.WorldPosition; }
|
// if (!FindSide.Find(data.WorldPosition, out bSide)) { return data.WorldPosition; }
|
||||||
if (aSide == bSide) { return data.WorldPosition; }
|
// if (aSide == bSide) { return data.WorldPosition; }
|
||||||
if (Intersect(bSide, data.WorldPosition, out Vector3 intersectPoint)) { return intersectPoint; }
|
// if (Intersect(bSide, data.WorldPosition, out Vector3 intersectPoint)) { return intersectPoint; }
|
||||||
else { return data.WorldPosition; }
|
// else { return data.WorldPosition; }
|
||||||
}
|
//}
|
||||||
private bool Intersect(DataSide side, Vector3 position, out Vector3 intersectPoint) {
|
//private bool Intersect(DataSide side, Vector3 position, out Vector3 intersectPoint) {
|
||||||
DataIntersect intersect = new DataIntersect(side, position);
|
//DataIntersect intersect = new DataIntersect(side, position);
|
||||||
AlgorithmSidePoint.Compute(intersect);
|
//AlgorithmSidePoint.Compute(intersect);
|
||||||
intersectPoint = intersect.intersectPoint;
|
//intersectPoint = intersect.intersectPoint;
|
||||||
return intersect.isIntersect;
|
//return intersect.isIntersect;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ public class DesignSutureReversal : UnitMouseInput {
|
|||||||
/// <summary> 设计视图相机模块 </summary>
|
/// <summary> 设计视图相机模块 </summary>
|
||||||
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
||||||
/// <summary> 查询点算法模块 </summary>
|
/// <summary> 查询点算法模块 </summary>
|
||||||
public ModuleFind<DataSide> FindSide => ModuleCore.FindSide;
|
public ModuleFind<DataPlateSide> FindSide => ModuleCore.FindSide;
|
||||||
|
|
||||||
public override void MouseDown(DataMouseInput data) {
|
public override void MouseDown(DataMouseInput data) {
|
||||||
if (!FindSide.Find(data.WorldPosition, out DataSide side)) { return; }
|
if (!FindSide.Find(data.WorldPosition, out DataPlateSide side)) { return; }
|
||||||
if (side.suture.a.side == side) {
|
if (side.suture.a.plateSide == side) {
|
||||||
side.suture.a.isReversal = !side.suture.a.isReversal;
|
side.suture.a.isReversal = !side.suture.a.isReversal;
|
||||||
}
|
}
|
||||||
if (side.suture.b.side == side) {
|
if (side.suture.b.plateSide == side) {
|
||||||
side.suture.b.isReversal = !side.suture.b.isReversal;
|
side.suture.b.isReversal = !side.suture.b.isReversal;
|
||||||
}
|
}
|
||||||
side.plate.UpdateVisual();
|
side.plate.UpdateVisual();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"com.muhua.tools": "https://github.com/MuHua-123/MuHua-Tools.git?path=Packages/Tools",
|
"com.muhua.tools": "https://github.com/MuHua-123/MuHua-Tools.git?path=Packages/Tools",
|
||||||
"com.muhua.uicontrol": "https://github.com/MuHua-123/MuHua-UIControl.git?path=Packages/UIControl",
|
"com.muhua.uicontrol": "https://github.com/MuHua-123/MuHua-UIControl.git?path=Packages/UIControl",
|
||||||
"com.unity.collab-proxy": "2.5.2",
|
"com.unity.collab-proxy": "2.5.2",
|
||||||
|
"com.unity.collections": "1.2.4",
|
||||||
"com.unity.feature.development": "1.0.1",
|
"com.unity.feature.development": "1.0.1",
|
||||||
"com.unity.render-pipelines.universal": "14.0.11",
|
"com.unity.render-pipelines.universal": "14.0.11",
|
||||||
"com.unity.textmeshpro": "3.0.6",
|
"com.unity.textmeshpro": "3.0.6",
|
||||||
|
|||||||
@@ -30,6 +30,16 @@
|
|||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"url": "https://packages.unity.cn"
|
"url": "https://packages.unity.cn"
|
||||||
},
|
},
|
||||||
|
"com.unity.collections": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"depth": 0,
|
||||||
|
"source": "registry",
|
||||||
|
"dependencies": {
|
||||||
|
"com.unity.burst": "1.6.6",
|
||||||
|
"com.unity.test-framework": "1.1.31"
|
||||||
|
},
|
||||||
|
"url": "https://packages.unity.cn"
|
||||||
|
},
|
||||||
"com.unity.editorcoroutines": {
|
"com.unity.editorcoroutines": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"depth": 1,
|
"depth": 1,
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &1
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 53
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: de02f9e1d18f588468e474319d09a723, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
shaderVariantLimit: 128
|
||||||
|
customInterpolatorErrorThreshold: 32
|
||||||
|
customInterpolatorWarningThreshold: 16
|
||||||
Reference in New Issue
Block a user