合并代码
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 算法:中心角度排序法
|
||||
/// 依据:???
|
||||
/// </summary>
|
||||
public class AlgorithmEdge : ModuleAlgorithm<DataPlate> {
|
||||
/// <summary> 算法:中心角度排序法 </summary>
|
||||
public AlgorithmEdge() { }
|
||||
|
||||
public class EdgeAngle {
|
||||
public float angle;
|
||||
public Vector3 position;
|
||||
}
|
||||
|
||||
public override void Compute(DataPlate data) {
|
||||
List<Vector2> edgePoints = data.edgePoints;
|
||||
//计算多边形中心点
|
||||
float x = edgePoints.Average((v3) => v3.x);
|
||||
float y = edgePoints.Average((v3) => v3.y);
|
||||
Vector2 center = new Vector2(x, y);
|
||||
//计算所有点的夹角
|
||||
Vector3 direction = edgePoints[0] - center;
|
||||
List<EdgeAngle> angleList = new List<EdgeAngle>();
|
||||
for (int i = 0; i < edgePoints.Count; i++) {
|
||||
Vector3 normal = edgePoints[i] - center;
|
||||
EdgeAngle edgeAngle = new EdgeAngle();
|
||||
edgeAngle.angle = Angle(direction, normal);
|
||||
edgeAngle.position = normal;
|
||||
angleList.Add(edgeAngle);
|
||||
}
|
||||
data.centerOffset = center;
|
||||
//排序
|
||||
angleList.Sort((x, y) => x.angle.CompareTo(y.angle));
|
||||
//把排序好的边缘点重新添加
|
||||
data.edgePoints = new List<Vector2>();
|
||||
for (int i = 0; i < angleList.Count; i++) {
|
||||
data.edgePoints.Add(angleList[i].position);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 计算两点夹角
|
||||
/// </summary>
|
||||
/// <param name="direction">0度点位置</param>
|
||||
/// <param name="position">目标点</param>
|
||||
/// <returns></returns>
|
||||
private float Angle(Vector3 direction, Vector3 position) {
|
||||
float angle = Vector2.SignedAngle(direction, position);
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 算法:根据设计点来生成边缘点
|
||||
/// 依据:???
|
||||
/// </summary>
|
||||
public class AlgorithmGenerateEdge : ModuleAlgorithm<DataPlate> {
|
||||
/// <summary> 算法:根据设计点来生成边缘点 </summary>
|
||||
public AlgorithmGenerateEdge() { }
|
||||
|
||||
public override void Compute(DataPlate data) {
|
||||
data.edgePoints = new List<Vector2>();
|
||||
int maxIndex = data.designPoints.Count;
|
||||
for (int i = 0; i < maxIndex; i++) {
|
||||
DataDesignPoint designPoint = data.FindDesignPoint(i);
|
||||
DataDesignPoint nextDesignPoint = data.FindDesignPoint(i + 1);
|
||||
CreateStraightLine(data, designPoint, nextDesignPoint);
|
||||
}
|
||||
}
|
||||
public void CreateStraightLine(DataPlate data, DataDesignPoint designPoint, DataDesignPoint nextDesignPoint) {
|
||||
designPoint.edgePoints = new List<Vector2>();
|
||||
//方向,距离
|
||||
Vector2 direction = (nextDesignPoint.postiton - designPoint.postiton).normalized;
|
||||
float distance = Vector2.Distance(nextDesignPoint.postiton, designPoint.postiton);
|
||||
//求余,得商数
|
||||
int a = (int)(distance * 1000);
|
||||
int b = (int)(data.edgeSmooth * 1000);
|
||||
int quotient = Math.DivRem(a, b, out int remainder);
|
||||
//点位间距
|
||||
float segment = distance / quotient;
|
||||
Vector3 ap = designPoint.postiton;
|
||||
Vector3 bp = designPoint.leftBezier + designPoint.postiton;
|
||||
Vector3 cp = nextDesignPoint.rightBezier + nextDesignPoint.postiton;
|
||||
Vector3 dp = nextDesignPoint.postiton;
|
||||
for (int i = 0; i < quotient; i++) {
|
||||
float t = segment * i / distance;
|
||||
Vector2 position = ComputeBezier(ap, bp, cp, dp, t);
|
||||
designPoint.edgePoints.Add(position);
|
||||
}
|
||||
data.edgePoints.AddRange(designPoint.edgePoints);
|
||||
}
|
||||
/// <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 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 算法:耳切法
|
||||
/// 依据:简单多边形的双耳定理
|
||||
/// </summary>
|
||||
public class AlgorithmPolygon : ModuleAlgorithm<DataPlate> {
|
||||
/// <summary> 算法:耳切法 </summary>
|
||||
public AlgorithmPolygon() { }
|
||||
|
||||
public enum AngleType {
|
||||
/// <summary> 平角 = 180 </summary>
|
||||
StraightAngle = 0,
|
||||
/// <summary> 优角 >180 </summary>
|
||||
ReflexAngle = 1,
|
||||
/// <summary> 劣角 <180 </summary>
|
||||
InferiorAngle = 2
|
||||
}
|
||||
|
||||
public class PointNode {
|
||||
public int index;
|
||||
public Vector2 Position;
|
||||
public Vector2 PreviousPosition;
|
||||
public Vector2 NextPosition;
|
||||
}
|
||||
|
||||
public class Triangle {
|
||||
public Vector2 a;
|
||||
public Vector2 b;
|
||||
public Vector2 c;
|
||||
}
|
||||
|
||||
public override void Compute(DataPlate data) {
|
||||
List<Vector2> edgePoints = new List<Vector2>(data.edgePoints);
|
||||
List<Triangle> polygons = new List<Triangle>();
|
||||
Vector2[] allArray = edgePoints.ToArray();
|
||||
bool isClockWise = IsClockWise(allArray);
|
||||
//耳切法生成三角形
|
||||
ComputeEarTriangle(polygons, edgePoints, allArray, isClockWise);
|
||||
MergeTriangles(data, polygons);
|
||||
}
|
||||
/// <summary> 循环计算耳点 </summary>
|
||||
public void ComputeEarTriangle(List<Triangle> polygons, List<Vector2> edgePoints, Vector2[] allArray, bool isClockWise) {
|
||||
List<Triangle> temp = ComputeEarTriangle(edgePoints, allArray, isClockWise);
|
||||
if (temp.Count == 0) { return; }
|
||||
polygons.AddRange(temp);
|
||||
ComputeEarTriangle(polygons, edgePoints, allArray, isClockWise);
|
||||
}
|
||||
/// <summary> 计算一个耳点 </summary>
|
||||
public List<Triangle> ComputeEarTriangle(List<Vector2> edgePoints, Vector2[] allArray, bool isClockWise) {
|
||||
Vector2[] array = edgePoints.ToArray();
|
||||
List<Triangle> polygons = new List<Triangle>();
|
||||
for (int i = 0; i < array.Length; i++) {
|
||||
PointNode pointNode = CreatePointNode(i, array);
|
||||
AngleType angleType = GetAngleType(pointNode, isClockWise);
|
||||
// 等于180,不可能为耳点
|
||||
if (angleType == AngleType.StraightAngle) { continue; }
|
||||
// 大于180,不可能为耳点
|
||||
if (angleType == AngleType.ReflexAngle) { continue; }
|
||||
// 包含其他点,不可能为耳点
|
||||
if (IsInsideTriangle(pointNode, allArray)) { continue; }
|
||||
// 包含其他耳点,不可能成为耳点
|
||||
if (!IsInsideEarTriangle(pointNode, edgePoints)) { continue; }
|
||||
edgePoints.Remove(pointNode.Position);
|
||||
polygons.Add(CreateTriangle(pointNode));
|
||||
}
|
||||
return polygons;
|
||||
}
|
||||
/// <summary> 创建节点 </summary>
|
||||
public PointNode CreatePointNode(int index, Vector2[] array) {
|
||||
int maxIndex = array.Length;
|
||||
PointNode pointNode = new PointNode();
|
||||
pointNode.index = index;
|
||||
pointNode.PreviousPosition = array[NormalIndex(index - 1, maxIndex)];
|
||||
pointNode.Position = array[NormalIndex(index + 0, maxIndex)];
|
||||
pointNode.NextPosition = array[NormalIndex(index + 1, maxIndex)];
|
||||
return pointNode;
|
||||
}
|
||||
/// <summary> 计算三角形内是否包含其他点 </summary>
|
||||
public bool IsInsideTriangle(PointNode node, Vector2[] array) {
|
||||
for (int i = 0; i < array.Length; i++) {
|
||||
if (array[i] == node.Position) { continue; }
|
||||
if (array[i] == node.PreviousPosition) { continue; }
|
||||
if (array[i] == node.NextPosition) { continue; }
|
||||
if (IsInsideTriangle(node, array[i])) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/// <summary> 计算三角形内是否包含其他点 </summary>
|
||||
public bool IsInsideEarTriangle(PointNode node, List<Vector2> edgePoints) {
|
||||
if (!edgePoints.Contains(node.Position)) { return false; }
|
||||
if (!edgePoints.Contains(node.PreviousPosition)) { return false; }
|
||||
if (!edgePoints.Contains(node.NextPosition)) { return false; }
|
||||
return true;
|
||||
}
|
||||
/// <summary> 从节点创建三角形 </summary>
|
||||
public Triangle CreateTriangle(PointNode node) {
|
||||
Triangle triangle = new Triangle();
|
||||
triangle.a = node.Position;
|
||||
triangle.b = node.PreviousPosition;
|
||||
triangle.c = node.NextPosition;
|
||||
return triangle;
|
||||
}
|
||||
/// <summary> 合并三角形 </summary>
|
||||
public void MergeTriangles(DataPlate data, List<Triangle> polygons) {
|
||||
//创建数据容器
|
||||
List<Vector3> vertices = new List<Vector3>();
|
||||
List<Vector2> uv = new List<Vector2>();
|
||||
List<int> triangles = new List<int>();
|
||||
//三角形合并
|
||||
for (int i = 0; i < polygons.Count; i++) {
|
||||
Vector3 a = polygons[i].a;
|
||||
int aIndex = vertices.Count - 1;
|
||||
if (!vertices.Contains(a)) { vertices.Add(a); aIndex = vertices.Count - 1; }
|
||||
else { aIndex = vertices.IndexOf(a); }
|
||||
|
||||
Vector3 b = polygons[i].b;
|
||||
int bIndex = vertices.Count - 1;
|
||||
if (!vertices.Contains(b)) { vertices.Add(b); bIndex = vertices.Count - 1; }
|
||||
else { bIndex = vertices.IndexOf(b); }
|
||||
|
||||
Vector3 c = polygons[i].c;
|
||||
int cIndex = vertices.Count - 1;
|
||||
if (!vertices.Contains(c)) { vertices.Add(c); cIndex = vertices.Count - 1; }
|
||||
else { cIndex = vertices.IndexOf(c); }
|
||||
|
||||
triangles.Add(aIndex);
|
||||
triangles.Add(bIndex);
|
||||
triangles.Add(cIndex);
|
||||
}
|
||||
//展开uv (顶点去掉z坐标就是未缩放的平面UV)
|
||||
for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
|
||||
//附加数据
|
||||
data.vertices = vertices;
|
||||
data.uv = uv;
|
||||
data.triangles = triangles;
|
||||
}
|
||||
|
||||
/// <summary> 头尾循环标准化索引 </summary>
|
||||
public static int NormalIndex(int index, int maxIndex) {
|
||||
if (maxIndex == 0) { Debug.LogError("错误索引:maxIndex = 0"); return 0; }
|
||||
if (index < 0) { return NormalIndex(index + maxIndex, maxIndex); }
|
||||
if (index >= maxIndex) { return NormalIndex(index - maxIndex, maxIndex); }
|
||||
return index;
|
||||
}
|
||||
/// <summary> 当前的点方向是否为顺时针 </summary>
|
||||
public static bool IsClockWise(Vector2[] array) {
|
||||
// 通过计算叉乘来确定方向
|
||||
float sum = 0f;
|
||||
double count = array.Length;
|
||||
Vector3 va, vb;
|
||||
for (int i = 0; i < array.Length; i++) {
|
||||
va = array[i];
|
||||
vb = (i == count - 1) ? array[0] : array[i + 1];
|
||||
sum += va.x * vb.y - va.y * vb.x;
|
||||
}
|
||||
return sum < 0;
|
||||
}
|
||||
/// <summary> 判断角的类型 </summary>
|
||||
public static AngleType GetAngleType(PointNode node, bool isClockWise) {
|
||||
// 角度是否小于180
|
||||
// oa & ob 之间的夹角,(右手法则)
|
||||
// 逆时针顺序是相反的
|
||||
Vector2 o = node.Position;
|
||||
Vector2 a = node.PreviousPosition;
|
||||
Vector2 b = node.NextPosition;
|
||||
float f = (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
||||
bool flag = isClockWise ? f > 0 : f < 0;
|
||||
if (f == 0) { return AngleType.StraightAngle; }
|
||||
else if (flag) { return AngleType.InferiorAngle; }
|
||||
else { return AngleType.ReflexAngle; }
|
||||
}
|
||||
/// <summary> p点是否在点和其左右两个点组成的三角形内,或ca,cb边上 </summary>
|
||||
public static bool IsInsideTriangle(PointNode node, Vector2 p) {
|
||||
// p点是否在abc三角形内
|
||||
Vector2 a = node.PreviousPosition;
|
||||
Vector2 b = node.NextPosition;
|
||||
Vector2 c = node.Position;
|
||||
float c1 = (b.x - a.x) * (p.y - b.y) - (b.y - a.y) * (p.x - b.x);
|
||||
float c2 = (c.x - b.x) * (p.y - c.y) - (c.y - b.y) * (p.x - c.x);
|
||||
float c3 = (a.x - c.x) * (p.y - a.y) - (a.y - c.y) * (p.x - a.x);
|
||||
return (c1 > 0f && c2 >= 0f && c3 >= 0f) || (c1 < 0f && c2 <= 0f && c3 <= 0f);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class AssetsPresetsPlate : ModuleAssets<DataPresetsPlate> {
|
||||
protected override void Awake() {
|
||||
ModuleCore.PresetsPlateAssets = this;
|
||||
}
|
||||
public override void ForEach(Action<DataPresetsPlate> action) {
|
||||
assets.ForEach(action);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class EnumeratorAgent : ModuleAgent {
|
||||
protected override void Awake() {
|
||||
ModuleCore.ModuleAgent = this;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eda56199f140e8e41bde06c79efd4b8e
|
||||
guid: f6fbfbc1731723a4babd9d4ee59ded5b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5e34f7c1927a3940b874cf7357c05c6
|
||||
guid: 46d78284a685f31429f5bd981c1f86c1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 查询贝塞尔点算法
|
||||
/// </summary>
|
||||
public class AlgorithmFindBezier : ModuleAlgorithm<DataFindBezier> {
|
||||
public readonly float FindRange = 0.01f;
|
||||
|
||||
protected override void Awake() => ModuleCore.AlgorithmFindBezier = this;
|
||||
|
||||
public override void Compute(DataFindBezier findBezier) {
|
||||
List<DataPlate> datas = findBezier.datas;
|
||||
for (int i = 0; i < datas.Count; i++) {
|
||||
if (FindPlatePoint(datas[i], findBezier)) { return; }
|
||||
}
|
||||
}
|
||||
/// <summary> 查询匹配的点 </summary>
|
||||
private bool FindPlatePoint(DataPlate plate, DataFindBezier findBezier) {
|
||||
List<DataPoint> points = plate.points;
|
||||
Vector3 position = findBezier.position - plate.position;
|
||||
for (int i = 0; i < points.Count; i++) {
|
||||
float f = Vector3.Distance(points[i].frontBezier, position);
|
||||
if (f <= FindRange && points[i].isCurveFront) {
|
||||
findBezier.isFront = true;
|
||||
findBezier.plate = plate;
|
||||
findBezier.point = points[i];
|
||||
return true;
|
||||
}
|
||||
float a = Vector3.Distance(points[i].afterBezier, position);
|
||||
if (a <= FindRange && points[i].isCurveAfter) {
|
||||
findBezier.plate = plate;
|
||||
findBezier.point = points[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8198c73995924524d985c3beb338f033
|
||||
guid: 4ecc5cf619be47744b8ac06557518014
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c944a47248a72ee4383dd37f9906753b
|
||||
guid: cd2aff163a310544886809b5b8590bb2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 查询点算法
|
||||
/// 转角法判断点是否在多边形内
|
||||
/// </summary>
|
||||
public class AlgorithmFindPoint : ModuleAlgorithm<DataFindPoint> {
|
||||
public readonly float FindRange = 0.01f;
|
||||
|
||||
protected override void Awake() => ModuleCore.AlgorithmFindPoint = this;
|
||||
|
||||
public override void Compute(DataFindPoint findPoint) {
|
||||
List<DataPlate> datas = findPoint.datas;
|
||||
for (int i = 0; i < datas.Count; i++) {
|
||||
if (FindPlatePoint(datas[i], findPoint)) { return; }
|
||||
if (FindPlateInside(datas[i], findPoint)) { findPoint.plate = datas[i]; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> 查询匹配的点 </summary>
|
||||
private bool FindPlatePoint(DataPlate plate, DataFindPoint findPoint) {
|
||||
List<DataPoint> points = plate.points;
|
||||
Vector3 position = findPoint.position - plate.position;
|
||||
for (int i = 0; i < points.Count; i++) {
|
||||
float distance = Vector3.Distance(points[i].position, position);
|
||||
if (distance > FindRange) { continue; }
|
||||
findPoint.plate = plate;
|
||||
findPoint.point = points[i];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/// <summary> 转角法查询位置是否在板片内 </summary>
|
||||
private bool FindPlateInside(DataPlate plate, DataFindPoint findPoint) {
|
||||
DataPoint[] points = plate.points.ToArray();
|
||||
double angles = 0;
|
||||
Vector3 position = findPoint.position - plate.position;
|
||||
for (int i = 0; i < points.Length; i++) {
|
||||
Vector3 a = points.LoopIndex(i + 0).position - position;
|
||||
Vector3 b = points.LoopIndex(i + 1).position - position;
|
||||
float angle = Vector2.SignedAngle(a, b);
|
||||
angles += angle;
|
||||
}
|
||||
int normal = (int)(angles * 1000);
|
||||
return normal > 0;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d0c7458fc5119243b7db98671184058
|
||||
guid: 159a37d73c0c32e4cbb41b0767597000
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 485602713f4e17344b5dc7f627ed1a81
|
||||
guid: ce9e6ecaa5ce98843abd7070cf9adb82
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 插入点算法
|
||||
/// </summary>
|
||||
public class AlgorithmInsertPoint : ModuleAlgorithm<DataInsertPoint> {
|
||||
public class Segment {
|
||||
public DataPlate plate;
|
||||
public DataPoint aPoint;
|
||||
public DataPoint bPoint;
|
||||
public float distance = float.MaxValue;
|
||||
}
|
||||
|
||||
protected override void Awake() => ModuleCore.AlgorithmInsertPoint = this;
|
||||
|
||||
public override void Compute(DataInsertPoint insertPoint) {
|
||||
List<DataPlate> datas = insertPoint.datas;
|
||||
List<Segment> segments = new List<Segment>();
|
||||
Vector3 position = insertPoint.position;
|
||||
|
||||
for (int i = 0; i < datas.Count; i++) {
|
||||
if (!FindSegment(datas[i], position, out Segment temp)) { continue; }
|
||||
segments.Add(temp);
|
||||
}
|
||||
|
||||
if (segments.Count <= 0) { return; }
|
||||
Segment segment = segments[0];
|
||||
for (int i = 0; i < segments.Count; i++) {
|
||||
if (segment.distance < segments[i].distance) { continue; }
|
||||
segment = segments[i];
|
||||
}
|
||||
insertPoint.plate = segment.plate;
|
||||
insertPoint.aPoint = segment.aPoint;
|
||||
insertPoint.bPoint = segment.bPoint;
|
||||
}
|
||||
/// <summary> 查询匹配的线 </summary>
|
||||
private bool FindSegment(DataPlate plate, Vector3 position, out Segment segment) {
|
||||
List<DataPoint> points = plate.points;
|
||||
Vector3 c = position - plate.position;
|
||||
segment = new Segment();
|
||||
segment.plate = plate;
|
||||
for (int i = 0; i < points.Count; i++) {
|
||||
Vector3 a = points.LoopIndex(i + 0).position;
|
||||
Vector3 b = points.LoopIndex(i + 1).position;
|
||||
float distance = ProjectDistance(a, b, c);
|
||||
if (segment.distance < distance) { continue; }
|
||||
segment.aPoint = points.LoopIndex(i + 0);
|
||||
segment.bPoint = points.LoopIndex(i + 1);
|
||||
segment.distance = distance;
|
||||
}
|
||||
return segment.distance != float.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量投影法
|
||||
/// 计算点c到线段ab最近的点
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <param name="c"></param>
|
||||
/// <returns>如果不在线段上返回 float.MaxValue</returns>
|
||||
private float ProjectDistance(Vector3 a, Vector3 b, Vector3 c) {
|
||||
Vector3 ab = b - a;
|
||||
Vector3 ac = c - a;
|
||||
Vector3 p = Vector3.Project(ac, ab);
|
||||
//Debug.Log($"{a} , {b} , {c} , {p} , {ab.normalized} , {p.normalized} , {ab.normalized != p.normalized} , {ab.magnitude < p.magnitude}");
|
||||
if (ab.normalized != p.normalized) { return float.MaxValue; }
|
||||
if (ab.magnitude < p.magnitude) { return float.MaxValue; }
|
||||
//Debug.Log($"{a} , {b} , {c} , {Vector3.Distance(c, p)}");
|
||||
return Vector3.Distance(c, p + a);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d17cdf61cce7657489b657640646a786
|
||||
guid: 6693b5fb3f035aa42bf27141ab05b01d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c315b7d2a7530784ab66ef5cc7d4d8b1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,131 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 多边形耳切法
|
||||
/// </summary>
|
||||
public class AFAuriculareCutting : ModuleAlgorithmFunction<DataPolygon> {
|
||||
public class Auriculare {
|
||||
public int index;
|
||||
public Vector3 aPoint;//+0
|
||||
public Vector3 bPoint;//-1
|
||||
public Vector3 cPoint;//+1
|
||||
}
|
||||
|
||||
/// <summary> 多边形耳切法 </summary>
|
||||
public AFAuriculareCutting() { }
|
||||
|
||||
public override void Compute(DataPolygon data) {
|
||||
List<Vector3> edgePoints = new List<Vector3>(data.edgePoints);
|
||||
List<DataTriangle> triangles = new List<DataTriangle>();
|
||||
Vector3[] allArray = edgePoints.ToArray();
|
||||
bool isClockWise = IsClockWise(allArray);
|
||||
//耳切法生成三角形
|
||||
ComputeAuriculare(triangles, edgePoints, allArray, isClockWise);
|
||||
data.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);
|
||||
if (temp.Count == 0) { return; }
|
||||
triangles.AddRange(temp);
|
||||
ComputeAuriculare(triangles, edgePoints, allArray, isClockWise);
|
||||
}
|
||||
/// <summary> 计算一个有效的耳点 </summary>
|
||||
public static List<DataTriangle> ComputeAuriculare(List<Vector3> edgePoints, Vector3[] allArray, bool isClockWise) {
|
||||
Vector3[] array = edgePoints.ToArray();
|
||||
List<DataTriangle> polygons = new List<DataTriangle>();
|
||||
for (int i = 0; i < array.Length; i++) {
|
||||
Auriculare auriculare = CreateAuriculare(i, array);
|
||||
// 等于180,大于180,不可能为耳点
|
||||
if (!GetAngleType(auriculare, isClockWise)) { continue; }
|
||||
// 包含其他点,不可能为耳点
|
||||
if (IsInsideTriangle(auriculare, allArray)) { continue; }
|
||||
// 包含其他耳点,不可能成为耳点
|
||||
if (!IsInsideAuriculare(auriculare, edgePoints)) { continue; }
|
||||
edgePoints.Remove(auriculare.aPoint);
|
||||
polygons.Add(CreateAuriculareToTriangle(auriculare));
|
||||
}
|
||||
return polygons;
|
||||
}
|
||||
/// <summary> 创建点 </summary>
|
||||
public static Auriculare CreateAuriculare(int index, Vector3[] array) {
|
||||
Auriculare auriculare = new Auriculare();
|
||||
auriculare.index = index;
|
||||
auriculare.bPoint = array.LoopIndex(index - 1);
|
||||
auriculare.aPoint = array.LoopIndex(index);
|
||||
auriculare.cPoint = array.LoopIndex(index + 1);
|
||||
return auriculare;
|
||||
}
|
||||
/// <summary> 计算三角形内是否包含其他点 </summary>
|
||||
public static bool IsInsideTriangle(Auriculare auriculare, Vector3[] array) {
|
||||
for (int i = 0; i < array.Length; i++) {
|
||||
if (array[i] == auriculare.aPoint) { continue; }
|
||||
if (array[i] == auriculare.bPoint) { continue; }
|
||||
if (array[i] == auriculare.cPoint) { continue; }
|
||||
if (IsInsideTriangle(auriculare, array[i])) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/// <summary> 计算三角形内是否包含其他点 </summary>
|
||||
public static bool IsInsideAuriculare(Auriculare auriculare, List<Vector3> edgePoints) {
|
||||
if (!edgePoints.Contains(auriculare.aPoint)) { return false; }
|
||||
if (!edgePoints.Contains(auriculare.bPoint)) { return false; }
|
||||
if (!edgePoints.Contains(auriculare.cPoint)) { return false; }
|
||||
return true;
|
||||
}
|
||||
/// <summary> 从节点创建三角形 </summary>
|
||||
public static DataTriangle CreateAuriculareToTriangle(Auriculare auriculare) {
|
||||
DataTriangle triangle = new DataTriangle();
|
||||
triangle.a = auriculare.aPoint;
|
||||
triangle.b = auriculare.bPoint;
|
||||
triangle.c = auriculare.cPoint;
|
||||
return triangle;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 算法
|
||||
/// <summary> 当前的点方向是否为顺时针 </summary>
|
||||
public static bool IsClockWise(Vector3[] array) {
|
||||
// 通过计算叉乘来确定方向
|
||||
float sum = 0f;
|
||||
double count = array.Length;
|
||||
Vector3 va, vb;
|
||||
for (int i = 0; i < array.Length; i++) {
|
||||
va = array[i];
|
||||
vb = (i == count - 1) ? array[0] : array[i + 1];
|
||||
sum += va.x * vb.y - va.y * vb.x;
|
||||
}
|
||||
return sum < 0;
|
||||
}
|
||||
/// <summary> 判断角的类型 </summary>
|
||||
public static bool GetAngleType(Auriculare auriculare, bool isClockWise) {
|
||||
// 角度是否小于180
|
||||
// oa & ob 之间的夹角,(右手法则)
|
||||
// 逆时针顺序是相反的
|
||||
Vector2 a = auriculare.aPoint;
|
||||
Vector2 b = auriculare.bPoint;
|
||||
Vector2 c = auriculare.cPoint;
|
||||
float f = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
|
||||
bool flag = isClockWise ? f > 0 : f < 0;
|
||||
if (f == 0) { return false;/*平角*/ }
|
||||
else if (flag) { return true;/*劣角*/ }
|
||||
else { return false;/*优角*/ }
|
||||
}
|
||||
/// <summary> p点是否在点a,b,c组成的三角形内,或边上 </summary>
|
||||
public static bool IsInsideTriangle(Auriculare auriculare, Vector2 p) {
|
||||
// p点是否在abc三角形内
|
||||
Vector2 a = auriculare.aPoint;
|
||||
Vector2 b = auriculare.bPoint;
|
||||
Vector2 c = auriculare.cPoint;
|
||||
float c1 = (b.x - a.x) * (p.y - b.y) - (b.y - a.y) * (p.x - b.x);
|
||||
float c2 = (c.x - b.x) * (p.y - c.y) - (c.y - b.y) * (p.x - c.x);
|
||||
float c3 = (a.x - c.x) * (p.y - a.y) - (a.y - c.y) * (p.x - a.x);
|
||||
return (c1 > 0f && c2 >= 0f && c3 >= 0f) || (c1 < 0f && c2 <= 0f && c3 <= 0f);
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e79a947f40825b54a8b65cb2714fbe6e
|
||||
guid: e9b83b680d622b5409fb9f74a1eaaebf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 三阶贝塞尔曲线计算边缘点
|
||||
/// </summary>
|
||||
public class AFEdgePoint : ModuleAlgorithmFunction<DataPolygon> {
|
||||
|
||||
/// <summary> 三阶贝塞尔曲线计算边缘点 </summary>
|
||||
public AFEdgePoint() { }
|
||||
|
||||
public override void Compute(DataPolygon data) {
|
||||
List<DataPoint> points = new List<DataPoint>(data.points);
|
||||
List<Vector3> edgePoints = new List<Vector3>();
|
||||
for (int i = 0; i < points.Count; i++) {
|
||||
DataPoint current = points.LoopIndex(i);
|
||||
DataPoint next = points.LoopIndex(i + 1);
|
||||
edgePoints.AddRange(CreateLine(current, next, data.edgeSmooth));
|
||||
}
|
||||
data.edgePoints = edgePoints;
|
||||
}
|
||||
|
||||
#region 函数
|
||||
public List<Vector3> CreateLine(DataPoint current, DataPoint next, float edgeSmooth) {
|
||||
List<Vector3> edgePoints = new List<Vector3>();
|
||||
//方向,距离
|
||||
Vector2 direction = (next.position - current.position).normalized;
|
||||
float distance = Vector2.Distance(next.position, current.position);
|
||||
//求余,得商数
|
||||
int quotient = Quotient(distance, edgeSmooth);
|
||||
//点位间距
|
||||
float segment = distance / quotient;
|
||||
//贝塞尔曲线点
|
||||
Vector3 ap = current.position;
|
||||
Vector3 bp = current.isCurveAfter ? current.afterBezier : current.position;
|
||||
Vector3 cp = next.isCurveFront ? next.frontBezier : next.position;
|
||||
Vector3 dp = next.position;
|
||||
for (int i = 0; i < quotient; i++) {
|
||||
float t = segment * i / distance;
|
||||
Vector2 position = ComputeBezier(ap, bp, cp, dp, t);
|
||||
edgePoints.Add(position);
|
||||
}
|
||||
return edgePoints;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 算法
|
||||
/// <summary> 商数 </summary>
|
||||
public static int Quotient(float distance, float edgeSmooth) {
|
||||
int a = (int)(distance * 1000);
|
||||
int b = (int)(edgeSmooth * 1000);
|
||||
return Math.DivRem(a, b, out int remainder);
|
||||
}
|
||||
/// <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;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e88d537872f0dba44ae4bda829b08c42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 合并三角形
|
||||
/// </summary>
|
||||
public class AFMergeTriangles : ModuleAlgorithmFunction<DataPolygon> {
|
||||
public override void Compute(DataPolygon data) {
|
||||
List<DataTriangle> triangles = new List<DataTriangle>(data.triangles);
|
||||
index = 0;
|
||||
MergeTriangles(triangles);
|
||||
data.triangles = triangles;
|
||||
ModuleCore.I.VisualPolygon.UpdateVisual(data);
|
||||
}
|
||||
private int index;
|
||||
private int maxIndex;
|
||||
/// <summary> 取一个三角形出来 匹配剩下的三角形 符合条件则合并 </summary>
|
||||
private void MergeTriangles(List<DataTriangle> triangles) {
|
||||
if (index > triangles.Count) { return; }
|
||||
|
||||
DataTriangle aT = triangles[0];
|
||||
triangles.Remove(aT);
|
||||
|
||||
maxIndex = triangles.Count;
|
||||
for (int i = 0; i < triangles.Count; i++) {
|
||||
DataTriangle bT = triangles[i];
|
||||
//ab同边
|
||||
if (MergeConditions(bT.a, bT.b, bT, ref aT)) { triangles.Remove(bT); continue; }
|
||||
//bc同边
|
||||
if (MergeConditions(bT.b, bT.c, bT, ref aT)) { triangles.Remove(bT); continue; }
|
||||
//ca同边
|
||||
if (MergeConditions(bT.c, bT.a, bT, ref aT)) { triangles.Remove(bT); continue; }
|
||||
}
|
||||
index = maxIndex == triangles.Count ? index + 1 : 0;
|
||||
Debug.Log($"{index} , {maxIndex} , {triangles.Count}");
|
||||
|
||||
triangles.Add(aT);
|
||||
MergeTriangles(triangles);
|
||||
}
|
||||
/// <summary> 匹配三角形 符合条件则合并 无法合并则返回 true </summary>
|
||||
private bool MergeTriangles(List<DataTriangle> triangles, DataTriangle aT) {
|
||||
for (int i = 0; i < triangles.Count; i++) {
|
||||
DataTriangle bT = triangles[i];
|
||||
//ab同边
|
||||
if (MergeConditions(bT.a, bT.b, bT, ref aT)) { triangles.Remove(bT); }
|
||||
//bc同边
|
||||
if (MergeConditions(bT.b, bT.c, bT, ref aT)) { triangles.Remove(bT); }
|
||||
//ca同边
|
||||
if (MergeConditions(bT.c, bT.a, bT, ref aT)) { triangles.Remove(bT); }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/// <summary> 计算三角形内是否包含其他点 </summary>
|
||||
private bool IsInsideTriangle(DataTriangle triangle, Vector3 point) {
|
||||
if (triangle.a == point) { return true; }
|
||||
if (triangle.b == point) { return true; }
|
||||
if (triangle.c == point) { return true; }
|
||||
return false;
|
||||
}
|
||||
//检测合并条件是否满足
|
||||
private bool MergeConditions(Vector3 a, Vector3 b, DataTriangle bT, ref DataTriangle aT) {
|
||||
if (!IsInsideTriangle(aT, a, b, out Vector3 o)) { return false; }
|
||||
if (!IsInsideTriangle(bT, a, b, out Vector3 c)) { return false; }
|
||||
if (IsInsideTriangle(aT, c)) { return true; }
|
||||
Vector3 oa = (o - a).normalized;
|
||||
Vector3 ob = (o - b).normalized;
|
||||
Vector3 oc = (o - c).normalized;
|
||||
if (oc == oa) { aT.a = o; aT.b = b; aT.c = c; return true; }
|
||||
if (oc == ob) { aT.a = o; aT.b = a; aT.c = c; return true; }
|
||||
return false;
|
||||
}
|
||||
/// <summary> 计算三角形内是否包含其他点 </summary>
|
||||
private bool IsInsideTriangle(DataTriangle triangle, Vector3 a, Vector3 b, out Vector3 o) {
|
||||
if (triangle.a == a && triangle.b == b) { o = triangle.c; return true; }
|
||||
if (triangle.a == b && triangle.b == a) { o = triangle.c; return true; }
|
||||
if (triangle.a == a && triangle.c == b) { o = triangle.b; return true; }
|
||||
if (triangle.a == b && triangle.c == a) { o = triangle.b; return true; }
|
||||
if (triangle.b == a && triangle.c == b) { o = triangle.a; return true; }
|
||||
if (triangle.b == b && triangle.c == a) { o = triangle.a; return true; }
|
||||
o = a; return false;
|
||||
}
|
||||
|
||||
/// <summary> p点是否在点a,b,c组成的三角形内,或边上 </summary>
|
||||
public static bool IsInsideTriangle(DataTriangle auriculare, Vector2 p) {
|
||||
// p点是否在abc三角形内
|
||||
Vector2 a = auriculare.a;
|
||||
Vector2 b = auriculare.b;
|
||||
Vector2 c = auriculare.c;
|
||||
float c1 = (b.x - a.x) * (p.y - b.y) - (b.y - a.y) * (p.x - b.x);
|
||||
float c2 = (c.x - b.x) * (p.y - c.y) - (c.y - b.y) * (p.x - c.x);
|
||||
float c3 = (a.x - c.x) * (p.y - a.y) - (a.y - c.y) * (p.x - a.x);
|
||||
return (c1 > 0f && c2 >= 0f && c3 >= 0f) || (c1 < 0f && c2 <= 0f && c3 <= 0f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45d3c753563f5be468680173acf8b1e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class AFSubdivision : ModuleAlgorithmFunction<DataPolygon> {
|
||||
public override void Compute(DataPolygon data) {
|
||||
List<DataTriangle> triangles = new List<DataTriangle>(data.triangles);
|
||||
List<DataTriangle> subdivision = new List<DataTriangle>();
|
||||
for (int i = 0; i < triangles.Count; i++) {
|
||||
subdivision.AddRange(Subdivision(triangles[i]));
|
||||
}
|
||||
//subdivision.AddRange(Subdivision(triangles[121], data.edgeSmooth));
|
||||
|
||||
data.triangles = subdivision;
|
||||
}
|
||||
private List<DataTriangle> Subdivision(DataTriangle triangle) {
|
||||
float ab = Vector3.Distance(triangle.a, triangle.b);
|
||||
float bc = Vector3.Distance(triangle.b, triangle.c);
|
||||
float ca = Vector3.Distance(triangle.c, triangle.a);
|
||||
if (ab > bc && ab > ca && ab > 0.02f) { return Subdivision(triangle.c, triangle.a, triangle.b); }
|
||||
if (bc > ab && bc > ca && bc > 0.02f) { return Subdivision(triangle.a, triangle.b, triangle.c); }
|
||||
if (ca > bc && ca > ab && ca > 0.02f) { return Subdivision(triangle.b, triangle.c, triangle.a); }
|
||||
|
||||
return new List<DataTriangle> { triangle };
|
||||
}
|
||||
private List<DataTriangle> Subdivision(Vector3 a, Vector3 b, Vector3 c) {
|
||||
Vector3 direction = b - c;
|
||||
Vector3 d = c + direction * 0.5f;
|
||||
|
||||
DataTriangle aT = new DataTriangle { a = a, b = d, c = c };
|
||||
DataTriangle bT = new DataTriangle { a = a, b = b, c = d };
|
||||
return new List<DataTriangle> { aT, bT, };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb4aa74668cf2134eb322b3a40d74c29
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 三角形转换网格
|
||||
/// </summary>
|
||||
public class AFTriangleMesh : ModuleAlgorithmFunction<DataPolygon> {
|
||||
public override void Compute(DataPolygon data) {
|
||||
List<DataTriangle> polygons = new List<DataTriangle>(data.triangles);
|
||||
//创建数据容器
|
||||
List<Vector3> vertices = new List<Vector3>();
|
||||
List<Vector2> uv = new List<Vector2>();
|
||||
List<int> triangles = new List<int>();
|
||||
//三角形合并
|
||||
for (int i = 0; i < polygons.Count; i++) {
|
||||
triangles.Add(AddIndexOf(vertices, polygons[i].a));
|
||||
triangles.Add(AddIndexOf(vertices, polygons[i].b));
|
||||
triangles.Add(AddIndexOf(vertices, polygons[i].c));
|
||||
}
|
||||
Debug.Log(vertices.Count);
|
||||
//展开uv (顶点去掉z坐标就是未缩放的平面UV)
|
||||
for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
|
||||
//附加数据
|
||||
data.polygon = new Mesh();
|
||||
data.polygon.vertices = vertices.ToArray();
|
||||
data.polygon.uv = uv.ToArray();
|
||||
data.polygon.triangles = triangles.ToArray();
|
||||
data.polygon.RecalculateBounds();
|
||||
data.polygon.RecalculateNormals();
|
||||
}
|
||||
//顶点列表不包含则添加点,获得索引
|
||||
private int AddIndexOf(List<Vector3> vertices, Vector3 a) {
|
||||
if (!vertices.Contains(a)) { vertices.Add(a); }
|
||||
return vertices.IndexOf(a);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e215bacbb6d0216408afb679ae863360
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 散列点生成多边形算法
|
||||
/// </summary>
|
||||
public class AlgorithmPolygon : ModuleAlgorithm<DataPlate> {
|
||||
private ModuleAlgorithmFunction<DataPolygon> EdgePoint = new AFEdgePoint();
|
||||
private ModuleAlgorithmFunction<DataPolygon> Cutting = new AFAuriculareCutting();
|
||||
private ModuleAlgorithmFunction<DataPolygon> Subdivision = new AFSubdivision();
|
||||
private ModuleAlgorithmFunction<DataPolygon> TriangleMesh = new AFTriangleMesh();
|
||||
|
||||
protected override void Awake() => ModuleCore.AlgorithmPolygon = this;
|
||||
|
||||
public override void Compute(DataPlate data) {
|
||||
DataPolygon polygon = new DataPolygon(data);
|
||||
//计算边缘点
|
||||
EdgePoint.Compute(polygon);
|
||||
//切割三角形
|
||||
Cutting.Compute(polygon);
|
||||
//合并三角形
|
||||
Subdivision.Compute(polygon);
|
||||
Subdivision.Compute(polygon);
|
||||
Subdivision.Compute(polygon);
|
||||
Subdivision.Compute(polygon);
|
||||
Subdivision.Compute(polygon);
|
||||
Subdivision.Compute(polygon);
|
||||
Subdivision.Compute(polygon);
|
||||
Subdivision.Compute(polygon);
|
||||
Subdivision.Compute(polygon);
|
||||
//三角形转换网格
|
||||
TriangleMesh.Compute(polygon);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad1a08fdeb67d3048a88c3668e3b6764
|
||||
guid: ef8ce839dfa79ff4d825f55925c48e7c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f504da41bfc887044b129dc255e092c2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class AssetsPlate : ModuleAssets<DataPlate> {
|
||||
private List<DataPlate> dataPlates = new List<DataPlate>();
|
||||
|
||||
/// <summary> 视图相机模块 </summary>
|
||||
private ModuleViewCamera ViewCameraDesign => ModuleCore.ViewCameraDesign;
|
||||
|
||||
public override int Count => dataPlates.Count;
|
||||
public override List<DataPlate> Datas => dataPlates;
|
||||
|
||||
protected override void Awake() => ModuleCore.AssetsPlate = this;
|
||||
|
||||
public override void Add(DataPlate data) {
|
||||
if (dataPlates.Contains(data)) { return; }
|
||||
dataPlates.Add(data);
|
||||
//初始化参数
|
||||
data.position = ViewCameraDesign.position;
|
||||
//生成可视化内容
|
||||
data.UpdateVisual();
|
||||
}
|
||||
public override void Remove(DataPlate data) {
|
||||
if (!dataPlates.Contains(data)) { return; }
|
||||
dataPlates.Remove(data);
|
||||
}
|
||||
public override DataPlate Find(int index) {
|
||||
return dataPlates.LoopIndex(index);
|
||||
}
|
||||
public override void ForEach(Action<DataPlate> action) {
|
||||
dataPlates.ForEach(action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1f4341af37c4904b8274f65dd58e837
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class AssetsPlatePresets : ModuleAssets<DataPlatePresets> {
|
||||
[SerializeField] private List<DataPlatePresets> assets;
|
||||
|
||||
public override int Count => assets.Count;
|
||||
public override List<DataPlatePresets> Datas => assets;
|
||||
|
||||
protected override void Awake() => ModuleCore.AssetsPlatePresets = this;
|
||||
|
||||
public override void Add(DataPlatePresets data) => assets.Add(data);
|
||||
public override void Remove(DataPlatePresets data) => assets.Remove(data);
|
||||
public override DataPlatePresets Find(int index) => assets.LoopIndex(index);
|
||||
public override void ForEach(Action<DataPlatePresets> action) => assets.ForEach(action);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 321aee0b32d39984085ac96e402e9c0b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3aff7fb266b16b642b5658e558c0c924
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BuilderInsertPointToPoint : ModuleBuilder<DataInsertPoint, DataPoint> {
|
||||
|
||||
protected override void Awake() => ModuleCore.InsertPointToPoint = this;
|
||||
|
||||
public override DataPoint To(DataInsertPoint insertPoint) {
|
||||
Vector3 position = insertPoint.position - insertPoint.plate.position;
|
||||
|
||||
DataPoint point = new DataPoint(insertPoint.plate);
|
||||
point.frontBezier = DataPointTool.DefaultBezier(position, insertPoint.aPoint.position);
|
||||
point.position = position;
|
||||
point.afterBezier = DataPointTool.DefaultBezier(position, insertPoint.bPoint.position);
|
||||
|
||||
int index = insertPoint.plate.points.IndexOf(insertPoint.aPoint);
|
||||
insertPoint.plate.points.Insert(index + 1, point);
|
||||
insertPoint.plate.UpdateVisual();
|
||||
|
||||
return point;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 992dfa55aae34c040a024d7743bb1a8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BuilderPlatePresetsToPlate : ModuleBuilder<DataPlatePresets, DataPlate> {
|
||||
|
||||
protected override void Awake() => ModuleCore.PlatePresetsToPlate = this;
|
||||
|
||||
public override DataPlate To(DataPlatePresets origin) {
|
||||
DataPlate dataPlate = new DataPlate();
|
||||
dataPlate.points = ToDataPoint(dataPlate, origin.designPoints);
|
||||
return dataPlate;
|
||||
}
|
||||
|
||||
private List<DataPoint> ToDataPoint(DataPlate dataPlate, List<Vector3> list) {
|
||||
List<DataPoint> points = new List<DataPoint>();
|
||||
|
||||
int maxIndex = list.Count - 1;
|
||||
|
||||
DataPoint start = new DataPoint(dataPlate);
|
||||
start.frontBezier = list[0] + DataPointTool.DefaultBezier(list[0], list[maxIndex]);
|
||||
start.position = list[0];
|
||||
start.afterBezier = list[0] + DataPointTool.DefaultBezier(list[0], list[1]);
|
||||
points.Add(start);
|
||||
|
||||
for (int i = 1; i < maxIndex; i++) {
|
||||
DataPoint dataPoint = new DataPoint(dataPlate);
|
||||
dataPoint.frontBezier = list[i] + DataPointTool.DefaultBezier(list[i], list[i - 1]);
|
||||
dataPoint.position = list[i];
|
||||
dataPoint.afterBezier = list[i] + DataPointTool.DefaultBezier(list[i], list[i + 1]);
|
||||
points.Add(dataPoint);
|
||||
}
|
||||
|
||||
DataPoint end = new DataPoint(dataPlate);
|
||||
end.frontBezier = list[maxIndex] + DataPointTool.DefaultBezier(list[maxIndex], list[maxIndex - 1]);
|
||||
end.position = list[maxIndex];
|
||||
end.afterBezier = list[maxIndex] + DataPointTool.DefaultBezier(list[maxIndex], list[0]);
|
||||
points.Add(end);
|
||||
|
||||
return points;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 476a9d6720db7284fae46d62e046095d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c91717fb961009a48af8b39c62eb5171
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6cbb5db737acfe4fae588472773f05f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class IDesignBezier : UIInputDesignUnit {
|
||||
/// <summary> 板片资产 </summary>
|
||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||
/// <summary> 查询点算法模块 </summary>
|
||||
public ModuleAlgorithm<DataFindBezier> AlgorithmFindBezier => ModuleCore.AlgorithmFindBezier;
|
||||
|
||||
private Vector3 mousePosition;
|
||||
private Vector3 originalPosition;
|
||||
private DataFindBezier findBezier;
|
||||
private void FindPoint(Vector3 localPosition) {
|
||||
findBezier = new DataFindBezier();
|
||||
findBezier.position = localPosition;
|
||||
findBezier.datas = AssetsPlate.Datas;
|
||||
AlgorithmFindBezier.Compute(findBezier);
|
||||
}
|
||||
|
||||
public override void MouseDown(DataUIMouseInput data) {
|
||||
FindPoint(data.WorldPosition);
|
||||
if (!findBezier.IsValid) { return; }
|
||||
mousePosition = data.ScreenPosition;
|
||||
originalPosition = findBezier.isFront ? findBezier.point.frontBezier : findBezier.point.afterBezier;
|
||||
}
|
||||
public override void MouseDrag(DataUIMouseInput data) {
|
||||
if (!findBezier.IsValid) { return; }
|
||||
Vector3 original = ViewCamera.ScreenToWorldPosition(mousePosition);
|
||||
Vector3 current = data.WorldPosition;
|
||||
Vector3 offset = current - original;
|
||||
if (findBezier.isFront) { findBezier.point.frontBezier = originalPosition + offset; }
|
||||
else { findBezier.point.afterBezier = originalPosition + offset; }
|
||||
findBezier.plate.UpdateVisual();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4c272ae3cc78a54c819d6b6194a75a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class IDesignInsert : UIInputDesignUnit {
|
||||
/// <summary> 板片资产 </summary>
|
||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||
/// <summary> 插入点算法模块 </summary>
|
||||
public ModuleAlgorithm<DataInsertPoint> AlgorithmInsertPoint => ModuleCore.AlgorithmInsertPoint;
|
||||
/// <summary> 插入点数据转换板片上的点 </summary>
|
||||
public ModuleBuilder<DataInsertPoint, DataPoint> InsertPointToPoint => ModuleCore.InsertPointToPoint;
|
||||
|
||||
private DataInsertPoint insertPoint;
|
||||
private void FindPoint(Vector3 localPosition) {
|
||||
insertPoint = new DataInsertPoint();
|
||||
insertPoint.position = localPosition;
|
||||
insertPoint.datas = AssetsPlate.Datas;
|
||||
AlgorithmInsertPoint.Compute(insertPoint);
|
||||
}
|
||||
|
||||
public override void MouseDown(DataUIMouseInput data) {
|
||||
FindPoint(data.WorldPosition);
|
||||
if (!insertPoint.IsValid) { return; }
|
||||
InsertPointToPoint.To(insertPoint);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6572c7ebab448a94d880fca85c728132
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class IDesignMobile : UIInputDesignUnit {
|
||||
/// <summary> 板片资产 </summary>
|
||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||
/// <summary> 查询点算法模块 </summary>
|
||||
public ModuleAlgorithm<DataFindPoint> AlgorithmFindPoint => ModuleCore.AlgorithmFindPoint;
|
||||
/// <summary> 广播查询数据模块 </summary>
|
||||
public ModuleSending<DataFindPoint> SendingFindPoint => ModuleCore.SendingFindPoint;
|
||||
|
||||
private Vector3 mousePosition;
|
||||
private Vector3 originalPosition;
|
||||
private DataFindPoint findPoint;
|
||||
private void FindPoint(Vector3 localPosition) {
|
||||
findPoint = new DataFindPoint();
|
||||
findPoint.position = localPosition;
|
||||
findPoint.datas = AssetsPlate.Datas;
|
||||
AlgorithmFindPoint.Compute(findPoint);
|
||||
}
|
||||
|
||||
public override void MouseDown(DataUIMouseInput data) {
|
||||
FindPoint(data.WorldPosition);
|
||||
SendingFindPoint.Change(findPoint);
|
||||
if (findPoint.IsValidPoint) { RecordPoint(data.ScreenPosition); return; }
|
||||
if (findPoint.IsValidPlate) { RecordPlate(data.ScreenPosition); return; }
|
||||
RecordCamera(data.ScreenPosition);
|
||||
}
|
||||
public override void MouseDrag(DataUIMouseInput data) {
|
||||
Vector3 original = ViewCamera.ScreenToWorldPosition(mousePosition);
|
||||
Vector3 current = data.WorldPosition;
|
||||
Vector3 offset = current - original;
|
||||
|
||||
if (findPoint.IsValidPoint) { MobilePoint(offset); return; }
|
||||
if (findPoint.IsValidPlate) { MobilePlate(offset); return; }
|
||||
MobileCamera(offset);
|
||||
}
|
||||
|
||||
private void RecordPoint(Vector3 screenPosition) {
|
||||
mousePosition = screenPosition;
|
||||
originalPosition = findPoint.point.position;
|
||||
}
|
||||
private void MobilePoint(Vector3 offset) {
|
||||
findPoint.point.position = originalPosition + offset;
|
||||
findPoint.plate.UpdateVisual();
|
||||
}
|
||||
|
||||
private void RecordPlate(Vector3 screenPosition) {
|
||||
mousePosition = screenPosition;
|
||||
originalPosition = findPoint.plate.position;
|
||||
}
|
||||
private void MobilePlate(Vector3 offset) {
|
||||
findPoint.plate.position = originalPosition + offset;
|
||||
findPoint.plate.UpdateVisual();
|
||||
}
|
||||
|
||||
private void RecordCamera(Vector3 screenPosition) {
|
||||
mousePosition = screenPosition;
|
||||
originalPosition = ViewCamera.position;
|
||||
}
|
||||
private void MobileCamera(Vector3 offset) {
|
||||
ViewCamera.position = originalPosition - offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebe339780ad7e11478aefbb1a97b9b51
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class IDesignScaleCamera : UIInputDesignUnit {
|
||||
public readonly float Min = 0.1f;
|
||||
public readonly float Max = 4f;
|
||||
public override void ScrollWheel(DataUIMouseInput data) {
|
||||
float size = ViewCamera.scale + data.ScrollWheel;
|
||||
size = Mathf.Clamp(size, Min, Max);
|
||||
ViewCamera.scale = Mathf.Lerp(ViewCamera.scale, size, Time.deltaTime * 20);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d241a760e6fc5d45bc735f6f3fbf881
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class IDesignSelect : UIInputDesignUnit {
|
||||
/// <summary> 板片资产 </summary>
|
||||
public ModuleAssets<DataPlate> AssetsPlate => ModuleCore.AssetsPlate;
|
||||
/// <summary> 查询点算法模块 </summary>
|
||||
public ModuleAlgorithm<DataFindPoint> AlgorithmFindPoint => ModuleCore.AlgorithmFindPoint;
|
||||
/// <summary> 广播查询数据模块 </summary>
|
||||
public ModuleSending<DataFindPoint> SendingFindPoint => ModuleCore.SendingFindPoint;
|
||||
|
||||
private DataFindPoint findPoint;
|
||||
private void FindPoint(Vector3 localPosition) {
|
||||
findPoint = new DataFindPoint();
|
||||
findPoint.position = localPosition;
|
||||
findPoint.datas = AssetsPlate.Datas;
|
||||
AlgorithmFindPoint.Compute(findPoint);
|
||||
}
|
||||
|
||||
public override void MouseDown(DataUIMouseInput data) {
|
||||
FindPoint(data.WorldPosition);
|
||||
SendingFindPoint.Change(findPoint);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ae4eed99f97b5e40a3ab2ee36fbd7ab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
/// <summary>
|
||||
/// 设计输入模块
|
||||
/// </summary>
|
||||
public class UIInputDesign : ModuleUIInput<UIInputDesignUnit> {
|
||||
private bool isDownMouseLeft;
|
||||
private bool isDownMouseRight;
|
||||
private bool isDownMouseMiddle;
|
||||
private UIInputDesignUnit leftInputUnit;
|
||||
private UIInputDesignUnit rightInputUnit;
|
||||
private UIInputDesignUnit middleInputUnit;
|
||||
private UIInputDesignUnit scrollInputUnit;
|
||||
|
||||
/// <summary> 设计视图相机模块 </summary>
|
||||
protected ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
||||
|
||||
public override UIInputDesignUnit Current => leftInputUnit;
|
||||
public override event Action<UIInputDesignUnit> OnChangeInput;
|
||||
public override void ChangeInput(UIInputDesignUnit input) {
|
||||
leftInputUnit = input;
|
||||
OnChangeInput?.Invoke(input);
|
||||
}
|
||||
|
||||
protected override void Awake() {
|
||||
ModuleCore.UIInputDesign = this;
|
||||
rightInputUnit = new IDesignMobile();
|
||||
middleInputUnit = new IDesignScaleCamera();
|
||||
scrollInputUnit = new IDesignScaleCamera();
|
||||
}
|
||||
|
||||
public override void Binding(VisualElement element) {
|
||||
element.RegisterCallback<MouseDownEvent>(MouseDown);
|
||||
element.RegisterCallback<MouseMoveEvent>(MouseMove);
|
||||
element.RegisterCallback<MouseUpEvent>(MouseRelease);
|
||||
element.RegisterCallback<MouseOutEvent>(MouseRelease);
|
||||
element.RegisterCallback<WheelEvent>(ScrollWheel);
|
||||
}
|
||||
|
||||
private void MouseDown(MouseDownEvent evt) {
|
||||
DataUIMouseInput data = CreateData(evt.localMousePosition, 0);
|
||||
if (evt.button == 0) { leftInputUnit.MouseDown(data); isDownMouseLeft = true; }
|
||||
if (evt.button == 1) { rightInputUnit.MouseDown(data); isDownMouseRight = true; }
|
||||
if (evt.button == 2) { middleInputUnit.MouseDown(data); isDownMouseMiddle = true; }
|
||||
}
|
||||
private void MouseMove(MouseMoveEvent evt) {
|
||||
DataUIMouseInput data = CreateData(evt.localMousePosition, 0);
|
||||
if (isDownMouseLeft) { leftInputUnit.MouseDrag(data); }
|
||||
if (isDownMouseRight) { rightInputUnit.MouseDrag(data); }
|
||||
if (isDownMouseMiddle) { middleInputUnit.MouseDrag(data); }
|
||||
if (evt.button == 0) { leftInputUnit.MouseMove(data); }
|
||||
if (evt.button == 1) { rightInputUnit.MouseMove(data); }
|
||||
if (evt.button == 2) { middleInputUnit.MouseMove(data); }
|
||||
}
|
||||
private void MouseRelease(MouseUpEvent evt) {
|
||||
DataUIMouseInput data = CreateData(evt.localMousePosition, 0);
|
||||
leftInputUnit.MouseRelease(data); isDownMouseLeft = false;
|
||||
rightInputUnit.MouseRelease(data); isDownMouseRight = false;
|
||||
middleInputUnit.MouseRelease(data); isDownMouseMiddle = false;
|
||||
}
|
||||
private void MouseRelease(MouseOutEvent evt) {
|
||||
DataUIMouseInput data = CreateData(evt.localMousePosition, 0);
|
||||
leftInputUnit.MouseRelease(data); isDownMouseLeft = false;
|
||||
rightInputUnit.MouseRelease(data); isDownMouseRight = false;
|
||||
middleInputUnit.MouseRelease(data); isDownMouseMiddle = false;
|
||||
}
|
||||
private void ScrollWheel(WheelEvent evt) {
|
||||
DataUIMouseInput data = CreateData(evt.localMousePosition, evt.delta.y);
|
||||
scrollInputUnit.ScrollWheel(data);
|
||||
}
|
||||
|
||||
private DataUIMouseInput CreateData(Vector2 localMousePosition, float scrollWheel) {
|
||||
DataUIMouseInput data = new DataUIMouseInput();
|
||||
data.ScrollWheel = scrollWheel;
|
||||
data.ViewPosition = ViewCamera.ScreenToViewPosition(localMousePosition);
|
||||
data.WorldPosition = ViewCamera.ScreenToWorldPosition(localMousePosition);
|
||||
data.ScreenPosition = localMousePosition;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
public abstract class UIInputDesignUnit {
|
||||
/// <summary> 核心模块 </summary>
|
||||
protected virtual ModuleCore ModuleCore => ModuleCore.I;
|
||||
/// <summary> 设计视图相机模块 </summary>
|
||||
protected ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
||||
|
||||
/// <summary> 按下鼠标 </summary>
|
||||
public virtual void MouseDown(DataUIMouseInput data) { }
|
||||
/// <summary> 拖拽鼠标 </summary>
|
||||
public virtual void MouseDrag(DataUIMouseInput data) { }
|
||||
/// <summary> 移动鼠标 </summary>
|
||||
public virtual void MouseMove(DataUIMouseInput data) { }
|
||||
/// <summary> 释放鼠标 </summary>
|
||||
public virtual void MouseRelease(DataUIMouseInput data) { }
|
||||
/// <summary> 鼠标滚轮 </summary>
|
||||
public virtual void ScrollWheel(DataUIMouseInput data) { }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9cf538c2c848fc4ca95d1f860f11acc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f004983677b94854a81359ae3a4fc1db
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class SendingFindPoint : ModuleSending<DataFindPoint> {
|
||||
private DataFindPoint findPoint;
|
||||
|
||||
public override DataFindPoint Current => findPoint;
|
||||
public override event Action<DataFindPoint> OnChange;
|
||||
public override void Change(DataFindPoint findPoint) {
|
||||
this.findPoint = findPoint;
|
||||
OnChange?.Invoke(findPoint);
|
||||
}
|
||||
|
||||
protected override void Awake() => ModuleCore.SendingFindPoint = this;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e4ee0e36af29af418b3610ad98cf21b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class SendingPlate : ModuleSending<DataPlate> {
|
||||
private DataPlate dataPlate;
|
||||
|
||||
public override DataPlate Current => dataPlate;
|
||||
public override event Action<DataPlate> OnChange;
|
||||
public override void Change(DataPlate dataPlate) {
|
||||
this.dataPlate = dataPlate;
|
||||
OnChange?.Invoke(dataPlate);
|
||||
}
|
||||
|
||||
protected override void Awake() => ModuleCore.SendingPlate = this;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcf91dd8e722ae845823651d7bc71333
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class SendingPoint : ModuleSending<DataPoint> {
|
||||
private DataPoint dataPoint;
|
||||
|
||||
public override DataPoint Current => dataPoint;
|
||||
public override event Action<DataPoint> OnChange;
|
||||
public override void Change(DataPoint dataPoint) {
|
||||
this.dataPoint = dataPoint;
|
||||
OnChange?.Invoke(dataPoint);
|
||||
}
|
||||
|
||||
protected override void Awake() => ModuleCore.SendingPoint = this;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffb8e2a96363fce4aadc0da4ba2a1ed9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3063fa7c3cf9fc547b47b9b541920f5d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 739c91aa6278a1d42ac00a82ac36616c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class UIPanelBaking : 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: 4a1ee2e53bd64f2449c39cdf466cf48f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class UIPanelDesign : ModuleUIPanel {
|
||||
|
||||
#region UI元素
|
||||
public override VisualElement Element => ModuleUIPage.Q<VisualElement>("PlateDesign");
|
||||
public VisualElement Rendering => Element.Q<VisualElement>("Rendering");
|
||||
public Button Button1 => Element.Q<Button>("Button1");
|
||||
public Button Button2 => Element.Q<Button>("Button2");
|
||||
public Button Button3 => Element.Q<Button>("Button3");
|
||||
public Button Button4 => Element.Q<Button>("Button4");
|
||||
public Button Button5 => Element.Q<Button>("Button5");
|
||||
#endregion
|
||||
|
||||
#region 引用模块
|
||||
/// <summary> 设计视图相机模块 </summary>
|
||||
public ModuleViewCamera ViewCamera => ModuleCore.ViewCameraDesign;
|
||||
/// <summary> 设计UI输入模块 </summary>
|
||||
public ModuleUIInput<UIInputDesignUnit> UIInputDesign => ModuleCore.UIInputDesign;
|
||||
#endregion
|
||||
|
||||
public override void Awake() {
|
||||
Element.generateVisualContent += Element_GenerateVisualContent;
|
||||
Button1.clicked += () => { UIInputDesign.ChangeInput(new IDesignMobile()); };
|
||||
Button2.clicked += () => { UIInputDesign.ChangeInput(new IDesignInsert()); };
|
||||
Button3.clicked += () => { UIInputDesign.ChangeInput(new IDesignBezier()); };
|
||||
Button4.clicked += () => { UIInputDesign.ChangeInput(new IDesignSelect()); };
|
||||
Button5.clicked += () => { UIInputDesign.ChangeInput(new IDesignSelect()); };
|
||||
}
|
||||
private void Start() {
|
||||
UIInputDesign.Binding(Rendering);
|
||||
UIInputDesign.OnChangeInput += UIInputDesign_OnChangeInput;
|
||||
UIInputDesign.ChangeInput(new IDesignMobile());
|
||||
}
|
||||
|
||||
#region 更新视图
|
||||
private void Element_GenerateVisualContent(MeshGenerationContext context) {
|
||||
StartCoroutine(UpdateRenderTexture());
|
||||
}
|
||||
private IEnumerator UpdateRenderTexture() {
|
||||
yield return null;
|
||||
int width = (int)Element.resolvedStyle.width;
|
||||
int height = (int)Element.resolvedStyle.height;
|
||||
ViewCamera.UpdateRenderTexture(width, height);
|
||||
Background background = Background.FromRenderTexture(ViewCamera.RenderTexture);
|
||||
StyleBackground style = new StyleBackground(background);
|
||||
Rendering.style.backgroundImage = style;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 输入功能
|
||||
private void UIInputDesign_OnChangeInput(UIInputDesignUnit obj) {
|
||||
Type type = obj.GetType();
|
||||
ButtonStyleChange(type, typeof(IDesignMobile), Button1);
|
||||
ButtonStyleChange(type, typeof(IDesignInsert), Button2);
|
||||
ButtonStyleChange(type, typeof(IDesignBezier), Button3);
|
||||
}
|
||||
private void ButtonStyleChange(Type obj, Type compare, Button button) {
|
||||
if (obj == compare) { button.AddToClassList("pd-button-s"); }
|
||||
else { button.RemoveFromClassList("pd-button-s"); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 141e3035b49c87441bdd757f6d978c1e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using MuHua;
|
||||
|
||||
public class UIPanelInspect : ModuleUIPanel {
|
||||
|
||||
#region UI元素
|
||||
public override VisualElement Element => ModuleUIPage.Q<VisualElement>("Inspect");
|
||||
public VisualElement PlateSettings => Element.Q<VisualElement>("PlateSettings");
|
||||
public VisualElement PointSettings => Element.Q<VisualElement>("PointSettings");
|
||||
#endregion
|
||||
|
||||
#region 引用模块
|
||||
/// <summary> 广播查询数据模块 </summary>
|
||||
public ModuleSending<DataFindPoint> SendingFindPoint => ModuleCore.SendingFindPoint;
|
||||
#endregion
|
||||
|
||||
private DataPlate Plate => SendingFindPoint.Current.plate;
|
||||
private DataPoint Point => SendingFindPoint.Current.point;
|
||||
|
||||
private UIPlateSettings uiPlateSettings;
|
||||
private UIPointSettings uiPointSettings;
|
||||
public override void Awake() {
|
||||
uiPlateSettings = new UIPlateSettings(PlateSettings);
|
||||
|
||||
uiPointSettings = new UIPointSettings(PointSettings);
|
||||
uiPointSettings.Toggle1.OnChange += (value) => { Point.isCurveFront = value; Plate.UpdateVisual(); };
|
||||
uiPointSettings.Toggle2.OnChange += (value) => { Point.isCurveAfter = value; Plate.UpdateVisual(); };
|
||||
}
|
||||
|
||||
private void Start() {
|
||||
SendingFindPoint.OnChange += SendingFindPoint_OnChange;
|
||||
}
|
||||
|
||||
private void SendingFindPoint_OnChange(DataFindPoint obj) {
|
||||
PointSettings.style.display = DisplayStyle.None;
|
||||
PlateSettings.style.display = DisplayStyle.None;
|
||||
if (obj.IsValidPoint) { UpdateUIPointSettings(); return; }
|
||||
if (obj.IsValidPlate) { UpdateUIPlateSettings(); return; }
|
||||
}
|
||||
private void UpdateUIPlateSettings() {
|
||||
PlateSettings.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
private void UpdateUIPointSettings() {
|
||||
PointSettings.style.display = DisplayStyle.Flex;
|
||||
uiPointSettings.Toggle1.SetValue(Point.isCurveFront);
|
||||
uiPointSettings.Toggle2.SetValue(Point.isCurveAfter);
|
||||
}
|
||||
|
||||
public class UIPlateSettings {
|
||||
public readonly VisualElement element;
|
||||
public UIPlateSettings(VisualElement element) => this.element = element;
|
||||
}
|
||||
public class UIPointSettings {
|
||||
public readonly VisualElement element;
|
||||
public VisualElement Bezier => element.Q<VisualElement>("Bezier");
|
||||
public MUToggle Toggle1 => element.Q<MUToggle>("Toggle1");
|
||||
public MUToggle Toggle2 => element.Q<MUToggle>("Toggle2");
|
||||
public UIPointSettings(VisualElement element) => this.element = element;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e19ef8edf7b1d7844838898350516ef8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 112b83d554c0b1c47b6654c490c692b7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class UIPageGlobal : ModuleUIPage {
|
||||
protected override void Awake() => ModuleCore.GlobalPage = this;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8b1855b5fed0e041878548696f2afbe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23fd5b1b4a536aa47a60881556c8e716
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ViewCameraBaking : 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: 802326651d2bc7442aa201a7859a30e2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ViewCameraDesign : ModuleViewCamera {
|
||||
public Camera viewCamera;
|
||||
public Transform viewSpace;
|
||||
private RenderTexture renderTexture;
|
||||
private readonly Vector3 CameraOffset = new Vector3(0, 0, -2);
|
||||
|
||||
protected override void Awake() => ModuleCore.ViewCameraDesign = this;
|
||||
|
||||
public override Vector3 position {
|
||||
get => viewCamera.transform.localPosition - CameraOffset;
|
||||
set => viewCamera.transform.localPosition = value + CameraOffset;
|
||||
}
|
||||
public override Vector3 eulerAngles {
|
||||
get => viewCamera.transform.eulerAngles;
|
||||
set => viewCamera.transform.eulerAngles = value;
|
||||
}
|
||||
public override float scale {
|
||||
get => viewCamera.orthographicSize;
|
||||
set => viewCamera.orthographicSize = value;
|
||||
}
|
||||
public override RenderTexture RenderTexture {
|
||||
get => renderTexture;
|
||||
}
|
||||
|
||||
public override void UpdateRenderTexture(int x, int y) {
|
||||
renderTexture = new RenderTexture(x, y, 0);
|
||||
viewCamera.targetTexture = renderTexture;
|
||||
}
|
||||
public override Vector3 ScreenToViewPosition(Vector3 screenPosition) {
|
||||
float x = screenPosition.x / viewCamera.pixelWidth;
|
||||
float y = 1 - screenPosition.y / viewCamera.pixelHeight;
|
||||
Vector3 mouseRatio = new Vector3(x - 0.5f, y - 0.5f);
|
||||
float aspectRatio = (float)viewCamera.pixelWidth / viewCamera.pixelHeight;
|
||||
return new Vector3(mouseRatio.x * aspectRatio, mouseRatio.y) * 2;
|
||||
}
|
||||
public override Vector3 ScreenToWorldPosition(Vector3 screenPosition) {
|
||||
return ScreenToViewPosition(screenPosition) * scale + position;
|
||||
}
|
||||
public override Vector3 ViewToScreenPosition(Vector3 screenPosition) {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
public override Vector3 ViewToWorldPosition(Vector3 screenPosition) {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
public override Vector3 WorldToScreenPosition(Vector3 screenPosition) {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
public override Vector3 WorldToViewPosition(Vector3 screenPosition) {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c639043240fd73545af704b1a6b52895
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 147f3f6086f4a504ba7edb9ae6282915
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class VisualPlate : ModuleVisual<DataPlate> {
|
||||
public Transform viewSpace;
|
||||
public Transform platePrefab;
|
||||
public Transform edgeLinePrefab;
|
||||
|
||||
protected override void Awake() => ModuleCore.VisualPlate = this;
|
||||
|
||||
public override void UpdateVisual(DataPlate data) {
|
||||
if (data.transform == null) { CreateTransform(data); }
|
||||
data.transform.localPosition = data.position;
|
||||
data.polygonMeshFilter.mesh = data.polygon;
|
||||
if (data.edgeLineRenderer == null) { CreateEdgeLineRenderer(data); }
|
||||
data.edgeLineRenderer.positionCount = data.edgePoints.Count;
|
||||
data.edgeLineRenderer.SetPositions(data.edgePoints.ToArray());
|
||||
//更新全部数据点的可视化内容
|
||||
data.points.ForEach(ModuleCore.VisualPoint.UpdateVisual);
|
||||
}
|
||||
|
||||
private void CreateTransform(DataPlate data) {
|
||||
Transform temp = Instantiate(platePrefab, viewSpace);
|
||||
temp.gameObject.SetActive(true);
|
||||
data.transform = temp;
|
||||
data.polygonMeshFilter = temp.GetComponent<MeshFilter>();
|
||||
}
|
||||
private void CreateEdgeLineRenderer(DataPlate data) {
|
||||
Transform temp = Instantiate(edgeLinePrefab, data.transform);
|
||||
temp.gameObject.SetActive(true);
|
||||
data.edgeLineRenderer = temp.GetComponent<LineRenderer>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce128d679e2869147a5b5306cef090e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,72 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class VisualPoint : ModuleVisual<DataPoint> {
|
||||
public Transform pointPrefab;//预设
|
||||
public Transform bezierPrefab;//贝塞尔点预设
|
||||
public Transform linePrefab;//线渲染器预设
|
||||
|
||||
protected override void Awake() => ModuleCore.VisualPoint = this;
|
||||
|
||||
public override void UpdateVisual(DataPoint data) {
|
||||
if (data.transform == null) { CreateTransform(data); }
|
||||
data.transform.localPosition = data.position;
|
||||
//贝塞尔曲线可视内容
|
||||
if (data.isCurveFront) { FrontBezier(data); }
|
||||
else { ReleaseBezier(data.frontBezierTransform, data.frontBezierLineRenderer); }
|
||||
if (data.isCurveAfter) { AfterBezier(data); }
|
||||
else { ReleaseBezier(data.afterBezierTransform, data.afterBezierLineRenderer); }
|
||||
}
|
||||
|
||||
/// <summary> 创建和改变 前贝塞尔点(-) 的可视内容 </summary>
|
||||
private void FrontBezier(DataPoint data) {
|
||||
if (data.frontBezierTransform == null) {
|
||||
data.frontBezierTransform = CreateBezierTransform(data);
|
||||
}
|
||||
if (data.frontBezierLineRenderer == null) {
|
||||
data.frontBezierLineRenderer = CreateBezierLineRenderer(data);
|
||||
}
|
||||
Vector3 position = (data.frontBezier - data.position) * 50;
|
||||
data.frontBezierTransform.localPosition = position;
|
||||
data.frontBezierLineRenderer.SetPosition(1, position);
|
||||
}
|
||||
/// <summary> 创建和改变 后贝塞尔点(+) 的可视内容 </summary>
|
||||
private void AfterBezier(DataPoint data) {
|
||||
if (data.afterBezierTransform == null) {
|
||||
data.afterBezierTransform = CreateBezierTransform(data);
|
||||
}
|
||||
if (data.afterBezierLineRenderer == null) {
|
||||
data.afterBezierLineRenderer = CreateBezierLineRenderer(data);
|
||||
}
|
||||
Vector3 position = (data.afterBezier - data.position) * 50;
|
||||
data.afterBezierTransform.localPosition = position;
|
||||
data.afterBezierLineRenderer.SetPosition(1, position);
|
||||
}
|
||||
/// <summary> 释放贝塞尔点可视内容 </summary>
|
||||
private void ReleaseBezier(Transform transform, LineRenderer lineRenderer) {
|
||||
if (transform != null) { Destroy(transform.gameObject); }
|
||||
if (lineRenderer != null) { Destroy(lineRenderer.gameObject); }
|
||||
}
|
||||
|
||||
#region 创建
|
||||
private void CreateTransform(DataPoint data) {
|
||||
Transform parent = data.plate.transform;
|
||||
data.transform = Instantiate(pointPrefab, parent);
|
||||
data.transform.gameObject.SetActive(true);
|
||||
}
|
||||
private Transform CreateBezierTransform(DataPoint data) {
|
||||
Transform parent = data.transform;
|
||||
Transform temp = Instantiate(bezierPrefab, parent);
|
||||
temp.gameObject.SetActive(true);
|
||||
return temp;
|
||||
}
|
||||
private LineRenderer CreateBezierLineRenderer(DataPoint data) {
|
||||
Transform parent = data.transform;
|
||||
Transform temp = Instantiate(linePrefab, parent);
|
||||
temp.gameObject.SetActive(true);
|
||||
return temp.GetComponent<LineRenderer>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 058d9230544d654458aaff125e23ad03
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using MuHua;
|
||||
|
||||
public class VisualPolygon : ModuleVisual<DataPolygon> {
|
||||
public Transform parent;//预设
|
||||
public Transform trianglePrefab;//三角形预设
|
||||
public Transform pointPrefab;//贝塞尔点预设
|
||||
|
||||
protected override void Awake() => ModuleCore.VisualPolygon = this;
|
||||
|
||||
public override void UpdateVisual(DataPolygon data) {
|
||||
List<DataTriangle> triangles = new List<DataTriangle>(data.triangles);
|
||||
parent.DestroySon();
|
||||
for (int i = 0; i < triangles.Count; i++) {
|
||||
CreateTriangle(triangles[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
#region 创建
|
||||
private void CreateTriangle(DataTriangle data, int index) {
|
||||
Transform triangle = Instantiate(trianglePrefab, parent);
|
||||
triangle.gameObject.SetActive(true);
|
||||
triangle.gameObject.name = index.ToString();
|
||||
|
||||
CreatePoint(data.a, triangle, "a");
|
||||
CreatePoint(data.b, triangle, "b");
|
||||
CreatePoint(data.c, triangle, "c");
|
||||
}
|
||||
private void CreatePoint(Vector3 position, Transform parent, string name) {
|
||||
Transform temp = Instantiate(pointPrefab, parent);
|
||||
temp.gameObject.SetActive(true);
|
||||
temp.localPosition = position;
|
||||
temp.gameObject.name = name;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff1be4cbf1a81844cb1d8f6b8c840ab8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,111 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using MuHua;
|
||||
|
||||
public class PlateDesign : ModulePlateDesign {
|
||||
public Transform PlateParent;
|
||||
public Transform PlateTemplate;
|
||||
|
||||
private DataPlate dataPlate;
|
||||
|
||||
public override void AddData(DataPlate data) {
|
||||
PlateParent.Instantiate(PlateTemplate, data, true);
|
||||
}
|
||||
|
||||
#region 边缘点操作
|
||||
private PrefabPlateEdge edgePoint;
|
||||
public override bool IsValidEdgePoint => edgePoint != null;
|
||||
public override Vector3 EdgePointPosition => edgePoint.CurrentPosition;
|
||||
public override void SelectEdgePoint(Vector3 screenPosition) {
|
||||
edgePoint = RayFind<PrefabPlateEdge>(screenPosition, DefaultLayerMask);
|
||||
if (!IsValidEdgePoint) { return; }
|
||||
dataPlate = edgePoint.value;
|
||||
}
|
||||
public override void ChangeEdgePoint(Vector3 localPosition) {
|
||||
if (!IsValidEdgePoint) { return; }
|
||||
dataPlate.ChangeEdgePoint(edgePoint.index, localPosition);
|
||||
}
|
||||
public override void InsertEdgePoint(Vector3 screenPosition) {
|
||||
Vector3 position = ViewCamera.ScreenToWorldPosition(screenPosition);
|
||||
Vector3 worldPosition = position + ViewCamera.CameraWorldPosition;
|
||||
worldPosition.z = 0;
|
||||
edgePoint = Physics2DOverlapCircleAll<PrefabPlateEdge>(worldPosition, DefaultLayerMask);
|
||||
if (!IsValidEdgePoint) { return; }
|
||||
dataPlate = edgePoint.value;
|
||||
dataPlate?.InsertEdgePoint(edgePoint.index, position);
|
||||
}
|
||||
public override void ReleaseEdgePoint() {
|
||||
if (!IsValidEdgePoint) { return; }
|
||||
dataPlate.Compute();
|
||||
edgePoint = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 设计点操作
|
||||
private PrefabDesignPoint designPoint;
|
||||
public override bool IsValidDesignPoint => designPoint != null;
|
||||
public override Vector3 DesignPointPosition => designPoint.Position;
|
||||
public override void SelectDesignPoint(Vector3 screenPosition) {
|
||||
designPoint = RayFind<PrefabDesignPoint>(screenPosition, DefaultLayerMask);
|
||||
if (!IsValidDesignPoint) { return; }
|
||||
dataPlate = designPoint.DataPlate;
|
||||
}
|
||||
public override void ChangeDesignPoint(Vector3 localPosition) {
|
||||
if (!IsValidDesignPoint) { return; }
|
||||
dataPlate.ChangeDesignPoint(designPoint.Index, localPosition);
|
||||
}
|
||||
public override void InsertDesignPoint(Vector3 screenPosition) {
|
||||
Vector3 position = ViewCamera.ScreenToWorldPosition(screenPosition);
|
||||
Vector3 worldPosition = position + ViewCamera.CameraWorldPosition;
|
||||
worldPosition.z = 0;
|
||||
designPoint = Physics2DOverlapCircleAll<PrefabDesignPoint>(worldPosition, DefaultLayerMask);
|
||||
if (!IsValidDesignPoint) { return; }
|
||||
dataPlate = designPoint.DataPlate;
|
||||
dataPlate?.InsertDesignPoint(designPoint.Index, position);
|
||||
}
|
||||
public override void ReleaseDesignPoint() {
|
||||
if (!IsValidDesignPoint) { return; }
|
||||
dataPlate.Compute();
|
||||
designPoint = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 贝塞尔曲线操作
|
||||
private PrefabBezierPoint bezierPoint;
|
||||
public override bool IsValidBezierPoint => bezierPoint != null;
|
||||
public override Vector3 BezierPointPosition => bezierPoint.Position;
|
||||
public override void SelectBezierPoint(Vector3 screenPosition) {
|
||||
bezierPoint = RayFind<PrefabBezierPoint>(screenPosition, DefaultLayerMask);
|
||||
if (!IsValidBezierPoint) { return; }
|
||||
dataPlate = bezierPoint.DataPlate;
|
||||
}
|
||||
public override void ChangeBezierPoint(Vector3 localPosition) {
|
||||
if (!IsValidBezierPoint) { return; }
|
||||
bezierPoint.Change(localPosition);
|
||||
}
|
||||
public override void ReleaseBezierPoint() {
|
||||
if (!IsValidBezierPoint) { return; }
|
||||
dataPlate.Compute();
|
||||
bezierPoint = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 检测方法
|
||||
private RaycastHit hitInfo;
|
||||
private readonly float CheckRange = 0.02f;
|
||||
private readonly LayerMask DefaultLayerMask = ~(1 << 0) | 1 << 0;
|
||||
/// <summary> 射线检测 </summary>
|
||||
private T RayFind<T>(Vector3 screenPosition, LayerMask layerMask) where T : Object {
|
||||
Ray ray = ViewCamera.ScreenPointToRay(screenPosition);
|
||||
Physics.Raycast(ray, out hitInfo, 200, layerMask);
|
||||
return hitInfo.transform?.GetComponent<T>();
|
||||
}
|
||||
/// <summary> 物理2D圆形检测 </summary>
|
||||
private T Physics2DOverlapCircleAll<T>(Vector3 worldPosition, LayerMask layerMask) where T : Object {
|
||||
Collider2D[] colliders = Physics2D.OverlapCircleAll(worldPosition, CheckRange, layerMask);
|
||||
if (colliders.Length == 0) { return null; }
|
||||
return colliders[0].GetComponentInParent<T>();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b896900f689abba438628c5bbef5125f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
using MuHua;
|
||||
|
||||
public class SceneLoader : ModuleScene {
|
||||
public Slider progressBar;
|
||||
public override IEnumerator ILoadSceneAsync(string scene) {
|
||||
int disableProgress = 0;
|
||||
int toProgress = 0;
|
||||
AsyncOperation ao = SceneManager.LoadSceneAsync(scene);
|
||||
ao.allowSceneActivation = false;
|
||||
transform.SonActive(true);
|
||||
while (ao.progress < 0.9f) {
|
||||
toProgress = (int)(ao.progress * 100);
|
||||
while (disableProgress < toProgress) {
|
||||
++disableProgress;
|
||||
progressBar.value = disableProgress / 100.0f;//0.01开始
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
}
|
||||
toProgress = 100;
|
||||
while (disableProgress < toProgress) {
|
||||
++disableProgress;
|
||||
progressBar.value = disableProgress / 100.0f;
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
ao.allowSceneActivation = true;
|
||||
while (!ao.isDone) {
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
transform.SonActive(false);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8965d99865432b844a65b6ea6960406c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,24 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class UIPageGarmentSewing : ModuleUIPage {
|
||||
private TopMenu topMenu;
|
||||
private UIPlateDesign plateDesign;
|
||||
private UIPlateBaking plateBaking;
|
||||
private VisualElement TopMenuElement => Q<VisualElement>("TopMenu");
|
||||
private VisualElement PlateDesignElement => Q<VisualElement>("PlateDesign");
|
||||
private VisualElement PlateBakingElement => Q<VisualElement>("PlateBaking");
|
||||
protected override void Awake() {
|
||||
ModuleCore.CurrentPage = this;
|
||||
}
|
||||
private void Start() {
|
||||
topMenu = new TopMenu(TopMenuElement);
|
||||
plateDesign = new UIPlateDesign(PlateDesignElement);
|
||||
plateBaking = new UIPlateBaking(PlateBakingElement);
|
||||
|
||||
topMenu.ClickTopMenu1 = () => { };
|
||||
topMenu.ClickTopMenu2 = () => { ModuleCore.PresetsPlateWindow.Open(null); };
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d436e806ac6755d4fb29cdb0f7208615
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28c2a70ea090a674a9f12dd415abbec9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class UIWindowPresetsPlate : ModuleUIWindow<Action> {
|
||||
public VisualTreeAsset PresetsPlateUnitAsset;
|
||||
private UIPresetsPlate presetsPlate;
|
||||
private VisualElement element => ModuleUIPage.Q<VisualElement>("PresetsPlate");
|
||||
private ModuleAssets<DataPresetsPlate> PresetsPlateAssets => ModuleCore.PresetsPlateAssets;
|
||||
public override void Awake() {
|
||||
ModuleCore.PresetsPlateWindow = this;
|
||||
presetsPlate = new UIPresetsPlate(element);
|
||||
|
||||
presetsPlate.ClickClose = Close;
|
||||
}
|
||||
public override void Open(Action data) {
|
||||
element.style.display = DisplayStyle.Flex;
|
||||
presetsPlate.Clear();
|
||||
PresetsPlateAssets.ForEach(Create);
|
||||
}
|
||||
public override void Close() {
|
||||
presetsPlate.Clear();
|
||||
element.style.display = DisplayStyle.None;
|
||||
}
|
||||
private void Create(DataPresetsPlate data) {
|
||||
VisualElement temp = PresetsPlateUnitAsset.Instantiate();
|
||||
UIPresetsPlateUnit unit = new UIPresetsPlateUnit(temp, data);
|
||||
unit.Click = () => { CreateTemplate(data); };
|
||||
presetsPlate.Add(unit);
|
||||
}
|
||||
private void CreateTemplate(DataPresetsPlate data) {
|
||||
ModuleCore.PlateDesign.AddData(data.ToPlate());
|
||||
Close();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a930d912222858846a23606c170a59d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,57 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Video;
|
||||
|
||||
[RequireComponent(typeof(VideoPlayer))]
|
||||
public class VideoSystem : ModuleVideo {
|
||||
public Vector2Int renderSize = new Vector2Int(1920, 1080);
|
||||
|
||||
private int index;
|
||||
private RenderTexture rTexture;
|
||||
private List<DataVideo> videoDatas = new List<DataVideo>();
|
||||
private VideoPlayer videoPlayer => GetComponent<VideoPlayer>();
|
||||
|
||||
protected override void Awake() {
|
||||
base.Awake();
|
||||
rTexture = new RenderTexture(renderSize.x, renderSize.y, 0);
|
||||
videoPlayer.targetTexture = rTexture;
|
||||
}
|
||||
protected override bool IsPlaying() => videoPlayer.isPlaying;
|
||||
protected override Vector2Int VideoCount() => new Vector2Int(index, videoDatas.Count);
|
||||
protected override RenderTexture RenderTexture() => rTexture;
|
||||
protected override double Time() => videoPlayer.clockTime;
|
||||
protected override double MaxTime() => videoPlayer.length;
|
||||
protected override long GetFrame() => videoPlayer.frame;
|
||||
protected override void SetFrame(long value) => videoPlayer.frame = value;
|
||||
protected override ulong FrameCount() => videoPlayer.frameCount;
|
||||
|
||||
public override void Play() {
|
||||
videoDatas[index].SetPlayer(videoPlayer);
|
||||
videoPlayer.Play();
|
||||
}
|
||||
public override void Pause() {
|
||||
videoPlayer.Pause();
|
||||
}
|
||||
public override void Stop() {
|
||||
videoPlayer.Stop();
|
||||
}
|
||||
public override void SetIndex(int value) {
|
||||
if (videoDatas.Count == 0) { Debug.LogError("没有视频可以播放!"); Stop(); return; }
|
||||
if (value < 0) { value = videoDatas.Count - 1; }
|
||||
if (value >= videoDatas.Count) { value = 0; }
|
||||
index = value; Play();
|
||||
}
|
||||
public override void AddIndex(int value) {
|
||||
SetIndex(index + value);
|
||||
}
|
||||
|
||||
public override void SetValue(DataVideo value) {
|
||||
index = 0;
|
||||
videoDatas = new List<DataVideo> { value };
|
||||
}
|
||||
public override void SetValue(List<DataVideo> list) {
|
||||
index = 0;
|
||||
videoDatas = list;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6341a66658f1184e82fba981a431514
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c1f6f992590ee740829401bdf9c7486
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,42 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary> 未初始化的视图相机模块 </summary>
|
||||
public class ViewCamera : ModuleViewCamera {
|
||||
public Camera viewCamera;
|
||||
public Transform viewSpace;
|
||||
|
||||
private RenderTexture renderTexture;
|
||||
|
||||
public override Vector3 Position { get => viewSpace.position; set => viewSpace.position = value; }
|
||||
public override Vector3 EulerAngles { get => viewSpace.eulerAngles; set => viewSpace.eulerAngles = value; }
|
||||
public override Vector3 LocalScale { get => viewSpace.localScale; set => viewSpace.localScale = value; }
|
||||
public override float OrthographicSize { get => viewCamera.orthographicSize; set => viewCamera.orthographicSize = value; }
|
||||
public override Vector3 CurrentViewSpaceCenter => viewSpace.localPosition * -1;
|
||||
public override Vector3 CameraWorldPosition => viewCamera.transform.position;
|
||||
public override RenderTexture RenderTexture => renderTexture;
|
||||
|
||||
protected override void Awake() {
|
||||
Debug.LogError("需要重写 ViewCamera 的 Awake 方法!");
|
||||
}
|
||||
public override void UpdateRenderTexture(int x, int y) {
|
||||
renderTexture = new RenderTexture(x, y, 0);
|
||||
viewCamera.targetTexture = renderTexture;
|
||||
}
|
||||
public override Vector2 ScreenToWorldPosition(Vector2 screenPosition) {
|
||||
return ScreenToViewPosition(screenPosition) * OrthographicSize;
|
||||
}
|
||||
public override Vector2 ScreenToViewPosition(Vector2 screenPosition) {
|
||||
float x = screenPosition.x / viewCamera.pixelWidth;
|
||||
float y = 1 - screenPosition.y / viewCamera.pixelHeight;
|
||||
Vector2 mouseRatio = new Vector2(x - 0.5f, y - 0.5f);
|
||||
float aspectRatio = (float)viewCamera.pixelWidth / viewCamera.pixelHeight;
|
||||
return new Vector2(mouseRatio.x * aspectRatio, mouseRatio.y) * 2;
|
||||
}
|
||||
public override Ray ScreenPointToRay(Vector2 screenPosition) {
|
||||
Vector3 mousePosition = ScreenToWorldPosition(screenPosition);
|
||||
Vector3 worldPosition = mousePosition + viewCamera.transform.position;
|
||||
return new Ray(worldPosition, viewCamera.transform.forward);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c9c4560364683648a17a66d4b7999fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ViewCameraPlateBaking : ViewCamera {
|
||||
protected override void Awake() {
|
||||
ModuleCore.PlateBakingViewCamera = this;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9eaab06c8ab27c4b8bad8ce8e831751
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ViewCameraPlateDesign : ViewCamera {
|
||||
protected override void Awake() {
|
||||
ModuleCore.PlateDesignViewCamera = this;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97f4f71f456807b4d959311475ce9687
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user