一、演算法
畫線可以簡化為正八棱柱
演算法為:
兩點A,B 向量AB 求向量AB的任意垂直向量,旋轉垂直向量獲得正半邊形的頂點,通過頂點繪制三角形網格
二、實作
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 畫線
public class MeshLine
{
private Material material; // 材質
private RepeatSegmentMesh segment_mesh;
private RenderObject render_object;
private MeshEnableFlag flag;
public MeshLine()
{
this.material = GlobalAppData.Instance.Data.line_material;
render_object = RenderObject.Create(null, null, Vector3.zero, Quaternion.identity);
render_object.mesh_render.material = material;
render_object.mesh_render.castShadows = true;
render_object.mesh_render.receiveShadows = true;
render_object.go.name = "MeshLine";
//Light light = render_object.mesh_filter.GetComponent<Lighting>();
flag = MeshEnableFlag.Vertice | MeshEnableFlag.Normal | MeshEnableFlag.Triangle | MeshEnableFlag.Color | MeshEnableFlag.UV;
segment_mesh = new RepeatSegmentMesh(3,3, 100, flag);
segment_mesh.SegmentData.MarkTriangleTopology();
}
public static Vector3 GetVerticalDir(Vector3 _dir) // 計算垂直向量
{
if (_dir.z == 0)
{
return new Vector3(0, 0, -1);
}
else
{
return new Vector3(-_dir.z / _dir.x, 0, 1).normalized;
}
}
// 增加線段
public void AddLine(Vector3 start, Vector3 end, Color color , float radius = 0.1f)
{
int num = 8;
int angle = 360 / num;
Vector3 dir = (end - start).normalized; // 取得向量AB
var vertical = GetVerticalDir(dir).normalized; // 垂直于AB的向量v
for (int i = 1; i <= 8; i++)
{
var r = Quaternion.AngleAxis(i * angle, dir) * vertical; // 繞AB旋轉angle度
var r1 = Quaternion.AngleAxis((i + 1) * angle, dir) * vertical; // angle * i度
var p1 = (r * radius) + start; // 開始正八邊形頂點1
var p2 = (r1 * radius) + start; // 開始正八邊形頂點2
var p3 = (r * radius) + end; // 結束正八邊形頂點1
var p4 = (r1 * radius) + end; // 結束正八邊形頂點2
segment_mesh.SegmentData.SetTriangleVertice(0, start, p2, p1); // 底部三角形
segment_mesh.SegmentData.SetColor(color);
segment_mesh.AddSegmentData(flag);
segment_mesh.SegmentData.SetTriangleVertice(0, end, p3, p4); // 頂部三角形
segment_mesh.SegmentData.SetColor(color);
segment_mesh.AddSegmentData(flag);
segment_mesh.SegmentData.SetTriangleVertice(0, p1, p2, p4); // 柱狀三角形1
segment_mesh.SegmentData.SetColor(color);
segment_mesh.AddSegmentData(flag);
segment_mesh.SegmentData.SetTriangleVertice(0, p3, p1, p4); // 柱狀三角形2
segment_mesh.SegmentData.SetColor(color);
segment_mesh.AddSegmentData(flag);
}
segment_mesh.CopyToMesh(render_object.mesh_filter.mesh, true);
render_object.mesh_filter.mesh.RecalculateNormals();
}
// 增加多段線
public void AddLine(List<Vector3> points, Color color , float radius = 0.1f)
{
for (int i = 1; i < points.Count; i++)
{
AddLine(points[i -1], points[i], color, radius);
}
}
// 清除
public void Clear()
{
segment_mesh.SetSegmentCount(0);
segment_mesh.CopyToMesh(render_object.mesh_filter.mesh, true);
render_object.mesh_filter.mesh.RecalculateNormals();
}
}
使用:
MeshLine mesh_line = new MeshLine();
mesh_line.AddLine(new Vector3(2,2,0), new Vector3(10,10,10), Color.yellow, 0.1f);
List<Vector3> list = new List<Vector3>();
list.Add(new Vector3(1, 1, 1));
list.Add(new Vector3(10, 1, 1));
list.Add(new Vector3(1, 1, 10));
list.Add(new Vector3(1, 10, 1));
mesh_line.AddLine(list, Color.yellow);
三、效果

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/241424.html
標籤:其他
上一篇:Jquery實驗2
