You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.0 KiB
172 lines
5.0 KiB
namespace Mapbox.Unity.MeshGeneration.Modifiers
|
|
{
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using Mapbox.Unity.MeshGeneration.Data;
|
|
using Assets.Mapbox.Unity.MeshGeneration.Modifiers.MeshModifiers;
|
|
|
|
[CreateAssetMenu(menuName = "Mapbox/Modifiers/Loft Modifier")]
|
|
public class LoftModifier : MeshModifier
|
|
{
|
|
public override ModifierType Type { get { return ModifierType.Preprocess; } }
|
|
public GameObject Slice;
|
|
public bool _closeEdges = false;
|
|
public float SliceScaleMultiplier = 1;
|
|
|
|
private int _counter = 0;
|
|
private List<Vector3> _slice;
|
|
private int _sliceCount;
|
|
private float _sliceTotalMagnitude;
|
|
private Vector2[] _sliceUvs;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
_slice = new List<Vector3>();
|
|
foreach (Transform tr in Slice.transform)
|
|
{
|
|
_slice.Add(tr.position);
|
|
}
|
|
_sliceCount = _slice.Count;
|
|
|
|
_sliceTotalMagnitude = 0;
|
|
for (int i = 0; i < _sliceCount - 1; i++)
|
|
{
|
|
_sliceTotalMagnitude += (_slice[i + 1] - _slice[i]).magnitude;
|
|
}
|
|
_sliceUvs = new Vector2[_sliceCount];
|
|
_sliceUvs[0] = new Vector2(0, 0);
|
|
for (int i = 0; i < _sliceCount - 1; i++)
|
|
{
|
|
_sliceUvs[i + 1] = new Vector2(0, _sliceUvs[i].y + (_slice[i + 1] - _slice[i]).magnitude / _sliceTotalMagnitude);
|
|
}
|
|
}
|
|
|
|
public override void Run(VectorFeatureUnity feature, MeshData md, UnityTile tile = null)
|
|
{
|
|
if (feature.Points.Count < 1)
|
|
return;
|
|
|
|
foreach (var roadSegment in feature.Points)
|
|
{
|
|
_counter = roadSegment.Count;
|
|
if (_counter <= 1)
|
|
continue;
|
|
|
|
var vl = new List<Vector3>(_sliceCount * _counter);
|
|
var edges = new List<Vector3>(_counter);
|
|
int co = 0;
|
|
|
|
for (int j = 0; j < _counter; j++)
|
|
{
|
|
var current = Constants.Math.Vector3Zero;
|
|
|
|
current = roadSegment[j];
|
|
Vector3 dirCurrent, dir1, dir2;
|
|
if (j > 0 && j < (_counter - 1))
|
|
{
|
|
dir1 = (roadSegment[j] - roadSegment[j - 1]).normalized;
|
|
dir2 = (roadSegment[j + 1] - roadSegment[j]).normalized;
|
|
dirCurrent = (dir2 + dir1).normalized;
|
|
}
|
|
else if (j == 0) //first
|
|
{
|
|
dirCurrent = (roadSegment[j + 1] - roadSegment[j]).normalized;
|
|
}
|
|
else //last
|
|
{
|
|
dirCurrent = (roadSegment[j] - roadSegment[j - 1]).normalized;
|
|
}
|
|
var q = Quaternion.LookRotation(dirCurrent);
|
|
|
|
co = _slice.Count;
|
|
for (int i = 0; i < co; i++)
|
|
{
|
|
var p = (q * _slice[i]) * SliceScaleMultiplier;
|
|
vl.Add(p + current);
|
|
if (i == co - 1) //last item capped
|
|
{
|
|
edges.Add(p + current);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (md.Triangles.Count == 0)
|
|
{
|
|
md.Triangles.Add(new List<int>());
|
|
}
|
|
md.Vertices.Capacity = md.Vertices.Count + (vl.Count - _sliceCount) * 4;
|
|
md.Normals.Capacity = md.Normals.Count + (vl.Count - _sliceCount) * 4;
|
|
md.Triangles.Capacity = md.Triangles.Count + (vl.Count - _sliceCount) * 6;
|
|
|
|
var uvDist = 0f;
|
|
float edMag = 0f, h = 0f;
|
|
co = 0;
|
|
Vector3 norm;
|
|
|
|
for (int i = 0; i < _counter - 1; i++)
|
|
{
|
|
for (int j = 0; j < _sliceCount - 1; j++)
|
|
{
|
|
var ind = i * _sliceCount + j;
|
|
var ed = vl[ind + _sliceCount] - vl[ind];
|
|
edMag = ed.magnitude;
|
|
co = md.Vertices.Count;
|
|
norm = Vector3.Cross(vl[ind] - vl[ind + 1], vl[ind + _sliceCount] - vl[ind]).normalized;
|
|
md.Vertices.Add(vl[ind]);
|
|
md.Vertices.Add(vl[ind + 1]);
|
|
md.Vertices.Add(vl[ind + _sliceCount]);
|
|
md.Vertices.Add(vl[ind + _sliceCount + 1]);
|
|
|
|
h = (float)j / _sliceCount;
|
|
|
|
md.UV[0].Add(new Vector2(uvDist, ((float)j - 1) / _sliceCount));
|
|
md.UV[0].Add(new Vector2(uvDist, h));
|
|
md.UV[0].Add(new Vector2(uvDist + edMag, ((float)j - 1) / _sliceCount));
|
|
md.UV[0].Add(new Vector2(uvDist + edMag, h));
|
|
|
|
md.Tangents.Add(new Vector4(ed.normalized.x, ed.normalized.y, ed.normalized.z, 1));
|
|
md.Tangents.Add(new Vector4(ed.normalized.x, ed.normalized.y, ed.normalized.z, 1));
|
|
md.Tangents.Add(new Vector4(ed.normalized.x, ed.normalized.y, ed.normalized.z, 1));
|
|
md.Tangents.Add(new Vector4(ed.normalized.x, ed.normalized.y, ed.normalized.z, 1));
|
|
|
|
md.Normals.Add(norm);
|
|
md.Normals.Add(norm);
|
|
md.Normals.Add(norm);
|
|
md.Normals.Add(norm);
|
|
|
|
md.Triangles[0].Add(co);
|
|
md.Triangles[0].Add(co + 2);
|
|
md.Triangles[0].Add(co + 1);
|
|
|
|
md.Triangles[0].Add(co + 1);
|
|
md.Triangles[0].Add(co + 2);
|
|
md.Triangles[0].Add(co + 3);
|
|
}
|
|
uvDist += edMag;
|
|
}
|
|
|
|
if (_closeEdges && edges.Count > 2)
|
|
{
|
|
if (md.Triangles.Count < 2)
|
|
{
|
|
md.Triangles.Add(new List<int>());
|
|
}
|
|
|
|
var flatData = EarcutLibrary.Flatten(new List<List<Vector3>>() { edges });
|
|
var result = EarcutLibrary.Earcut(flatData.Vertices, flatData.Holes, flatData.Dim);
|
|
|
|
md.Triangles[1].AddRange(result.Select(x => md.Vertices.Count + x).ToList());
|
|
for (int i = 0; i < edges.Count; i++)
|
|
{
|
|
md.Vertices.Add(edges[i]);
|
|
md.Normals.Add(Constants.Math.Vector3Up);
|
|
md.UV[0].Add(new Vector2(edges[i].x, edges[i].z));
|
|
md.Tangents.Add(new Vector4(1,0,0,1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|