Skip to content

Commit 9720ddd

Browse files
authored
Merge pull request #61 from tangrams/constant-uvs
wip: Generate UVs for polylines and polygons
2 parents 5cc9f88 + 40daf89 commit 9720ddd

29 files changed

+1189
-790
lines changed

Assets/Editor/MapzenMapEditor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ private void LogWarnings()
141141
{
142142
foreach (var style in mapzenMap.FeatureStyling)
143143
{
144+
if (style == null)
145+
{
146+
Debug.LogWarning("'Null' style provided in feature styling collection");
147+
continue;
148+
}
149+
144150
if (style.FilterStyles.Count == 0)
145151
{
146152
Debug.LogWarning("The style " + style.name + " has no filter");

Assets/Editor/PolygonBuilderEditor.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using UnityEngine;
22
using UnityEditor;
33
using Mapzen;
4+
using System.Linq;
45
using Mapzen.Unity;
56
using System;
67

@@ -10,6 +11,9 @@ public class PolygonBuilderEditor : EditorBase
1011
[SerializeField]
1112
private bool show;
1213

14+
[SerializeField]
15+
private int selectedExtrusionType = -1;
16+
1317
public PolygonBuilderEditor()
1418
: base()
1519
{
@@ -20,7 +24,7 @@ public static PolygonBuilder.Options DefaultOptions()
2024
{
2125
var defaultOptions = new PolygonBuilder.Options();
2226

23-
defaultOptions.Extrude = true;
27+
defaultOptions.Extrusion = PolygonBuilder.ExtrusionType.TopAndSides;
2428
defaultOptions.Enabled = true;
2529
defaultOptions.MaxHeight = 0.0f;
2630

@@ -49,8 +53,16 @@ public PolygonBuilder.Options OnInspectorGUI(PolygonBuilder.Options options)
4953
return options;
5054
}
5155

56+
if (selectedExtrusionType == -1)
57+
{
58+
selectedExtrusionType = (int) options.Extrusion;
59+
}
60+
5261
options.MaxHeight = EditorGUILayout.FloatField("Max Height: ", options.MaxHeight);
53-
options.Extrude = EditorGUILayout.Toggle("Extrude: ", options.Extrude);
62+
var extrusionTypeList = Enum.GetValues(typeof(PolygonBuilder.ExtrusionType)).Cast<PolygonBuilder.ExtrusionType>();
63+
var extrusionTypeStringList = extrusionTypeList.Select(type => type.ToString());
64+
selectedExtrusionType = EditorGUILayout.Popup("Extrusion type: ", selectedExtrusionType, extrusionTypeStringList.ToArray());
65+
options.Extrusion = (PolygonBuilder.ExtrusionType) selectedExtrusionType;
5466
options.Enabled = EditorGUILayout.Toggle("Enabled: ", options.Enabled);
5567

5668
SavePreferences();

Assets/Editor/PolylineBuilderEditor.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using UnityEditor;
33
using Mapzen;
44
using Mapzen.Unity;
5+
using System.Linq;
56
using System;
67

78
[Serializable]
@@ -10,6 +11,9 @@ public class PolylineBuilderEditor : EditorBase
1011
[SerializeField]
1112
private bool show;
1213

14+
[SerializeField]
15+
private int selectedExtrusionType = -1;
16+
1317
public PolylineBuilderEditor()
1418
: base()
1519
{
@@ -20,7 +24,7 @@ public static PolylineBuilder.Options DefaultOptions()
2024
{
2125
var defaultOptions = new PolylineBuilder.Options();
2226

23-
defaultOptions.Extrude = true;
27+
defaultOptions.Extrusion = PolygonBuilder.ExtrusionType.TopAndSides;
2428
defaultOptions.Enabled = true;
2529
defaultOptions.MaxHeight = 3.0f;
2630
defaultOptions.MiterLimit = 3.0f;
@@ -51,9 +55,17 @@ public PolylineBuilder.Options OnInspectorGUI(PolylineBuilder.Options options)
5155
return options;
5256
}
5357

58+
if (selectedExtrusionType == -1)
59+
{
60+
selectedExtrusionType = (int) options.Extrusion;
61+
}
62+
5463
options.Width = EditorGUILayout.FloatField("Width: ", options.Width);
5564
options.MaxHeight = EditorGUILayout.FloatField("Max Height: ", options.MaxHeight);
56-
options.Extrude = EditorGUILayout.Toggle("Extrude: ", options.Extrude);
65+
var extrusionTypeList = Enum.GetValues(typeof(PolygonBuilder.ExtrusionType)).Cast<PolygonBuilder.ExtrusionType>();
66+
var extrusionTypeStringList = extrusionTypeList.Select(type => type.ToString());
67+
selectedExtrusionType = EditorGUILayout.Popup("Extrusion type:", selectedExtrusionType, extrusionTypeStringList.ToArray());
68+
options.Extrusion = (PolygonBuilder.ExtrusionType) selectedExtrusionType;
5769
options.Enabled = EditorGUILayout.Toggle("Enabled: ", options.Enabled);
5870

5971
SavePreferences();

Assets/Mapzen/Unity/Earcut.cs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,15 @@ public class Earcut
2020
private static extern uint ReleaseTesselationContext(uint context);
2121

2222
[DllImport(LibraryName, EntryPoint = "TesselatePolygon")]
23-
private static extern void TesselatePolygon(uint context, IntPtr points, IntPtr rings, int nRings, out int nIndices, out int nVertices);
23+
private static extern void TesselatePolygon(uint context, IntPtr points, IntPtr rings, int nRings, out int nIndices);
2424

2525
[DllImport(LibraryName, EntryPoint = "GetIndices")]
2626
private static extern void GetIndices(uint context, IntPtr indices);
2727

28-
[DllImport(LibraryName, EntryPoint = "GetVertices")]
29-
private static extern void GetVertices(uint context, IntPtr vertices);
30-
3128
private uint contextId;
3229

3330
public int[] Indices { get; internal set; }
3431

35-
public float[] Vertices { get; internal set; }
36-
3732
public Earcut()
3833
{
3934
contextId = CreateTesselationContext();
@@ -42,28 +37,23 @@ public Earcut()
4237

4338
public void Tesselate(float[] points, int[] rings)
4439
{
45-
int nVertices = 0;
4640
int nIndices = 0;
4741

4842
GCHandle pointsBufferHandle = GCHandle.Alloc(points, GCHandleType.Pinned);
4943
GCHandle ringsBufferHandle = GCHandle.Alloc(rings, GCHandleType.Pinned);
5044

51-
TesselatePolygon(contextId, pointsBufferHandle.AddrOfPinnedObject(), ringsBufferHandle.AddrOfPinnedObject(), rings.Length, out nIndices, out nVertices);
45+
TesselatePolygon(contextId, pointsBufferHandle.AddrOfPinnedObject(), ringsBufferHandle.AddrOfPinnedObject(), rings.Length, out nIndices);
5246

5347
pointsBufferHandle.Free();
5448
ringsBufferHandle.Free();
5549

5650
Indices = new int[nIndices];
57-
Vertices = new float[nVertices * 2];
5851

5952
GCHandle indicesBufferHandle = GCHandle.Alloc(Indices, GCHandleType.Pinned);
60-
GCHandle verticesBufferHandle = GCHandle.Alloc(Vertices, GCHandleType.Pinned);
6153

6254
GetIndices(contextId, indicesBufferHandle.AddrOfPinnedObject());
63-
GetVertices(contextId, verticesBufferHandle.AddrOfPinnedObject());
6455

6556
indicesBufferHandle.Free();
66-
verticesBufferHandle.Free();
6757
}
6858

6959
public void Release()

Assets/Mapzen/Unity/FeatureStyle.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public List<Matcher> Matchers
106106

107107
public IFeatureMatcher GetFeatureMatcher()
108108
{
109-
IFeatureMatcher matcher = null;
109+
IFeatureMatcher matcher = new FeatureMatcher();
110110

111111
if (IsCompound() && matchers.Count > 0)
112112
{

Assets/Mapzen/Unity/MeshData.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ public class MeshBucket
1616
{
1717
public List<Submesh> Submeshes;
1818
public List<Vector3> Vertices;
19+
public List<Vector2> UVs;
1920

2021
public MeshBucket()
2122
{
2223
Vertices = new List<Vector3>();
24+
UVs = new List<Vector2>();
2325
Submeshes = new List<Submesh>();
2426
}
2527
}
@@ -33,7 +35,7 @@ public MeshData()
3335
Meshes = new List<MeshBucket>();
3436
}
3537

36-
public void AddElements(IEnumerable<Vector3> vertices, IEnumerable<int> indices, Material material)
38+
public void AddElements(IEnumerable<Vector3> vertices, IEnumerable<Vector2> uvs, IEnumerable<int> indices, Material material)
3739
{
3840
var vertexList = new List<Vector3>(vertices);
3941
int vertexCount = vertexList.Count;
@@ -59,6 +61,7 @@ public void AddElements(IEnumerable<Vector3> vertices, IEnumerable<int> indices,
5961

6062
int offset = bucket.Vertices.Count;
6163
bucket.Vertices.AddRange(vertexList);
64+
bucket.UVs.AddRange(uvs);
6265

6366
// Find a submesh with this material, or create a new one.
6467
Submesh submesh = null;

Assets/Mapzen/Unity/PolygonBuilder.cs

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Linq;
23
using Mapzen.VectorData;
34
using UnityEngine;
45
using System;
@@ -7,11 +8,19 @@ namespace Mapzen.Unity
78
{
89
public class PolygonBuilder : IGeometryHandler
910
{
11+
[Serializable]
12+
public enum ExtrusionType
13+
{
14+
TopOnly,
15+
TopAndSides,
16+
SidesOnly,
17+
}
18+
1019
[Serializable]
1120
public struct Options
1221
{
1322
public Material Material;
14-
public bool Extrude;
23+
public ExtrusionType Extrusion;
1524
public float MinHeight;
1625
public float MaxHeight;
1726
public bool Enabled;
@@ -27,7 +36,9 @@ public PolygonBuilder(MeshData outputMeshData, Options options, Matrix4x4 transf
2736
this.lastPoint = new Point();
2837
this.pointsInRing = 0;
2938
this.extrusionVertices = new List<Vector3>();
39+
this.extrusionUVs = new List<Vector2>();
3040
this.extrusionIndices = new List<int>();
41+
this.polygonUVs = new List<Vector2>();
3142
}
3243

3344
private Matrix4x4 transform;
@@ -42,13 +53,19 @@ public PolygonBuilder(MeshData outputMeshData, Options options, Matrix4x4 transf
4253
// Values for extrusions.
4354
private Point lastPoint;
4455
private List<Vector3> extrusionVertices;
56+
private List<Vector2> extrusionUVs;
57+
private List<Vector2> polygonUVs;
4558
private List<int> extrusionIndices;
4659

4760
public void OnPoint(Point point)
4861
{
62+
bool buildWalls =
63+
options.Extrusion == ExtrusionType.TopAndSides ||
64+
options.Extrusion == ExtrusionType.SidesOnly;
65+
4966
// For all but the first point in each ring, create a quad extending from the
5067
// previous point to the current point and from MinHeight to MaxHeight.
51-
if (options.Extrude && pointsInRing > 0)
68+
if (buildWalls && pointsInRing > 0)
5269
{
5370
var p0 = lastPoint;
5471
var p1 = point;
@@ -70,21 +87,36 @@ public void OnPoint(Point point)
7087
extrusionVertices.Add(v2);
7188
extrusionVertices.Add(v3);
7289

90+
extrusionUVs.Add(new Vector2(1.0f, 1.0f));
91+
extrusionUVs.Add(new Vector2(0.0f, 1.0f));
92+
extrusionUVs.Add(new Vector2(1.0f, 0.0f));
93+
extrusionUVs.Add(new Vector2(0.0f, 0.0f));
94+
7395
extrusionIndices.Add(indexOffset + 1);
7496
extrusionIndices.Add(indexOffset + 3);
7597
extrusionIndices.Add(indexOffset + 2);
7698
extrusionIndices.Add(indexOffset + 1);
7799
extrusionIndices.Add(indexOffset + 2);
78100
extrusionIndices.Add(indexOffset + 0);
79101
}
102+
80103
lastPoint = point;
81104

82105
// Add the current point to the buffer of coordinates for the tesselator.
83-
coordinates.Add(point.X);
84-
coordinates.Add(point.Y);
106+
if (options.Extrusion != ExtrusionType.SidesOnly)
107+
{
108+
coordinates.Add(point.X);
109+
coordinates.Add(point.Y);
110+
}
111+
85112
pointsInRing++;
86113
}
87114

115+
public void AddUV(Vector2 uv)
116+
{
117+
polygonUVs.Add(uv);
118+
}
119+
88120
public void OnBeginLineString()
89121
{
90122
}
@@ -108,33 +140,49 @@ public void OnBeginPolygon()
108140
coordinates.Clear();
109141
rings.Clear();
110142
extrusionVertices.Clear();
143+
extrusionUVs.Clear();
111144
extrusionIndices.Clear();
145+
polygonUVs.Clear();
112146
}
113147

114148
public void OnEndPolygon()
115149
{
116150
// First add vertices and indices for extrusions.
117-
outputMeshData.AddElements(extrusionVertices, extrusionIndices, options.Material);
118-
119-
// Then tesselate polygon interior and add vertices and indices.
120-
var earcut = new Earcut();
121-
122-
earcut.Tesselate(coordinates.ToArray(), rings.ToArray());
151+
outputMeshData.AddElements(extrusionVertices, extrusionUVs, extrusionIndices, options.Material);
123152

124-
var vertices = new List<Vector3>(earcut.Vertices.Length / 2);
125-
126-
for (int i = 0; i < earcut.Vertices.Length; i += 2)
153+
if (coordinates.Count > 0)
127154
{
128-
var v = new Vector3(earcut.Vertices[i], options.MaxHeight, earcut.Vertices[i + 1]);
129-
130-
v = this.transform.MultiplyPoint(v);
131-
132-
vertices.Add(v);
155+
// Then tesselate polygon interior and add vertices and indices.
156+
var earcut = new Earcut();
157+
158+
earcut.Tesselate(coordinates.ToArray(), rings.ToArray());
159+
var vertices = new List<Vector3>(coordinates.Count / 2);
160+
List<Vector2> uvs;
161+
162+
if (polygonUVs.Count > 0)
163+
{
164+
uvs = polygonUVs;
165+
}
166+
else
167+
{
168+
uvs = new List<Vector2>(coordinates.Count / 2);
169+
for (int i = 0; i < coordinates.Count; i += 2)
170+
{
171+
uvs.Add(new Vector2(coordinates[i], coordinates[i + 1]));
172+
}
173+
}
174+
175+
for (int i = 0; i < coordinates.Count; i += 2)
176+
{
177+
var v = new Vector3(coordinates[i], options.MaxHeight, coordinates[i + 1]);
178+
v = this.transform.MultiplyPoint(v);
179+
vertices.Add(v);
180+
}
181+
182+
outputMeshData.AddElements(vertices, uvs, earcut.Indices, options.Material);
183+
184+
earcut.Release();
133185
}
134-
135-
outputMeshData.AddElements(vertices, earcut.Indices, options.Material);
136-
137-
earcut.Release();
138186
}
139187
}
140188
}

0 commit comments

Comments
 (0)