1
This commit is contained in:
@@ -5,41 +5,41 @@ using UnityEngine;
|
||||
/// <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) {
|
||||
Vector3 position = data.position - data.side.plate.designPosition;
|
||||
for (int i = 0; i < data.side.lines.Length; i++) {
|
||||
DataLine line = data.side.lines[i];
|
||||
if (!Compute(line, position, out Vector3 intersectPoint)) { continue; }
|
||||
data.isIntersect = true;
|
||||
data.intersectPoint = intersectPoint + data.side.plate.designPosition;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// public override void Compute(DataIntersect data) {
|
||||
// Vector3 position = data.position - data.side.plate.designPosition;
|
||||
// for (int i = 0; i < data.side.lines.Length; i++) {
|
||||
// DataLine line = data.side.lines[i];
|
||||
// if (!Compute(line, position, out Vector3 intersectPoint)) { continue; }
|
||||
// data.isIntersect = true;
|
||||
// data.intersectPoint = intersectPoint + data.side.plate.designPosition;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary> 查询匹配的边 </summary>
|
||||
private bool Compute(DataLine line, Vector3 position, out Vector3 intersectPoint) {
|
||||
return ProjectDistance(line.a, line.b, position, out intersectPoint);
|
||||
}
|
||||
// /// <summary> 查询匹配的边 </summary>
|
||||
// private bool Compute(DataLine line, Vector3 position, out Vector3 intersectPoint) {
|
||||
// return ProjectDistance(line.a, line.b, position, out intersectPoint);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 向量投影法
|
||||
/// 计算点c到线段ab最近的点
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <param name="c"></param>
|
||||
/// <returns>如果不在线段上返回 false</returns>
|
||||
public static bool ProjectDistance(Vector3 a, Vector3 b, Vector3 c, out Vector3 intersectPoint) {
|
||||
Vector3 ab = b - a;
|
||||
Vector3 ac = c - a;
|
||||
Vector3 p = Vector3.Project(ac, ab.normalized);
|
||||
intersectPoint = p + a;
|
||||
if (ab.normalized != p.normalized) { return false; }
|
||||
if (ab.magnitude < p.magnitude) { return false; }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 向量投影法
|
||||
// /// 计算点c到线段ab最近的点
|
||||
// /// </summary>
|
||||
// /// <param name="a"></param>
|
||||
// /// <param name="b"></param>
|
||||
// /// <param name="c"></param>
|
||||
// /// <returns>如果不在线段上返回 false</returns>
|
||||
// public static bool ProjectDistance(Vector3 a, Vector3 b, Vector3 c, out Vector3 intersectPoint) {
|
||||
// Vector3 ab = b - a;
|
||||
// Vector3 ac = c - a;
|
||||
// Vector3 p = Vector3.Project(ac, ab.normalized);
|
||||
// intersectPoint = p + a;
|
||||
// if (ab.normalized != p.normalized) { return false; }
|
||||
// if (ab.magnitude < p.magnitude) { return false; }
|
||||
// return true;
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -6,18 +6,18 @@ using UnityEngine;
|
||||
/// 散列点生成简单多边形算法
|
||||
/// </summary>
|
||||
public class AlgorithmSimplePolygon : ModuleAlgorithm<DataPlate> {
|
||||
private UnitAlgorithm<DataPlate> AlgorithmSideSubdivision = new UnitAlgorithmBezier();
|
||||
private UnitAlgorithm<DataPlate> AlgorithmTriangle = new UnitAlgorithmEarCutting();
|
||||
private UnitAlgorithm<DataPlate> AlgorithmMergeTriangle = new UnitAlgorithmMergeTriangle();
|
||||
private UnitAlgorithm<DataPlateDesign> AlgorithmSideSubdivision = new UnitAlgorithmJobsSideSubdivision();
|
||||
private UnitAlgorithm<DataPlateDesign> AlgorithmTriangle = new UnitAlgorithmEarCutting();
|
||||
private UnitAlgorithm<DataPlateDesign> AlgorithmMergeTriangle = new UnitAlgorithmMergeTriangle();
|
||||
|
||||
protected override void Awake() => ModuleCore.AlgorithmSimplePolygon = this;
|
||||
|
||||
public override void Compute(DataPlate data) {
|
||||
public override void Compute(DataPlate plate) {
|
||||
//遍历计算边(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>
|
||||
public class AlgorithmSutureSide : ModuleAlgorithm<DataSutureSide> {
|
||||
public class VertexPosition : IComparable<VertexPosition> {
|
||||
public Vector3 designPosition;
|
||||
public Vector3 bakingPosition;
|
||||
public float distance;
|
||||
public int CompareTo(VertexPosition other) {
|
||||
return other.distance >= distance ? 1 : -1;
|
||||
}
|
||||
}
|
||||
//public class AlgorithmSutureSide : ModuleAlgorithm<DataSutureSide> {
|
||||
// public class VertexPosition : IComparable<VertexPosition> {
|
||||
// public Vector3 designPosition;
|
||||
// public Vector3 bakingPosition;
|
||||
// public float distance;
|
||||
// public int CompareTo(VertexPosition other) {
|
||||
// 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) {
|
||||
//List<VertexPosition> vertexPositions = VertexPositions(data);
|
||||
data.designPositions = VertexToDesignPositions(data).ToArray();
|
||||
data.bakingPositions = VertexToBakingPositions(data).ToArray();
|
||||
}
|
||||
// public override void Compute(DataSutureSide data) {
|
||||
// //List<VertexPosition> vertexPositions = VertexPositions(data);
|
||||
// data.designPositions = VertexToDesignPositions(data).ToArray();
|
||||
// data.bakingPositions = VertexToBakingPositions(data).ToArray();
|
||||
// }
|
||||
|
||||
private List<VertexPosition> VertexPositions(DataSutureSide sutureSide) {
|
||||
List<VertexPosition> vertexPositions = new List<VertexPosition>();
|
||||
for (int i = 0; i < sutureSide.Vertices.Length; i++) {
|
||||
Vector3 design = sutureSide.Vertices[i].design;
|
||||
Quaternion quaternion = Quaternion.Euler(sutureSide.PlateBakingEulerAngles);
|
||||
Vector3 baking = quaternion * sutureSide.Vertices[i].design;
|
||||
VertexPosition vertexPosition = new VertexPosition();
|
||||
vertexPosition.designPosition = design + sutureSide.PlateDesignPosition;
|
||||
vertexPosition.bakingPosition = baking + sutureSide.PlateBakingPosition;
|
||||
vertexPosition.distance = Vector3.Distance(design, sutureSide.side.aPoint.position);
|
||||
vertexPositions.Add(vertexPosition);
|
||||
}
|
||||
//按距离从小到大排序
|
||||
vertexPositions.Sort();
|
||||
//是否颠倒
|
||||
if (sutureSide.isReversal) { vertexPositions.Reverse(); }
|
||||
return vertexPositions;
|
||||
}
|
||||
private List<Vector3> VertexToDesignPositions(DataSutureSide data) {
|
||||
//转换列表
|
||||
List<Vector3> positions = new List<Vector3>();
|
||||
for (int i = 0; i < data.Vertices.Length; i++) {
|
||||
Vector3 position = data.Vertices[i].design + data.PlateDesignPosition;
|
||||
positions.Add(position);
|
||||
}
|
||||
if (data.isReversal) { positions.Reverse(); }
|
||||
return positions;
|
||||
}
|
||||
private List<Vector3> VertexToBakingPositions(DataSutureSide data) {
|
||||
//转换列表
|
||||
List<Vector3> positions = new List<Vector3>();
|
||||
for (int i = 0; i < data.Vertices.Length; i++) {
|
||||
Quaternion quaternion = Quaternion.Euler(data.PlateBakingEulerAngles);
|
||||
Vector3 baking = quaternion * data.Vertices[i].design;
|
||||
Vector3 position = baking + data.PlateBakingPosition;
|
||||
positions.Add(position);
|
||||
}
|
||||
if (data.isReversal) { positions.Reverse(); }
|
||||
return positions;
|
||||
}
|
||||
}
|
||||
// private List<VertexPosition> VertexPositions(DataSutureSide sutureSide) {
|
||||
// List<VertexPosition> vertexPositions = new List<VertexPosition>();
|
||||
// for (int i = 0; i < sutureSide.Vertices.Length; i++) {
|
||||
// Vector3 design = sutureSide.Vertices[i].design;
|
||||
// Quaternion quaternion = Quaternion.Euler(sutureSide.PlateBakingEulerAngles);
|
||||
// Vector3 baking = quaternion * sutureSide.Vertices[i].design;
|
||||
// VertexPosition vertexPosition = new VertexPosition();
|
||||
// vertexPosition.designPosition = design + sutureSide.PlateDesignPosition;
|
||||
// vertexPosition.bakingPosition = baking + sutureSide.PlateBakingPosition;
|
||||
// vertexPosition.distance = Vector3.Distance(design, sutureSide.side.aPoint.position);
|
||||
// vertexPositions.Add(vertexPosition);
|
||||
// }
|
||||
// //按距离从小到大排序
|
||||
// vertexPositions.Sort();
|
||||
// //是否颠倒
|
||||
// if (sutureSide.isReversal) { vertexPositions.Reverse(); }
|
||||
// return vertexPositions;
|
||||
// }
|
||||
// private List<Vector3> VertexToDesignPositions(DataSutureSide data) {
|
||||
// //转换列表
|
||||
// List<Vector3> positions = new List<Vector3>();
|
||||
// for (int i = 0; i < data.Vertices.Length; i++) {
|
||||
// Vector3 position = data.Vertices[i].design + data.PlateDesignPosition;
|
||||
// positions.Add(position);
|
||||
// }
|
||||
// if (data.isReversal) { positions.Reverse(); }
|
||||
// return positions;
|
||||
// }
|
||||
// private List<Vector3> VertexToBakingPositions(DataSutureSide data) {
|
||||
// //转换列表
|
||||
// List<Vector3> positions = new List<Vector3>();
|
||||
// for (int i = 0; i < data.Vertices.Length; i++) {
|
||||
// Quaternion quaternion = Quaternion.Euler(data.PlateBakingEulerAngles);
|
||||
// Vector3 baking = quaternion * data.Vertices[i].design;
|
||||
// Vector3 position = baking + data.PlateBakingPosition;
|
||||
// positions.Add(position);
|
||||
// }
|
||||
// if (data.isReversal) { positions.Reverse(); }
|
||||
// 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;
|
||||
|
||||
public override void Add(DataPlate data) {
|
||||
if (dataPlates.Contains(data)) { return; }
|
||||
dataPlates.Add(data);
|
||||
public override void Add(DataPlate plate) {
|
||||
if (dataPlates.Contains(plate)) { return; }
|
||||
dataPlates.Add(plate);
|
||||
//初始化参数
|
||||
data.designPosition = ViewCameraDesign.CameraPosition;
|
||||
data.bakingPosition = ViewCameraDesign.CameraPosition;
|
||||
plate.dataDesign.position = ViewCameraDesign.CameraPosition;
|
||||
plate.dataBaking.position = ViewCameraDesign.CameraPosition;
|
||||
//生成可视化内容
|
||||
data.UpdateVisual();
|
||||
plate.UpdateVisual();
|
||||
}
|
||||
public override void Remove(DataPlate data) {
|
||||
if (!dataPlates.Contains(data)) { return; }
|
||||
|
||||
@@ -5,37 +5,37 @@ using UnityEngine;
|
||||
/// <summary>
|
||||
/// 插入点(DataInsertPoint) 转换 点(DataPoint)
|
||||
/// </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) {
|
||||
DataPlate plate = insertPoint.plate;
|
||||
Vector3 position = insertPoint.position;
|
||||
//创建新的点
|
||||
DataPoint point = new DataPoint(insertPoint.plate);
|
||||
point.position = position;
|
||||
//改变关联的边B点,重置贝塞尔曲线
|
||||
insertPoint.side.bPoint = point;
|
||||
insertPoint.side.OneRankBezier();
|
||||
//创建新的边
|
||||
DataSide side = CreateDataSide(plate, point, insertPoint.bPoint);
|
||||
//插入边
|
||||
int sideIndex = plate.sides.IndexOf(insertPoint.side);
|
||||
plate.sides.Insert(sideIndex + 1, side);
|
||||
//插入点
|
||||
int pointIndex = plate.points.IndexOf(insertPoint.aPoint);
|
||||
plate.points.Insert(pointIndex + 1, point);
|
||||
//更新数据
|
||||
plate.UpdateVisual();
|
||||
return point;
|
||||
}
|
||||
// public override DataPoint To(DataInsertPoint insertPoint) {
|
||||
// DataPlate plate = insertPoint.plate;
|
||||
// Vector3 position = insertPoint.position;
|
||||
// //创建新的点
|
||||
// DataPoint point = new DataPoint(insertPoint.plate);
|
||||
// point.position = position;
|
||||
// //改变关联的边B点,重置贝塞尔曲线
|
||||
// insertPoint.side.bPoint = point;
|
||||
// insertPoint.side.OneRankBezier();
|
||||
// //创建新的边
|
||||
// DataSide side = CreateDataSide(plate, point, insertPoint.bPoint);
|
||||
// //插入边
|
||||
// int sideIndex = plate.sides.IndexOf(insertPoint.side);
|
||||
// plate.sides.Insert(sideIndex + 1, side);
|
||||
// //插入点
|
||||
// int pointIndex = plate.points.IndexOf(insertPoint.aPoint);
|
||||
// plate.points.Insert(pointIndex + 1, point);
|
||||
// //更新数据
|
||||
// plate.UpdateVisual();
|
||||
// return point;
|
||||
// }
|
||||
|
||||
private DataSide CreateDataSide(DataPlate plate, DataPoint a, DataPoint b) {
|
||||
DataSide side = new DataSide(plate);
|
||||
side.aPoint = a;
|
||||
side.bPoint = b;
|
||||
side.OneRankBezier();
|
||||
return side;
|
||||
}
|
||||
}
|
||||
// private DataSide CreateDataSide(DataPlate plate, DataPoint a, DataPoint b) {
|
||||
// DataSide side = new DataSide(plate);
|
||||
// side.aPoint = a;
|
||||
// side.bPoint = b;
|
||||
// side.OneRankBezier();
|
||||
// return side;
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -11,24 +11,24 @@ public class BuilderPlatePresetsToPlate : ModuleBuilder<DataPlatePresets, DataPl
|
||||
|
||||
public override DataPlate To(DataPlatePresets origin) {
|
||||
DataPlate dataPlate = new DataPlate();
|
||||
dataPlate.points = ToDataPoint(dataPlate, origin.designPoints);
|
||||
dataPlate.sides = ToDataSide(dataPlate, dataPlate.points);
|
||||
dataPlate.platePoints = ToDataPoint(dataPlate, origin.designPoints);
|
||||
dataPlate.plateSides = ToDataSide(dataPlate, dataPlate.platePoints);
|
||||
return dataPlate;
|
||||
}
|
||||
|
||||
private List<DataPoint> ToDataPoint(DataPlate dataPlate, List<Vector3> list) {
|
||||
List<DataPoint> points = new List<DataPoint>();
|
||||
private List<DataPlatePoint> ToDataPoint(DataPlate dataPlate, List<Vector3> list) {
|
||||
List<DataPlatePoint> points = new List<DataPlatePoint>();
|
||||
for (int i = 0; i < list.Count; i++) {
|
||||
DataPoint point = new DataPoint(dataPlate);
|
||||
DataPlatePoint point = new DataPlatePoint(dataPlate);
|
||||
point.position = list[i];
|
||||
points.Add(point);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
private List<DataSide> ToDataSide(DataPlate dataPlate, List<DataPoint> list) {
|
||||
List<DataSide> sides = new List<DataSide>();
|
||||
private List<DataPlateSide> ToDataSide(DataPlate dataPlate, List<DataPlatePoint> list) {
|
||||
List<DataPlateSide> sides = new List<DataPlateSide>();
|
||||
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.bPoint = list.LoopIndex(i + 1);
|
||||
side.OneRankBezier();
|
||||
|
||||
@@ -46,37 +46,37 @@ public class ModuleCore : Module<ModuleCore> {
|
||||
public ModuleBuilder<DataPlatePresets, DataPlate> PlatePresetsToPlate;
|
||||
/// <summary> 板片数据(DataPlate) 转换 多边形数据(DataPolygon) </summary>
|
||||
public ModuleBuilder<DataPlate, DataPolygon> PlateToPolygon;
|
||||
/// <summary> 插入点(DataInsertPoint) 转换 点(DataPoint) </summary>
|
||||
public ModuleBuilder<DataInsertPoint, DataPoint> InsertPointToPoint;
|
||||
#endregion
|
||||
|
||||
#region 可视模块
|
||||
/// <summary> 设计可视化内容生成模块 </summary>
|
||||
public ModuleVisual<DataPlate> VisualDesign;
|
||||
/// <summary> 烘焙可视化内容生成模块 </summary>
|
||||
public ModuleVisual<DataPlate> VisualBaking;
|
||||
/// <summary> 连接可视化内容生成模块 </summary>
|
||||
/// <summary> 板片设计 可视化内容生成模块 </summary>
|
||||
public ModuleVisual<DataPlate> VisualPlateDesign;
|
||||
/// <summary> 板片烘焙 可视化内容生成模块 </summary>
|
||||
public ModuleVisual<DataPlate> VisualPlateBaking;
|
||||
/// <summary> 缝合设计 可视化内容生成模块 </summary>
|
||||
public ModuleVisual<DataSuture> VisualSutureDesign;
|
||||
/// <summary> 缝合烘焙 可视化内容生成模块 </summary>
|
||||
public ModuleVisual<DataSuture> VisualSutureBaking;
|
||||
/// <summary> 连接器 可视化内容生成模块 </summary>
|
||||
public ModuleVisual<DataConnector> VisualConnector;
|
||||
#endregion
|
||||
|
||||
#region 查询模块
|
||||
/// <summary> 查询点模块 </summary>
|
||||
public ModuleFind<DataPoint> FindPoint;
|
||||
public ModuleFind<DataPlatePoint> FindPoint;
|
||||
/// <summary> 查询边模块 </summary>
|
||||
public ModuleFind<DataSide> FindSide;
|
||||
public ModuleFind<DataPlateSide> FindSide;
|
||||
/// <summary> 查询贝塞尔点模块 </summary>
|
||||
public ModuleFind<DataBezier> FindBezier;
|
||||
#endregion
|
||||
|
||||
#region 算法模块
|
||||
/// <summary> 计算位置到边上最近的点 </summary>
|
||||
public ModuleAlgorithm<DataIntersect> AlgorithmSidePoint;
|
||||
/// <summary> 简单多边形算法模块 </summary>
|
||||
public ModuleAlgorithm<DataPlate> AlgorithmSimplePolygon;
|
||||
/// <summary> 细分多边形算法模块 </summary>
|
||||
public ModuleAlgorithm<DataPlate> AlgorithmSubdivisionPolygon;
|
||||
/// <summary> 缝合边算法模块 </summary>
|
||||
public ModuleAlgorithm<DataSutureSide> AlgorithmSutureSide;
|
||||
public ModuleAlgorithm<DataSuture> AlgorithmSuture;
|
||||
#endregion
|
||||
|
||||
#region 事件定义
|
||||
|
||||
@@ -15,7 +15,7 @@ public class FindBezier : ModuleFind<DataBezier> {
|
||||
public override bool Find(Vector3 position, out DataBezier bezier) {
|
||||
List<DataPlate> plates = AssetsPlate.Datas;
|
||||
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);
|
||||
if (bezier != null) { return true; }
|
||||
}
|
||||
@@ -24,14 +24,14 @@ public class FindBezier : ModuleFind<DataBezier> {
|
||||
|
||||
/// <summary> 查询匹配的边 </summary>
|
||||
private DataBezier Find(DataPlate plate, Vector3 localPosition) {
|
||||
for (int i = 0; i < plate.sides.Count; i++) {
|
||||
DataBezier bezier = Find(plate.sides[i], localPosition);
|
||||
for (int i = 0; i < plate.plateSides.Count; i++) {
|
||||
DataBezier bezier = Find(plate.plateSides[i], localPosition);
|
||||
if (bezier != null) { return bezier; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary> 查询匹配的边 </summary>
|
||||
private DataBezier Find(DataSide side, Vector3 localPosition) {
|
||||
private DataBezier Find(DataPlateSide side, Vector3 localPosition) {
|
||||
if (side.bezier == Bezier.一阶) { return null; }
|
||||
float aDis = Vector3.Distance(side.aBezier, localPosition);
|
||||
if (aDis < FindRange) { return new DataBezier() { isA = true, side = side }; }
|
||||
|
||||
@@ -5,17 +5,17 @@ using UnityEngine;
|
||||
/// <summary>
|
||||
/// 查找点
|
||||
/// </summary>
|
||||
public class FindPoint : ModuleFind<DataPoint> {
|
||||
public class FindPoint : ModuleFind<DataPlatePoint> {
|
||||
public readonly float FindRange = 0.01f;
|
||||
/// <summary> 板片资产 </summary>
|
||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||
|
||||
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;
|
||||
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);
|
||||
if (point != null) { return true; }
|
||||
}
|
||||
@@ -23,8 +23,8 @@ public class FindPoint : ModuleFind<DataPoint> {
|
||||
}
|
||||
|
||||
/// <summary> 查询匹配的点 </summary>
|
||||
private DataPoint Find(DataPlate plate, Vector3 localPosition) {
|
||||
List<DataPoint> points = plate.points;
|
||||
private DataPlatePoint Find(DataPlate plate, Vector3 localPosition) {
|
||||
List<DataPlatePoint> points = plate.platePoints;
|
||||
for (int i = 0; i < points.Count; i++) {
|
||||
float distance = Vector3.Distance(points[i].position, localPosition);
|
||||
if (distance > FindRange) { continue; }
|
||||
|
||||
@@ -5,17 +5,17 @@ using UnityEngine;
|
||||
/// <summary>
|
||||
/// 查找边
|
||||
/// </summary>
|
||||
public class FindSide : ModuleFind<DataSide> {
|
||||
public class FindSide : ModuleFind<DataPlateSide> {
|
||||
public readonly float FindRange = 0.01f;
|
||||
/// <summary> 板片资产 </summary>
|
||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||
|
||||
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;
|
||||
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);
|
||||
if (side != null) { return true; }
|
||||
}
|
||||
@@ -23,20 +23,20 @@ public class FindSide : ModuleFind<DataSide> {
|
||||
}
|
||||
|
||||
/// <summary> 查询匹配的边 </summary>
|
||||
private DataSide Find(DataPlate plate, Vector3 localPosition) {
|
||||
for (int i = 0; i < plate.sides.Count; i++) {
|
||||
DataSide side = Find(plate.sides[i], localPosition);
|
||||
private DataPlateSide Find(DataPlate plate, Vector3 localPosition) {
|
||||
for (int i = 0; i < plate.plateSides.Count; i++) {
|
||||
DataPlateSide side = Find(plate.plateSides[i], localPosition);
|
||||
if (side != null) { return side; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary> 查询匹配的边 </summary>
|
||||
private DataSide Find(DataSide side, Vector3 localPosition) {
|
||||
for (int i = 0; i < side.lines.Length; i++) {
|
||||
Vector3 a = side.lines[i].a;
|
||||
Vector3 b = side.lines[i].b;
|
||||
private DataPlateSide Find(DataPlateSide side, Vector3 localPosition) {
|
||||
DataPlateSideDesign design = side.dataDesign;
|
||||
for (int i = 0; i < design.lines.Length; i++) {
|
||||
Vector3 a = design.lines[i].a;
|
||||
Vector3 b = design.lines[i].b;
|
||||
float distance = ProjectDistance(a, b, localPosition);
|
||||
//Debug.Log($"{a} , {b} , {localPosition}");
|
||||
if (distance < FindRange) { return side; }
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -2,45 +2,45 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class VisualBaking : ModuleVisual<DataPlate> {
|
||||
public Transform viewSpace;
|
||||
public Transform platePrefab;//板片
|
||||
public Transform suturePrefab;//缝合
|
||||
public Transform sutureSidePrefab;//缝合边
|
||||
//public class VisualBaking : ModuleVisual<DataPlate> {
|
||||
// public Transform viewSpace;
|
||||
// public Transform platePrefab;//板片
|
||||
// public Transform suturePrefab;//缝合
|
||||
// public Transform sutureSidePrefab;//缝合边
|
||||
|
||||
protected override void Awake() => ModuleCore.VisualBaking = this;
|
||||
// protected override void Awake() => ModuleCore.VisualBaking = this;
|
||||
|
||||
public override void UpdateVisual(DataPlate plate) {
|
||||
//更新板片
|
||||
Create(ref plate.baking, platePrefab, viewSpace);
|
||||
plate.baking.UpdateVisual(plate);
|
||||
//子数据父对象
|
||||
Transform parent = plate.design.transform;
|
||||
//更新线段
|
||||
plate.sides.ForEach(obj => UpdateVisual(obj, parent));
|
||||
}
|
||||
public override void ReleaseVisual(DataPlate data) {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
// public override void UpdateVisual(DataPlate plate) {
|
||||
// //更新板片
|
||||
// Create(ref plate.baking, platePrefab, viewSpace);
|
||||
// plate.baking.UpdateVisual(plate);
|
||||
// //子数据父对象
|
||||
// Transform parent = plate.design.transform;
|
||||
// //更新线段
|
||||
// plate.sides.ForEach(obj => UpdateVisual(obj, parent));
|
||||
// }
|
||||
// public override void ReleaseVisual(DataPlate data) {
|
||||
// throw new System.NotImplementedException();
|
||||
// }
|
||||
|
||||
private void UpdateVisual(DataSide 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);
|
||||
}
|
||||
}
|
||||
// private void UpdateVisual(DataSide 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);
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -5,53 +5,53 @@ using UnityEngine;
|
||||
/// <summary>
|
||||
/// 版片可视化模块
|
||||
/// </summary>
|
||||
public class VisualDesign : ModuleVisual<DataPlate> {
|
||||
public Transform viewSpace;
|
||||
public Transform platePrefab;//板片
|
||||
public Transform pointPrefab;//点
|
||||
public Transform sidePrefab;//边
|
||||
public Transform suturePrefab;//缝合
|
||||
public Transform sutureSidePrefab;//缝合边
|
||||
//public class VisualDesign : ModuleVisual<DataPlate> {
|
||||
// public Transform viewSpace;
|
||||
// public Transform platePrefab;//板片
|
||||
// public Transform pointPrefab;//点
|
||||
// public Transform sidePrefab;//边
|
||||
// public Transform suturePrefab;//缝合
|
||||
// public Transform sutureSidePrefab;//缝合边
|
||||
|
||||
protected override void Awake() => ModuleCore.VisualDesign = this;
|
||||
// protected override void Awake() => ModuleCore.VisualDesign = this;
|
||||
|
||||
public override void UpdateVisual(DataPlate plate) {
|
||||
//更新板片
|
||||
Create(ref plate.design, platePrefab, viewSpace);
|
||||
plate.design.UpdateVisual(plate);
|
||||
//子数据父对象
|
||||
Transform parent = plate.design.transform;
|
||||
//更新点
|
||||
plate.points.ForEach(obj => UpdateVisual(obj, parent));
|
||||
//更新线段
|
||||
plate.sides.ForEach(obj => UpdateVisual(obj, parent));
|
||||
}
|
||||
public override void ReleaseVisual(DataPlate data) {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
// public override void UpdateVisual(DataPlate plate) {
|
||||
// //更新板片
|
||||
// Create(ref plate.design, platePrefab, viewSpace);
|
||||
// plate.design.UpdateVisual(plate);
|
||||
// //子数据父对象
|
||||
// Transform parent = plate.design.transform;
|
||||
// //更新点
|
||||
// plate.points.ForEach(obj => UpdateVisual(obj, parent));
|
||||
// //更新线段
|
||||
// plate.sides.ForEach(obj => UpdateVisual(obj, parent));
|
||||
// }
|
||||
// public override void ReleaseVisual(DataPlate data) {
|
||||
// throw new System.NotImplementedException();
|
||||
// }
|
||||
|
||||
private void UpdateVisual(DataPoint point, Transform parent) {
|
||||
Create(ref point.visual, pointPrefab, parent);
|
||||
point.visual.UpdateVisual(point);
|
||||
}
|
||||
private void UpdateVisual(DataSide 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.design, suturePrefab, parent);
|
||||
UpdateVisual(suture.a, suture.design.transform);
|
||||
UpdateVisual(suture.b, suture.design.transform);
|
||||
suture.design.UpdateVisual(suture);
|
||||
}
|
||||
/// <summary> 更新缝合边 </summary>
|
||||
private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
||||
Create(ref sutureSide.design, sutureSidePrefab, parent);
|
||||
sutureSide.design.UpdateVisual(sutureSide);
|
||||
}
|
||||
}
|
||||
// private void UpdateVisual(DataPoint point, Transform parent) {
|
||||
// Create(ref point.visual, pointPrefab, parent);
|
||||
// point.visual.UpdateVisual(point);
|
||||
// }
|
||||
// private void UpdateVisual(DataSide 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.design, suturePrefab, parent);
|
||||
// UpdateVisual(suture.a, suture.design.transform);
|
||||
// UpdateVisual(suture.b, suture.design.transform);
|
||||
// suture.design.UpdateVisual(suture);
|
||||
// }
|
||||
// /// <summary> 更新缝合边 </summary>
|
||||
// private void UpdateVisual(DataSutureSide sutureSide, Transform parent) {
|
||||
// Create(ref sutureSide.design, sutureSidePrefab, parent);
|
||||
// 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>
|
||||
public bool isA;
|
||||
/// <summary> 关联的边 </summary>
|
||||
public DataSide side;
|
||||
public DataPlateSide side;
|
||||
/// <summary> 位置 </summary>
|
||||
public Vector3 position => isA ? side.aBezier : side.bBezier;
|
||||
|
||||
|
||||
@@ -2,21 +2,34 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary> 2D边界数据 </summary>
|
||||
/// <summary> 边界数据 </summary>
|
||||
public class DataBorder {
|
||||
/// <summary> 网格细分 </summary>
|
||||
public readonly float smooth = 0.01f;
|
||||
/// <summary> minX </summary>
|
||||
public readonly float minX = 0;
|
||||
/// <summary> maxX </summary>
|
||||
public readonly float maxX = 0;
|
||||
/// <summary> minY </summary>
|
||||
public readonly float minY = 0;
|
||||
/// <summary> maxY </summary>
|
||||
public readonly float maxY = 0;
|
||||
/// <summary> 2D边界数据 </summary>
|
||||
public DataBorder(float minX, float maxX, float minY, float maxY) {
|
||||
/// <summary> 多边形边缘点 </summary>
|
||||
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.minY = minY; this.maxY = maxY;
|
||||
this.points = points;
|
||||
}
|
||||
/// <summary> 边界宽 </summary>
|
||||
public float Wide => maxX - minX;
|
||||
/// <summary> 边界高 </summary>
|
||||
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>
|
||||
public Vector3 MinPoint => new Vector3(minX, minY, 0);
|
||||
/// <summary> 最大点 </summary>
|
||||
|
||||
@@ -7,18 +7,22 @@ public class DataPlate {
|
||||
/// <summary> 核心模块 </summary>
|
||||
private ModuleCore ModuleCore => ModuleCore.I;
|
||||
/// <summary> 设计可视化模块 </summary>
|
||||
private ModuleVisual<DataPlate> VisualDesign => ModuleCore.VisualDesign;
|
||||
private ModuleVisual<DataPlate> VisualDesign => ModuleCore.VisualPlateDesign;
|
||||
/// <summary> 烘焙可视化模块 </summary>
|
||||
private ModuleVisual<DataPlate> VisualBaking => ModuleCore.VisualBaking;
|
||||
private ModuleVisual<DataPlate> VisualBaking => ModuleCore.VisualPlateBaking;
|
||||
/// <summary> 简单多边形算法模块 </summary>
|
||||
private ModuleAlgorithm<DataPlate> AlgorithmSimplePolygon => ModuleCore.AlgorithmSimplePolygon;
|
||||
/// <summary> 细分多边形算法模块 </summary>
|
||||
private ModuleAlgorithm<DataPlate> AlgorithmSubdivisionPolygon => ModuleCore.AlgorithmSubdivisionPolygon;
|
||||
|
||||
public DataPlate() {
|
||||
dataDesign = new DataPlateDesign(this);
|
||||
}
|
||||
|
||||
public void UpdateVisual(bool recalculate = true) {
|
||||
if (recalculate) {
|
||||
//简单多边形计算
|
||||
//AlgorithmSimplePolygon.Compute(this);
|
||||
AlgorithmSimplePolygon.Compute(this);
|
||||
//细分多边形计算
|
||||
AlgorithmSubdivisionPolygon.Compute(this);
|
||||
}
|
||||
@@ -29,42 +33,55 @@ public class DataPlate {
|
||||
}
|
||||
|
||||
#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>
|
||||
public List<DataPoint> points = new List<DataPoint>();
|
||||
public List<DataPlatePoint> platePoints = new List<DataPlatePoint>();
|
||||
/// <summary> 边 </summary>
|
||||
public List<DataSide> sides = new List<DataSide>();
|
||||
public List<DataPlateSide> plateSides = new List<DataPlateSide>();
|
||||
#endregion
|
||||
|
||||
#region 次要数据
|
||||
/// <summary> 边界数据 </summary>
|
||||
public DataBorder border;
|
||||
/// <summary> 边缘点 </summary>
|
||||
public List<Vector3> edgePoints;
|
||||
/// <summary> 设计网格 </summary>
|
||||
public Mesh designMesh;
|
||||
|
||||
/// <summary> 三角形数据 </summary>
|
||||
public List<DataTriangle> triangles;
|
||||
|
||||
/// <summary> 顶点网格 </summary>
|
||||
public GridTool<DataVertex> vertexGrid;
|
||||
/// <summary> 设计缓存数据 </summary>
|
||||
public DataPlateDesign dataDesign;
|
||||
/// <summary> 烘焙缓存数据 </summary>
|
||||
public DataPlateBaking dataBaking = new DataPlateBaking();
|
||||
#endregion
|
||||
|
||||
#region 可视化数据
|
||||
/// <summary> 可视化对象 </summary>
|
||||
public ModulePrefab<DataPlate> design;
|
||||
public ModulePrefab<DataPlate> designPrefab;
|
||||
/// <summary> 可视化对象 </summary>
|
||||
public ModulePrefab<DataPlate> baking;
|
||||
public ModulePrefab<DataPlate> bakingPrefab;
|
||||
/// <summary> 安排点 </summary>
|
||||
public FixedArrange arrange;
|
||||
#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 UnityEngine;
|
||||
|
||||
public enum Bezier {
|
||||
一阶 = 0, 二阶 = 1, 三阶 = 2
|
||||
}
|
||||
//public enum Bezier {
|
||||
// 一阶 = 0, 二阶 = 1, 三阶 = 2
|
||||
//}
|
||||
public class DataSide {
|
||||
/// <summary> 绑定的板片 </summary>
|
||||
public readonly DataPlate plate;
|
||||
|
||||
@@ -5,24 +5,33 @@ using UnityEngine;
|
||||
public class DataSuture {
|
||||
/// <summary> 核心模块 </summary>
|
||||
private ModuleCore ModuleCore => ModuleCore.I;
|
||||
/// <summary> 简单多边形算法模块 </summary>
|
||||
private ModuleAlgorithm<DataSutureSide> AlgorithmSutureSide => ModuleCore.AlgorithmSutureSide;
|
||||
/// <summary> 设计可视化模块 </summary>
|
||||
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 b;
|
||||
public DataSuture(DataSide aSide, DataSide bSide) {
|
||||
public DataSuture(DataPlateSide aSide, DataPlateSide bSide) {
|
||||
a = new DataSutureSide(aSide, this);
|
||||
b = new DataSutureSide(bSide, this);
|
||||
Update();
|
||||
UpdateVisual();
|
||||
}
|
||||
|
||||
public void Update() {
|
||||
AlgorithmSutureSide.Compute(a);
|
||||
AlgorithmSutureSide.Compute(b);
|
||||
public void UpdateVisual() {
|
||||
AlgorithmSuture.Compute(this);
|
||||
VisualDesign.UpdateVisual(this);
|
||||
VisualBaking.UpdateVisual(this);
|
||||
}
|
||||
|
||||
#region 次要数据
|
||||
/// <summary> 缝合长度 </summary>
|
||||
public float length => this.SutureLength();
|
||||
public float length;
|
||||
/// <summary> 缝合点 </summary>
|
||||
public List<DataSuturePoint> points;
|
||||
#endregion
|
||||
|
||||
#region 可视化内容
|
||||
/// <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>
|
||||
public class DataSutureSide {
|
||||
/// <summary> 关联的边 </summary>
|
||||
public readonly DataSide side;
|
||||
public readonly DataPlateSide plateSide;
|
||||
/// <summary> 关联的缝合数据 </summary>
|
||||
public readonly DataSuture suture;
|
||||
/// <summary> 缝合边 </summary>
|
||||
public DataSutureSide(DataSide side, DataSuture suture) {
|
||||
this.side = side;
|
||||
public DataSutureSide(DataPlateSide side, DataSuture suture) {
|
||||
this.plateSide = side;
|
||||
this.suture = suture;
|
||||
}
|
||||
|
||||
@@ -22,32 +22,10 @@ public class DataSutureSide {
|
||||
#endregion
|
||||
|
||||
#region 次要数据
|
||||
|
||||
/// <summary> 边最大长度 </summary>
|
||||
public float MaxLength => side.length;
|
||||
/// <summary> 边缘顶点数据 </summary>
|
||||
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];
|
||||
|
||||
/// <summary> 设计缓存数据 </summary>
|
||||
public DataSutureSideDesign dataDesign = new DataSutureSideDesign();
|
||||
/// <summary> 烘焙缓存数据 </summary>
|
||||
public DataSutureSideBaking dataBaking = new DataSutureSideBaking();
|
||||
#endregion
|
||||
|
||||
#region 可视化数据
|
||||
@@ -57,3 +35,43 @@ public class DataSutureSide {
|
||||
public ModulePrefab<DataSutureSide> baking;
|
||||
#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 b;
|
||||
public Vector3 c;
|
||||
|
||||
public override string ToString() {
|
||||
return $"{a} , {b} , {c}";
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ public class PrefabPlateBaking : ModulePrefab<DataPlate> {
|
||||
|
||||
public override void UpdateVisual(DataPlate plate) {
|
||||
this.plate = plate;
|
||||
transform.localPosition = plate.bakingPosition;
|
||||
transform.localEulerAngles = plate.bakingEulerAngles;
|
||||
|
||||
meshFilter.mesh = plate.designMesh;
|
||||
meshCollider.sharedMesh = plate.designMesh;
|
||||
DataPlateBaking baking = plate.dataBaking;
|
||||
//transform.localPosition = baking.position;
|
||||
//transform.localEulerAngles = baking.eulerAngles;
|
||||
meshFilter.mesh = baking.mesh;
|
||||
meshCollider.sharedMesh = baking.mesh;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,10 @@ public class PrefabPlateDesign : ModulePrefab<DataPlate> {
|
||||
|
||||
public override void UpdateVisual(DataPlate plate) {
|
||||
this.plate = plate;
|
||||
transform.localPosition = plate.designPosition;
|
||||
meshFilter.mesh = plate.designMesh;
|
||||
meshCollider.sharedMesh = plate.designMesh;
|
||||
DataPlateDesign design = plate.dataDesign;
|
||||
transform.localPosition = design.position;
|
||||
meshFilter.mesh = design.mesh;
|
||||
meshCollider.sharedMesh = design.mesh;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class PrefabPoint : ModulePrefab<DataPoint> {
|
||||
private DataPoint point;
|
||||
public class PrefabPoint : ModulePrefab<DataPlatePoint> {
|
||||
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;
|
||||
transform.localPosition = point.position;
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class PrefabSide : ModulePrefab<DataSide> {
|
||||
public class PrefabSide : ModulePrefab<DataPlateSide> {
|
||||
public Transform aPoint;
|
||||
public Transform bPoint;
|
||||
public LineRenderer lineRenderer;
|
||||
public LineRenderer aBezier;
|
||||
public LineRenderer bBezier;
|
||||
private DataSide side;
|
||||
private DataPlateSide side;
|
||||
|
||||
#region 引用模块
|
||||
/// <summary> 设计UI输入模块 </summary>
|
||||
public ModuleUIInput<UnitMouseInput> UIInputDesign => ModuleCore.I.UIInputDesign;
|
||||
#endregion
|
||||
|
||||
public override DataSide Value => side;
|
||||
public override DataPlateSide Value => side;
|
||||
|
||||
private void Awake() {
|
||||
UIInputDesign.OnChangeInput += UIInputDesign_OnChangeInput;
|
||||
@@ -34,11 +34,12 @@ public class PrefabSide : ModulePrefab<DataSide> {
|
||||
aBezier.gameObject.SetActive(false);
|
||||
bBezier.gameObject.SetActive(false);
|
||||
}
|
||||
public override void UpdateVisual(DataSide side) {
|
||||
public override void UpdateVisual(DataPlateSide side) {
|
||||
this.side = side;
|
||||
|
||||
lineRenderer.positionCount = side.positions.Length;
|
||||
lineRenderer.SetPositions(side.positions);
|
||||
DataPlateSideDesign design = side.dataDesign;
|
||||
lineRenderer.positionCount = design.positions.Length;
|
||||
lineRenderer.SetPositions(design.positions);
|
||||
|
||||
Type type = UIInputDesign.Current.GetType();
|
||||
if (type != typeof(DesignBezier)) { ActiveGameObject(false); return; }
|
||||
|
||||
@@ -14,10 +14,12 @@ public class PrefabSutureBaking : ModulePrefab<DataSuture> {
|
||||
public override void UpdateVisual(DataSuture suture) {
|
||||
this.suture = suture;
|
||||
|
||||
aLineRenderer.SetPosition(0, suture.a.BakingPosintA);
|
||||
aLineRenderer.SetPosition(1, suture.b.BakingPosintA);
|
||||
DataSutureSideBaking aBaking = suture.a.dataBaking;
|
||||
DataSutureSideBaking bBaking = suture.b.dataBaking;
|
||||
aLineRenderer.SetPosition(0, aBaking.PointA);
|
||||
aLineRenderer.SetPosition(1, bBaking.PointA);
|
||||
|
||||
bLineRenderer.SetPosition(0, suture.a.BakingPosintB);
|
||||
bLineRenderer.SetPosition(1, suture.b.BakingPosintB);
|
||||
bLineRenderer.SetPosition(0, aBaking.PointB);
|
||||
bLineRenderer.SetPosition(1, bBaking.PointB);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,12 @@ public class PrefabSutureDesign : ModulePrefab<DataSuture> {
|
||||
public override void UpdateVisual(DataSuture suture) {
|
||||
this.suture = suture;
|
||||
|
||||
aLineRenderer.SetPosition(0, suture.a.DesignPosintA);
|
||||
aLineRenderer.SetPosition(1, suture.b.DesignPosintA);
|
||||
DataSutureSideDesign aDesign = suture.a.dataDesign;
|
||||
DataSutureSideDesign bDesign = suture.b.dataDesign;
|
||||
aLineRenderer.SetPosition(0, aDesign.PointA);
|
||||
aLineRenderer.SetPosition(1, bDesign.PointA);
|
||||
|
||||
bLineRenderer.SetPosition(0, suture.a.DesignPosintB);
|
||||
bLineRenderer.SetPosition(1, suture.b.DesignPosintB);
|
||||
bLineRenderer.SetPosition(0, aDesign.PointB);
|
||||
bLineRenderer.SetPosition(1, bDesign.PointB);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ public class PrefabSutureSideBaking : ModulePrefab<DataSutureSide> {
|
||||
public override void UpdateVisual(DataSutureSide sutureSide) {
|
||||
this.sutureSide = sutureSide;
|
||||
|
||||
lineRenderer.positionCount = sutureSide.bakingPositions.Length;
|
||||
lineRenderer.SetPositions(sutureSide.bakingPositions);
|
||||
DataSutureSideBaking baking = sutureSide.dataBaking;
|
||||
lineRenderer.positionCount = baking.positions.Length;
|
||||
lineRenderer.SetPositions(baking.positions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ public class PrefabSutureSideDesign : ModulePrefab<DataSutureSide> {
|
||||
public override void UpdateVisual(DataSutureSide sutureSide) {
|
||||
this.sutureSide = sutureSide;
|
||||
|
||||
lineRenderer.positionCount = sutureSide.designPositions.Length;
|
||||
lineRenderer.SetPositions(sutureSide.designPositions);
|
||||
DataSutureSideDesign design = sutureSide.dataDesign;
|
||||
lineRenderer.positionCount = design.positions.Length;
|
||||
lineRenderer.SetPositions(design.positions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,30 +3,30 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
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.二阶) { side.bBezier = 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.二阶) { side.aBezier = position; }
|
||||
side.bBezier = position;
|
||||
}
|
||||
public static void OneRankBezier(this DataSide side) {
|
||||
public static void OneRankBezier(this DataPlateSide side) {
|
||||
side.bezier = Bezier.一阶;
|
||||
}
|
||||
public static void TwoRankBezier(this DataSide side) {
|
||||
public static void TwoRankBezier(this DataPlateSide side) {
|
||||
side.bezier = Bezier.二阶;
|
||||
DataPoint a = side.aPoint;
|
||||
DataPoint b = side.bPoint;
|
||||
DataPlatePoint a = side.aPoint;
|
||||
DataPlatePoint b = side.bPoint;
|
||||
side.aBezier = 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.三阶;
|
||||
DataPoint a = side.aPoint;
|
||||
DataPoint b = side.bPoint;
|
||||
DataPlatePoint a = side.aPoint;
|
||||
DataPlatePoint b = side.bPoint;
|
||||
side.aBezier = a.position + (b.position - a.position) * 0.3f;
|
||||
side.bBezier = a.position + (b.position - a.position) * 0.7f;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public static class DataSutureTool {
|
||||
public static float SutureLength(this DataSuture suture) {
|
||||
if (suture.a.MaxLength < suture.b.MaxLength) {
|
||||
return suture.a.MaxLength;
|
||||
}
|
||||
else { return suture.b.MaxLength; }
|
||||
}
|
||||
//public static float SutureLength(this DataSuture suture) {
|
||||
// if (suture.a.MaxLength < suture.b.MaxLength) {
|
||||
// return suture.a.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>
|
||||
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 float smooth;
|
||||
@@ -22,69 +48,28 @@ public class UnitAlgorithmBezier : UnitAlgorithm<DataPlate> {
|
||||
//输出
|
||||
public float length;
|
||||
public List<Vector3> positions = new List<Vector3>();
|
||||
public List<DataLine> lines = new List<DataLine>();
|
||||
}
|
||||
|
||||
public void Compute(DataPlate data) {
|
||||
List<Vector3> points = new List<Vector3>();
|
||||
for (int i = 0; i < data.sides.Count; i++) {
|
||||
Compute(data.sides[i]);
|
||||
points.AddRange(data.sides[i].positions);
|
||||
}
|
||||
//去除重复边缘点
|
||||
points = points.Distinct().ToList();
|
||||
data.edgePoints = points;
|
||||
}
|
||||
public void Compute(DataSide 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;
|
||||
|
||||
Compute(dataBezier);
|
||||
|
||||
data.length = dataBezier.length;
|
||||
data.positions = dataBezier.positions.ToArray();
|
||||
data.lines = dataBezier.lines.ToArray();
|
||||
}
|
||||
|
||||
public List<DataPlateLine> lines = new List<DataPlateLine>();
|
||||
/// <summary> 计算曲线细分点 </summary>
|
||||
private void Compute(DataBezier data) {
|
||||
public void Compute() {
|
||||
//细分点
|
||||
if (data.bezier == Bezier.一阶) {
|
||||
data.positions = Compute(data.aPoint, data.bPoint);
|
||||
}
|
||||
if (data.bezier == Bezier.二阶) {
|
||||
data.positions = Compute(data.aPoint, data.aBezier, data.bPoint, data.smooth);
|
||||
}
|
||||
if (data.bezier == Bezier.三阶) {
|
||||
data.positions = Compute(data.aPoint, data.aBezier, data.bBezier, data.bPoint, data.smooth);
|
||||
}
|
||||
if (bezier == Bezier.一阶) { positions = new List<Vector3> { aPoint, bPoint }; }
|
||||
if (bezier == Bezier.二阶) { positions = Compute(aPoint, aBezier, bPoint); }
|
||||
if (bezier == Bezier.三阶) { positions = Compute(aPoint, aBezier, bBezier, bPoint); }
|
||||
//线段
|
||||
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;
|
||||
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>
|
||||
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) {
|
||||
private List<Vector3> Compute(Vector3 a, Vector3 b, Vector3 c) {
|
||||
List<Vector3> points = new List<Vector3>();
|
||||
//方向,距离
|
||||
Vector2 direction = (c - a).normalized;
|
||||
float distance = Vector2.Distance(c, a);
|
||||
//求余,得商数
|
||||
int quotient = Quotient(distance, smooth);
|
||||
@@ -98,7 +83,7 @@ public class UnitAlgorithmBezier : UnitAlgorithm<DataPlate> {
|
||||
return points;
|
||||
}
|
||||
/// <summary> 三阶贝塞尔线段 </summary>
|
||||
private List<Vector3> Compute(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float smooth) {
|
||||
private List<Vector3> Compute(Vector3 a, Vector3 b, Vector3 c, Vector3 d) {
|
||||
List<Vector3> points = new List<Vector3>();
|
||||
//方向,距离
|
||||
Vector2 direction = (d - a).normalized;
|
||||
@@ -114,6 +99,7 @@ public class UnitAlgorithmBezier : UnitAlgorithm<DataPlate> {
|
||||
points.Add(d);
|
||||
return points;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> 商数 </summary>
|
||||
public static int Quotient(float distance, float smooth) {
|
||||
|
||||
@@ -1,28 +1,35 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 散点边界算法
|
||||
/// </summary>
|
||||
public class UnitAlgorithmBorder : UnitAlgorithm<DataPlate> {
|
||||
public class UnitAlgorithmBorder : UnitAlgorithm<DataPlateBaking> {
|
||||
/// <summary> 散点边界算法 </summary>
|
||||
public UnitAlgorithmBorder() { }
|
||||
|
||||
public void Compute(DataPlate plate) {
|
||||
List<Vector3> edgePoints = new List<Vector3>(plate.edgePoints);
|
||||
plate.border = Border(edgePoints);
|
||||
public void Compute(DataPlateBaking plateBaking) {
|
||||
//List<DataPlateSide> plateSides = plateBaking.plate.plateSides;
|
||||
|
||||
//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 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 > maxX) { maxX = points[i].x; }
|
||||
if (points[i].y < minY) { minY = 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>
|
||||
public class UnitAlgorithmEarCutting : UnitAlgorithm<DataPlate> {
|
||||
public class UnitAlgorithmEarCutting : UnitAlgorithm<DataPlateDesign> {
|
||||
/// <summary> 多边形耳切法 </summary>
|
||||
public UnitAlgorithmEarCutting() { }
|
||||
|
||||
@@ -17,27 +17,27 @@ public class UnitAlgorithmEarCutting : UnitAlgorithm<DataPlate> {
|
||||
public Vector3 cPoint;//+1
|
||||
}
|
||||
|
||||
public void Compute(DataPlate data) {
|
||||
List<Vector3> points = new List<Vector3>(data.edgePoints);
|
||||
public void Compute(DataPlateDesign plateDesign) {
|
||||
List<Vector3> points = new List<Vector3>(plateDesign.points);
|
||||
//判断散列点排序方向
|
||||
Vector3[] allArray = points.ToArray();
|
||||
bool isClockWise = IsClockWise(allArray);
|
||||
Vector3[] allPoints = plateDesign.points;
|
||||
bool isClockWise = IsClockWise(allPoints);
|
||||
//耳切法生成三角形
|
||||
List<DataTriangle> triangles = new List<DataTriangle>();
|
||||
ComputeAuriculare(triangles, points, allArray, isClockWise);
|
||||
data.triangles = triangles;
|
||||
ComputeAuriculare(triangles, points, allPoints, isClockWise);
|
||||
plateDesign.triangles = triangles;
|
||||
}
|
||||
|
||||
#region 函数
|
||||
/// <summary> 循环计算有效的耳点 </summary>
|
||||
public static void ComputeAuriculare(List<DataTriangle> triangles, List<Vector3> edgePoints, Vector3[] allArray, bool isClockWise) {
|
||||
List<DataTriangle> temp = ComputeAuriculare(edgePoints, allArray, isClockWise);
|
||||
public static void ComputeAuriculare(List<DataTriangle> triangles, List<Vector3> edgePoints, Vector3[] allPoints, bool isClockWise) {
|
||||
List<DataTriangle> temp = ComputeAuriculare(edgePoints, allPoints, isClockWise);
|
||||
if (temp.Count == 0) { return; }
|
||||
triangles.AddRange(temp);
|
||||
ComputeAuriculare(triangles, edgePoints, allArray, isClockWise);
|
||||
ComputeAuriculare(triangles, edgePoints, allPoints, isClockWise);
|
||||
}
|
||||
/// <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();
|
||||
List<DataTriangle> polygons = new List<DataTriangle>();
|
||||
for (int i = 0; i < array.Length; i++) {
|
||||
@@ -45,7 +45,7 @@ public class UnitAlgorithmEarCutting : UnitAlgorithm<DataPlate> {
|
||||
// 等于180,大于180,不可能为耳点
|
||||
if (!GetAngleType(auriculare, isClockWise)) { continue; }
|
||||
// 包含其他点,不可能为耳点
|
||||
if (IsInsideTriangle(auriculare, allArray)) { continue; }
|
||||
if (IsInsideTriangle(auriculare, allPoints)) { continue; }
|
||||
// 包含其他耳点,不可能成为耳点
|
||||
if (!IsInsideAuriculare(auriculare, edgePoints)) { continue; }
|
||||
edgePoints.Remove(auriculare.aPoint);
|
||||
|
||||
@@ -35,7 +35,7 @@ public class UnitAlgorithmEdgePoint : UnitAlgorithm<DataPolygon> {
|
||||
|
||||
#region 函数
|
||||
/// <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>();
|
||||
//方向,距离
|
||||
Vector2 direction = (bPoint.position - aPoint.position).normalized;
|
||||
@@ -53,7 +53,7 @@ public class UnitAlgorithmEdgePoint : UnitAlgorithm<DataPolygon> {
|
||||
return points;
|
||||
}
|
||||
/// <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>();
|
||||
//方向,距离
|
||||
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>
|
||||
public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlate> {
|
||||
public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlateDesign>, UnitAlgorithm<DataPlateBaking> {
|
||||
/// <summary> 三角形合并网格 </summary>
|
||||
public UnitAlgorithmMergeTriangle() { }
|
||||
|
||||
public void Compute(DataPlate data) {
|
||||
List<DataTriangle> polygons = data.triangles;
|
||||
public void Compute(DataPlateDesign plateDesign) {
|
||||
List<DataTriangle> polygons = plateDesign.triangles;
|
||||
//三角形合并
|
||||
List<Vector3> vertices = vertices = MergeVertices(polygons);
|
||||
List<int> triangles = JobFindTriangleIndex(polygons, vertices);
|
||||
@@ -23,12 +23,28 @@ public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlate> {
|
||||
List<Vector2> uv = new List<Vector2>();
|
||||
for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
|
||||
//附加数据
|
||||
data.designMesh = new Mesh();
|
||||
data.designMesh.vertices = vertices.ToArray();
|
||||
data.designMesh.uv = uv.ToArray();
|
||||
data.designMesh.triangles = triangles.ToArray();
|
||||
data.designMesh.RecalculateBounds();
|
||||
data.designMesh.RecalculateNormals();
|
||||
plateDesign.mesh = new Mesh();
|
||||
plateDesign.mesh.vertices = vertices.ToArray();
|
||||
plateDesign.mesh.uv = uv.ToArray();
|
||||
plateDesign.mesh.triangles = triangles.ToArray();
|
||||
plateDesign.mesh.RecalculateBounds();
|
||||
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>
|
||||
private List<Vector3> MergeVertices(List<DataTriangle> polygons) {
|
||||
@@ -54,7 +70,7 @@ public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlate> {
|
||||
triangleIndex.triangles = trianglesArray;
|
||||
|
||||
JobHandle dependency = new JobHandle();
|
||||
JobHandle handle = triangleIndex.ScheduleParallel(polygons.Count, 2048, dependency);
|
||||
JobHandle handle = triangleIndex.ScheduleParallel(polygons.Count, 32, dependency);
|
||||
handle.Complete();
|
||||
|
||||
List<int> triangles = new List<int>();
|
||||
|
||||
@@ -5,55 +5,58 @@ using UnityEngine;
|
||||
/// <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>();
|
||||
data.vertexGrid.Loop((x, y) => {
|
||||
DataVertex vertex = data.vertexGrid.Get(x, y);
|
||||
if (!vertex.isValid) { return; }
|
||||
List<DataPlateVertex> vertexs = new List<DataPlateVertex>();
|
||||
//plateBaking.grid.Loop((x, y) => {
|
||||
// DataPlateVertex vertex = plateBaking.grid.Get(x, y);
|
||||
// if (!vertex.isValid) { return; }
|
||||
|
||||
TryGet(data.vertexGrid, x, y + 1, ref vertex.above);
|
||||
TryGet(data.vertexGrid, x, y - 1, ref vertex.below);
|
||||
TryGet(data.vertexGrid, x - 1, y, ref vertex.left);
|
||||
TryGet(data.vertexGrid, x + 1, y, ref vertex.right);
|
||||
// TryGet(plateBaking.grid, x, y + 1, ref vertex.above);
|
||||
// TryGet(plateBaking.grid, x, y - 1, ref vertex.below);
|
||||
// TryGet(plateBaking.grid, x - 1, y, ref vertex.left);
|
||||
// TryGet(plateBaking.grid, x + 1, y, ref vertex.right);
|
||||
|
||||
TryGet(data.vertexGrid, x - 1, y + 1, ref vertex.leftAbove);
|
||||
TryGet(data.vertexGrid, x - 1, y - 1, ref vertex.leftBelow);
|
||||
TryGet(data.vertexGrid, x + 1, y + 1, ref vertex.rightAbove);
|
||||
TryGet(data.vertexGrid, x + 1, y - 1, ref vertex.rightBelow);
|
||||
//默认绘制左上角
|
||||
if (vertex.above != null && vertex.left != null) {
|
||||
triangles.Add(CreateDataTriangle(vertex, vertex.left, vertex.above));
|
||||
}
|
||||
//默认绘制右下角
|
||||
if (vertex.below != null && vertex.right != null) {
|
||||
triangles.Add(CreateDataTriangle(vertex, vertex.right, vertex.below));
|
||||
}
|
||||
//如果右上角点不存在,则尝试绘制右上角
|
||||
if (vertex.rightAbove == null && vertex.above != null && vertex.right != null) {
|
||||
triangles.Add(CreateDataTriangle(vertex, vertex.above, vertex.right));
|
||||
}
|
||||
//如果左下角点不存在,则尝试绘制左下角
|
||||
if (vertex.leftBelow == null && vertex.below != null && vertex.left != null) {
|
||||
triangles.Add(CreateDataTriangle(vertex, vertex.below, vertex.left));
|
||||
}
|
||||
});
|
||||
data.triangles = triangles;
|
||||
// TryGet(plateBaking.grid, x - 1, y + 1, ref vertex.leftAbove);
|
||||
// TryGet(plateBaking.grid, x - 1, y - 1, ref vertex.leftBelow);
|
||||
// TryGet(plateBaking.grid, x + 1, y + 1, ref vertex.rightAbove);
|
||||
// TryGet(plateBaking.grid, x + 1, y - 1, ref vertex.rightBelow);
|
||||
// //默认绘制左上角
|
||||
// if (vertex.above != null && vertex.left != null) {
|
||||
// triangles.Add(CreateDataTriangle(vertex, vertex.left, vertex.above));
|
||||
// }
|
||||
// //默认绘制右下角
|
||||
// if (vertex.below != null && vertex.right != null) {
|
||||
// triangles.Add(CreateDataTriangle(vertex, vertex.right, vertex.below));
|
||||
// }
|
||||
// //如果右上角点不存在,则尝试绘制右上角
|
||||
// if (vertex.rightAbove == null && vertex.above != null && vertex.right != null) {
|
||||
// triangles.Add(CreateDataTriangle(vertex, vertex.above, vertex.right));
|
||||
// }
|
||||
// //如果左下角点不存在,则尝试绘制左下角
|
||||
// if (vertex.leftBelow == null && vertex.below != null && vertex.left != null) {
|
||||
// triangles.Add(CreateDataTriangle(vertex, vertex.below, vertex.left));
|
||||
// }
|
||||
// vertexs.Add(vertex);
|
||||
//});
|
||||
//plateBaking.triangles = triangles;
|
||||
//plateBaking.vertexs = vertexs.ToArray();
|
||||
}
|
||||
|
||||
/// <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;
|
||||
if (!grid.TryGet(x, y, out DataVertex data)) { return; }
|
||||
if (!grid.TryGet(x, y, out DataPlateVertex data)) { return; }
|
||||
if (data.isValid) { vertex = data; }
|
||||
}
|
||||
/// <summary> 创建三角形 </summary>
|
||||
private DataTriangle CreateDataTriangle(DataVertex a, DataVertex b, DataVertex c) {
|
||||
private DataTriangle CreateDataTriangle(DataPlateVertex a, DataPlateVertex b, DataPlateVertex c) {
|
||||
DataTriangle triangle = new DataTriangle();
|
||||
triangle.b = a.design;
|
||||
triangle.c = b.design;
|
||||
triangle.a = c.design;
|
||||
triangle.b = a.position;
|
||||
triangle.c = b.position;
|
||||
triangle.a = c.position;
|
||||
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>
|
||||
public class UnitAlgorithmVertex : UnitAlgorithm<DataPlate> {
|
||||
public class UnitAlgorithmVertex : UnitAlgorithm<DataPlateBaking> {
|
||||
|
||||
public class SideVertex : IComparable<SideVertex> {
|
||||
public float distance;
|
||||
public DataVertex vertex;
|
||||
public Vector3 position;
|
||||
|
||||
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) {
|
||||
float smooth = data.smooth;
|
||||
DataBorder border = data.border;
|
||||
List<Vector3> edgePoints = new List<Vector3>(data.edgePoints);
|
||||
public void Compute(DataPlateBaking plateBaking) {
|
||||
DataBorder border = plateBaking.border;
|
||||
Vector3[] points = border.points;
|
||||
|
||||
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) => {
|
||||
Vector3 position = border.MinPoint + new Vector3(x * smooth, y * smooth);
|
||||
DataVertex vertex = new DataVertex();
|
||||
vertex.isValid = FindPlateInside(edgePoints, position);
|
||||
vertex.design = position;
|
||||
return vertex;
|
||||
});
|
||||
//plateBaking.grid = new GridTool<DataPlateVertex>(border.GridWide, border.GridHigh, (x, y) => {
|
||||
// Vector3 position = new Vector3(x, y) * border.smooth + border.MinPoint;
|
||||
// DataPlateVertex vertex = new DataPlateVertex();
|
||||
// vertex.isValid = FindPlateInside(points, position);
|
||||
// vertex.position = position;
|
||||
// return vertex;
|
||||
//});
|
||||
|
||||
//边缘所有的线段
|
||||
for (int i = 0; i < data.sides.Count; i++) {
|
||||
Compute(data.sides[i], wide, high, border, smooth, data.vertexGrid);
|
||||
}
|
||||
//List<DataPlateSide> plateSides = plateBaking.plate.plateSides;
|
||||
//for (int i = 0; i < plateSides.Count; i++) {
|
||||
// SubdivideSideVertex(plateBaking, plateSides[i]);
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary> 向网格和边缘写入顶点数据 </summary>
|
||||
private void Compute(DataSide side, int wide, int high, DataBorder border, float smooth, GridTool<DataVertex> grid) {
|
||||
DataLine[] lines = side.lines;
|
||||
List<SideVertex> sideVertices = new List<SideVertex>();
|
||||
private void SubdivideSideVertex(DataPlateBaking plateBaking, DataPlateSide plateSides) {
|
||||
DataBorder border = plateBaking.border;
|
||||
DataPlateLine[] lines = plateSides.dataBaking.lines;
|
||||
//计算水平线段顶点
|
||||
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);
|
||||
List<SideVertex> sideVertexs = new List<SideVertex>();
|
||||
for (int x = 0; x < border.GridWide; x++) {
|
||||
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++) {
|
||||
DataVertex vertex = Compute(a, b, lines[i], smooth, border, grid);
|
||||
if (vertex == null) { continue; }
|
||||
float distance = Vector3.Distance(lines[i].a, vertex.design) + lines[i].origin;
|
||||
if (!TryGetIntersectPoint(a, b, lines[i].a, lines[i].b, out Vector3 IntersectPoint)) { continue; }
|
||||
float distance = Vector3.Distance(lines[i].a, IntersectPoint) + lines[i].origin;
|
||||
SideVertex sideVertex = new SideVertex();
|
||||
sideVertex.distance = distance;
|
||||
sideVertex.vertex = vertex;
|
||||
sideVertices.Add(sideVertex);
|
||||
sideVertex.position = IntersectPoint;
|
||||
sideVertexs.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 y = 0; y < border.GridHigh; y++) {
|
||||
Vector3 a = new Vector3(border.minX - 1, border.minY + y * border.smooth);
|
||||
Vector3 b = new Vector3(border.maxX + 1, border.minY + y * border.smooth);
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
DataVertex vertex = Compute(a, b, lines[i], smooth, border, grid);
|
||||
if (vertex == null) { continue; }
|
||||
float distance = Vector3.Distance(lines[i].a, vertex.design) + lines[i].origin;
|
||||
if (!TryGetIntersectPoint(a, b, lines[i].a, lines[i].b, out Vector3 IntersectPoint)) { continue; }
|
||||
float distance = Vector3.Distance(lines[i].a, IntersectPoint) + lines[i].origin;
|
||||
SideVertex sideVertex = new SideVertex();
|
||||
sideVertex.distance = distance;
|
||||
sideVertex.vertex = vertex;
|
||||
sideVertices.Add(sideVertex);
|
||||
sideVertex.position = IntersectPoint;
|
||||
sideVertexs.Add(sideVertex);
|
||||
}
|
||||
}
|
||||
sideVertices.Sort();
|
||||
List<DataVertex> vertices = new List<DataVertex>();
|
||||
for (int i = 0; i < sideVertices.Count; i++) {
|
||||
vertices.Add(sideVertices[i].vertex);
|
||||
}
|
||||
side.vertices = vertices.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);
|
||||
//排序
|
||||
sideVertexs.Sort();
|
||||
//写入网格,写入顶点
|
||||
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);
|
||||
//填充数据
|
||||
DataVertex vertex = grid.Get(vertexX, vertexY);
|
||||
vertex.isValid = true;
|
||||
vertex.design = IntersectPoint;
|
||||
return vertex;
|
||||
//DataPlateVertex vertex = plateBaking.grid.Get(vertexX, vertexY);
|
||||
//vertex.isValid = true;
|
||||
//vertex.position = position;
|
||||
////写入顶点
|
||||
//vertexs.Add(vertex);
|
||||
}
|
||||
plateSides.dataBaking.vertexs = vertexs.ToArray();
|
||||
}
|
||||
|
||||
/// <summary> 转角法查询位置是否在板片内 </summary>
|
||||
public static bool FindPlateInside(List<Vector3> points, Vector3 position) {
|
||||
public static bool FindPlateInside(Vector3[] points, Vector3 position) {
|
||||
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 b = points.LoopIndex(i + 1) - position;
|
||||
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; }
|
||||
mousePosition = data.ScreenPosition;
|
||||
originalPosition = platePrefab.transform.localPosition;
|
||||
platePrefab.Value.bakingPosition = originalPosition;
|
||||
platePrefab.Value.dataBaking.position = originalPosition;
|
||||
ModuleCore.BakingMobilePlate(platePrefab.Value);
|
||||
}
|
||||
public override void MouseDrag(DataMouseInput data) {
|
||||
if (platePrefab == null) { return; }
|
||||
if (ViewCamera.ScreenToWorldObjectParent(data.ScreenPosition, out arrange, Arrange)) {
|
||||
platePrefab.Value.arrange = arrange;
|
||||
platePrefab.Value.bakingPosition = arrange.transform.localPosition;
|
||||
platePrefab.Value.bakingEulerAngles = arrange.transform.localEulerAngles;
|
||||
platePrefab.Value.dataBaking.position = arrange.transform.localPosition;
|
||||
platePrefab.Value.dataBaking.eulerAngles = arrange.transform.localEulerAngles;
|
||||
}
|
||||
else { Mobile(data.WorldPosition); }
|
||||
platePrefab.Value.UpdateVisual(false);
|
||||
@@ -41,6 +41,6 @@ public class BakingMobilePlate : UnitMouseInput {
|
||||
Vector3 offset = current - original;
|
||||
Vector3 up = ViewCamera.Up * offset.y;
|
||||
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>
|
||||
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
||||
/// <summary> 查询点算法模块 </summary>
|
||||
public ModuleFind<DataSide> FindSide => ModuleCore.FindSide;
|
||||
public ModuleFind<DataPlateSide> FindSide => ModuleCore.FindSide;
|
||||
|
||||
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.ThreeRankBezier(); side.plate.UpdateVisual(); return; }
|
||||
if (side.bezier == Bezier.三阶) { side.OneRankBezier(); side.plate.UpdateVisual(); return; }
|
||||
|
||||
@@ -3,28 +3,33 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class DesignInsert : UnitMouseInput {
|
||||
/// <summary> 板片资产 </summary>
|
||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||
/// <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;
|
||||
/// <summary> 查询边交点 </summary>
|
||||
public UnitFind<SideIntersectPoint> find = new FindSideIntersectPoint();
|
||||
|
||||
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);
|
||||
AlgorithmSidePoint.Compute(intersect);
|
||||
if (!intersect.isIntersect) { return; }
|
||||
|
||||
DataInsertPoint insertPoint = new DataInsertPoint();
|
||||
insertPoint.position = intersect.intersectPoint - side.plate.designPosition;
|
||||
insertPoint.plate = side.plate;
|
||||
insertPoint.aPoint = side.aPoint;
|
||||
insertPoint.bPoint = side.bPoint;
|
||||
insertPoint.side = side;
|
||||
InsertPointToPoint.To(insertPoint);
|
||||
private void Insert(DataPlateSide side, DataPlate plate, DataPlatePoint aPoint, DataPlatePoint bPoint, Vector3 position) {
|
||||
//创建新的点
|
||||
DataPlatePoint newPoint = new DataPlatePoint(plate);
|
||||
newPoint.position = position - plate.dataDesign.position;
|
||||
//改变关联的边B点,重置贝塞尔曲线
|
||||
side.bPoint = newPoint;
|
||||
side.OneRankBezier();
|
||||
//创建新的边
|
||||
DataPlateSide newSide = new DataPlateSide(plate);
|
||||
newSide.aPoint = newPoint;
|
||||
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 Vector3 mousePosition;
|
||||
private Vector3 originalPosition;
|
||||
private ModulePrefab<DataPoint> prefabPoint;
|
||||
private ModulePrefab<DataPlatePoint> prefabPoint;
|
||||
private ModulePrefab<DataPlate> prefabPlate;
|
||||
|
||||
public override void MouseDown(DataMouseInput data) {
|
||||
@@ -61,10 +61,10 @@ public class DesignMobile : UnitMouseInput {
|
||||
//板片
|
||||
private void RecordPlate(Vector3 screenPosition) {
|
||||
mousePosition = screenPosition;
|
||||
originalPosition = prefabPlate.Value.designPosition;
|
||||
originalPosition = prefabPlate.Value.dataDesign.position;
|
||||
}
|
||||
private void MobilePlate(Vector3 offset) {
|
||||
prefabPlate.Value.designPosition = originalPosition + offset;
|
||||
prefabPlate.Value.dataDesign.position = originalPosition + offset;
|
||||
prefabPlate.Value.UpdateVisual(false);
|
||||
}
|
||||
//相机
|
||||
|
||||
@@ -3,29 +3,30 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class DesignSuture : UnitMouseInput {
|
||||
/// <summary> 设计视图相机模块 </summary>
|
||||
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
||||
/// <summary> 查询点算法模块 </summary>
|
||||
public ModuleFind<DataSide> FindSide => ModuleCore.FindSide;
|
||||
/// <summary> 计算位置到边上最近的点 </summary>
|
||||
public ModuleAlgorithm<DataIntersect> AlgorithmSidePoint => ModuleCore.AlgorithmSidePoint;
|
||||
/// <summary> 查询边交点 </summary>
|
||||
public UnitFind<SideIntersectPoint> find = new FindSideIntersectPoint();
|
||||
/// <summary> 连接可视化内容生成模块 </summary>
|
||||
public ModuleVisual<DataConnector> VisualConnector => ModuleCore.VisualConnector;
|
||||
|
||||
private DataSide aSide;
|
||||
private DataSide bSide;
|
||||
private DataPlateSide aSide;
|
||||
private DataPlateSide bSide;
|
||||
private DataConnector connector;
|
||||
|
||||
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.aPoint = intersectPoint;
|
||||
connector.bPoint = intersectPoint;
|
||||
connector.aPoint = data.WorldPosition;
|
||||
if (!find.Find(data.WorldPosition, out SideIntersectPoint sip)) { return; }
|
||||
connector.aPoint = sip.intersectPoint;
|
||||
aSide = sip.side;
|
||||
}
|
||||
public override void MouseDrag(DataMouseInput data) {
|
||||
if (aSide == null) { return; }
|
||||
connector.bPoint = GetPosition(data);
|
||||
if (connector == null) { return; }
|
||||
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);
|
||||
}
|
||||
public override void MouseRelease(DataMouseInput data) {
|
||||
@@ -41,16 +42,16 @@ public class DesignSuture : UnitMouseInput {
|
||||
aSide.plate.UpdateVisual();
|
||||
}
|
||||
|
||||
private Vector3 GetPosition(DataMouseInput data) {
|
||||
if (!FindSide.Find(data.WorldPosition, out bSide)) { return data.WorldPosition; }
|
||||
if (aSide == bSide) { return data.WorldPosition; }
|
||||
if (Intersect(bSide, data.WorldPosition, out Vector3 intersectPoint)) { return intersectPoint; }
|
||||
else { return data.WorldPosition; }
|
||||
}
|
||||
private bool Intersect(DataSide side, Vector3 position, out Vector3 intersectPoint) {
|
||||
DataIntersect intersect = new DataIntersect(side, position);
|
||||
AlgorithmSidePoint.Compute(intersect);
|
||||
intersectPoint = intersect.intersectPoint;
|
||||
return intersect.isIntersect;
|
||||
}
|
||||
//private Vector3 GetPosition(DataMouseInput data) {
|
||||
// if (!FindSide.Find(data.WorldPosition, out bSide)) { return data.WorldPosition; }
|
||||
// if (aSide == bSide) { return data.WorldPosition; }
|
||||
// if (Intersect(bSide, data.WorldPosition, out Vector3 intersectPoint)) { return intersectPoint; }
|
||||
// else { return data.WorldPosition; }
|
||||
//}
|
||||
//private bool Intersect(DataSide side, Vector3 position, out Vector3 intersectPoint) {
|
||||
//DataIntersect intersect = new DataIntersect(side, position);
|
||||
//AlgorithmSidePoint.Compute(intersect);
|
||||
//intersectPoint = intersect.intersectPoint;
|
||||
//return intersect.isIntersect;
|
||||
//}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@ public class DesignSutureReversal : UnitMouseInput {
|
||||
/// <summary> 设计视图相机模块 </summary>
|
||||
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
||||
/// <summary> 查询点算法模块 </summary>
|
||||
public ModuleFind<DataSide> FindSide => ModuleCore.FindSide;
|
||||
public ModuleFind<DataPlateSide> FindSide => ModuleCore.FindSide;
|
||||
|
||||
public override void MouseDown(DataMouseInput data) {
|
||||
if (!FindSide.Find(data.WorldPosition, out DataSide side)) { return; }
|
||||
if (side.suture.a.side == side) {
|
||||
if (!FindSide.Find(data.WorldPosition, out DataPlateSide side)) { return; }
|
||||
if (side.suture.a.plateSide == side) {
|
||||
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.plate.UpdateVisual();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"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.unity.collab-proxy": "2.5.2",
|
||||
"com.unity.collections": "1.2.4",
|
||||
"com.unity.feature.development": "1.0.1",
|
||||
"com.unity.render-pipelines.universal": "14.0.11",
|
||||
"com.unity.textmeshpro": "3.0.6",
|
||||
|
||||
@@ -30,6 +30,16 @@
|
||||
"dependencies": {},
|
||||
"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": {
|
||||
"version": "1.0.0",
|
||||
"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