144 lines
4.5 KiB
C#
144 lines
4.5 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using Object = UnityEngine.Object;
|
||
|
||
//============================================================
|
||
//支持中文,文件使用UTF-8编码
|
||
//@author JiphuTzu
|
||
//@create 20220910
|
||
//@company Umawerse
|
||
//
|
||
//@description:
|
||
//============================================================
|
||
namespace Umawerse.FiniteStateMachines
|
||
{
|
||
public class PolygonDrawState : DrawingState
|
||
{
|
||
private Mesh _mesh;
|
||
private LineRenderer _line;
|
||
public PolygonDrawState(ToolsBootstrap root) : base(root, StateName.polygon, 3, 99)
|
||
{
|
||
}
|
||
|
||
protected override void OnTap(Vector3 pos)
|
||
{
|
||
AddPoint(pos);
|
||
}
|
||
|
||
protected override void OnDoubleTap(Vector3 pos)
|
||
{
|
||
AddPoint(pos);
|
||
}
|
||
|
||
protected override void UpdatePreview(Vector3 pos)
|
||
{
|
||
var verts = new List<Vector3>();
|
||
verts.AddRange(vertices);
|
||
verts.Add(pos);
|
||
Show(verts);
|
||
}
|
||
|
||
public override void Init()
|
||
{
|
||
base.Init();
|
||
_mesh = new Mesh();
|
||
target.AddComponent<MeshFilter>().mesh = _mesh;
|
||
var renderer = target.AddComponent<MeshRenderer>();
|
||
renderer.material = root.ployMaterial;
|
||
renderer.material.color = Color.green;
|
||
//
|
||
var mr = new GameObject("LineRender");
|
||
mr.transform.SetParent(target.transform);
|
||
_line = mr.AddComponent<LineRenderer>();
|
||
_line.sortingOrder = -1;
|
||
_line.startWidth = 0.3f;
|
||
_line.endWidth = 0.3f;
|
||
_line.numCornerVertices = 3;
|
||
_line.material = root.solidLineMaterial;
|
||
_line.material.color = Color.green;
|
||
}
|
||
|
||
public override void Complete()
|
||
{
|
||
Show(vertices);
|
||
var mc = target.AddComponent<MeshCollider>();
|
||
//var label = Object.Instantiate(root.labelPrefab, target.transform);
|
||
//label.Init($"面积:", false);
|
||
//label.SetPosition(mc.bounds.center + Vector3.up);
|
||
//label.SetAlignment();
|
||
}
|
||
|
||
|
||
|
||
public override void AddPoint(Vector3 position, bool showImmediately = true)
|
||
{
|
||
vertices.Add(position);
|
||
if (showImmediately)
|
||
{
|
||
var h = vertices[0].y > position.y ? vertices[0].y : position.y;
|
||
for (var i = 0; i < vertices.Count; i++)
|
||
{
|
||
var v = vertices[i];
|
||
v.y = h;
|
||
vertices[i] = v;
|
||
if (i + 1 < target.transform.childCount)
|
||
target.transform.GetChild(i + 1).position = v;
|
||
}
|
||
}
|
||
var ployPoint = Object.Instantiate(root.ployPointPrefab, target.transform);
|
||
ployPoint.transform.localPosition = vertices[vertices.Count - 1];
|
||
var mr = ployPoint.GetComponent<MeshRenderer>();
|
||
mr.material.SetColor(COLOR_ID, Color.green);
|
||
mr.sortingOrder = 2;
|
||
|
||
if (vertices.Count < 3 || !showImmediately) return;
|
||
Show(vertices);
|
||
}
|
||
|
||
private void Show(List<Vector3> verts)
|
||
{
|
||
var triangles = new List<int>();
|
||
for (var i = 2; i < verts.Count; i++)
|
||
{
|
||
triangles.Add(0);
|
||
if (IsUp(verts[i] - verts[0], verts[i - 1] - verts[0]))
|
||
{
|
||
triangles.Add(i);
|
||
triangles.Add(i - 1);
|
||
}
|
||
else
|
||
{
|
||
triangles.Add(i - 1);
|
||
triangles.Add(i);
|
||
}
|
||
|
||
}
|
||
_mesh.vertices = verts.ToArray();
|
||
_mesh.triangles = triangles.ToArray();
|
||
//
|
||
var vs = new Vector3[verts.Count + 1];
|
||
verts.CopyTo(vs);
|
||
vs[vs.Length - 1] = vs[0];
|
||
_line.positionCount = vs.Length;
|
||
_line.SetPositions(vs);
|
||
_line.material.SetFloat("_Cnt", GetLength(vs) / 3);
|
||
}
|
||
|
||
private bool IsUp(Vector3 a, Vector3 b)
|
||
{
|
||
var nor = Vector3.Cross(a, b);
|
||
var angle = Vector3.Dot(nor, Vector3.up);
|
||
return angle > 0;
|
||
}
|
||
private float GetLength(Vector3[] verts)
|
||
{
|
||
var length = 0f;
|
||
for (var i = 1; i < verts.Length; i++)
|
||
{
|
||
length += Vector3.Distance(verts[i], verts[i - 1]);
|
||
}
|
||
return length;
|
||
}
|
||
}
|
||
}
|