1
1
using System . Collections . Generic ;
2
+ using System . Linq ;
2
3
using Mapzen . VectorData ;
3
4
using UnityEngine ;
4
5
using System ;
@@ -7,11 +8,19 @@ namespace Mapzen.Unity
7
8
{
8
9
public class PolygonBuilder : IGeometryHandler
9
10
{
11
+ [ Serializable ]
12
+ public enum ExtrusionType
13
+ {
14
+ TopOnly ,
15
+ TopAndSides ,
16
+ SidesOnly ,
17
+ }
18
+
10
19
[ Serializable ]
11
20
public struct Options
12
21
{
13
22
public Material Material ;
14
- public bool Extrude ;
23
+ public ExtrusionType Extrusion ;
15
24
public float MinHeight ;
16
25
public float MaxHeight ;
17
26
public bool Enabled ;
@@ -27,7 +36,9 @@ public PolygonBuilder(MeshData outputMeshData, Options options, Matrix4x4 transf
27
36
this . lastPoint = new Point ( ) ;
28
37
this . pointsInRing = 0 ;
29
38
this . extrusionVertices = new List < Vector3 > ( ) ;
39
+ this . extrusionUVs = new List < Vector2 > ( ) ;
30
40
this . extrusionIndices = new List < int > ( ) ;
41
+ this . polygonUVs = new List < Vector2 > ( ) ;
31
42
}
32
43
33
44
private Matrix4x4 transform ;
@@ -42,13 +53,19 @@ public PolygonBuilder(MeshData outputMeshData, Options options, Matrix4x4 transf
42
53
// Values for extrusions.
43
54
private Point lastPoint ;
44
55
private List < Vector3 > extrusionVertices ;
56
+ private List < Vector2 > extrusionUVs ;
57
+ private List < Vector2 > polygonUVs ;
45
58
private List < int > extrusionIndices ;
46
59
47
60
public void OnPoint ( Point point )
48
61
{
62
+ bool buildWalls =
63
+ options . Extrusion == ExtrusionType . TopAndSides ||
64
+ options . Extrusion == ExtrusionType . SidesOnly ;
65
+
49
66
// For all but the first point in each ring, create a quad extending from the
50
67
// previous point to the current point and from MinHeight to MaxHeight.
51
- if ( options . Extrude && pointsInRing > 0 )
68
+ if ( buildWalls && pointsInRing > 0 )
52
69
{
53
70
var p0 = lastPoint ;
54
71
var p1 = point ;
@@ -70,21 +87,36 @@ public void OnPoint(Point point)
70
87
extrusionVertices . Add ( v2 ) ;
71
88
extrusionVertices . Add ( v3 ) ;
72
89
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
+
73
95
extrusionIndices . Add ( indexOffset + 1 ) ;
74
96
extrusionIndices . Add ( indexOffset + 3 ) ;
75
97
extrusionIndices . Add ( indexOffset + 2 ) ;
76
98
extrusionIndices . Add ( indexOffset + 1 ) ;
77
99
extrusionIndices . Add ( indexOffset + 2 ) ;
78
100
extrusionIndices . Add ( indexOffset + 0 ) ;
79
101
}
102
+
80
103
lastPoint = point ;
81
104
82
105
// 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
+
85
112
pointsInRing ++ ;
86
113
}
87
114
115
+ public void AddUV ( Vector2 uv )
116
+ {
117
+ polygonUVs . Add ( uv ) ;
118
+ }
119
+
88
120
public void OnBeginLineString ( )
89
121
{
90
122
}
@@ -108,33 +140,49 @@ public void OnBeginPolygon()
108
140
coordinates . Clear ( ) ;
109
141
rings . Clear ( ) ;
110
142
extrusionVertices . Clear ( ) ;
143
+ extrusionUVs . Clear ( ) ;
111
144
extrusionIndices . Clear ( ) ;
145
+ polygonUVs . Clear ( ) ;
112
146
}
113
147
114
148
public void OnEndPolygon ( )
115
149
{
116
150
// 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 ) ;
123
152
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 )
127
154
{
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 ( ) ;
133
185
}
134
-
135
- outputMeshData . AddElements ( vertices , earcut . Indices , options . Material ) ;
136
-
137
- earcut . Release ( ) ;
138
186
}
139
187
}
140
188
}
0 commit comments