forked from jbdong/CityEngine_cga
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStreet_Modern_Standard.cga
347 lines (261 loc) · 13.9 KB
/
Street_Modern_Standard.cga
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/**
* File: Street Construction Simple.cga
* Created: 5 Nov 2013
* Author: Esri R&D Center Zurich
*/
# Differences to Street Construction Simple:
# This ruleset can also generate stop markings and crosswalks (by using the
# objects attributes) and generates more detailed roundabouts
version "2014.0"
###################################################
# Control Attributes
#
@Order(1) @Range(0,4)
attr NbrOfRightLanes = _getInitialNbrOfRightLanes
@Order(2) @Range("yellow","white","none")
attr Centerline = _getInitialCenterline
@Order(3) @Range("right-hand","left-hand")
attr RoadTraffic = "right-hand"
@Group("Stop Markings",4)
@Order(1) @Range("none","line only","with stop marking","arrows on all lanes","arrows on side lanes","arrows for right turn") @Description("The initial stop markings do not take into account the topology of the intersection i.e. they need to be set manually")
attr StopBegin = _getInitialStop(connectionStart,nLanesLeft)
@Order(2) @Range("none","line only","with stop marking","arrows on all lanes","arrows on side lanes","arrows for right turn") @Description("The initial stop markings do not take into account the topology of the intersection i.e. they need to be set manually")
attr StopEnd = _getInitialStop(connectionEnd,NbrOfRightLanes)
@Group("Crosswalk Markings",5)
@Order(1) @Range("none","continental","ladder","transverse","dashed","solid") # TODO "solid","dashed","ladder"
attr CrosswalkBegin = _getInitialCrosswalk(connectionStart)
@Order(2) @Range("none","continental","ladder","transverse","dashed","solid")
attr CrosswalkEnd = _getInitialCrosswalk(connectionEnd)
@Order(3) @Range("white","yellow")
attr CrosswalkColor = "white"
# Mapped Attributes (comming from graph)
# @Group("Shape driven:",8)
@Hidden @Order(1) @Range(0,30)
attr streetWidth = geometry.dv(0,unitSpace) # REALWORLD-distance in V-direction corresponds to width of street (in case the geometry does not contain rounded entry geometry)
@Hidden @Order(2) @Range(1,6)
attr laneWidth = streetWidth/geometry.dv(0,uvSpace) # note that TEXTURE-distance in V-direction corresponds to number of lanes (as generated by CityEngine)
@Hidden @Order(3)
attr connectionEnd = "STREET" # built in value attributes, needs to be sourced as Object (parent)
@Hidden @Order(4)
attr connectionStart = "STREET" # built in value attributes, needs to be sourced as Object (parent)
@Hidden @Order(5)
attr valency = 0
# User constants
const StreetTextureFolder = "Streets"
const GreenTextureFolder = "Groundcover/Green"
const Brightness = "#d7d7d7"
const SidewalkHeight = 0.2 # height of sidewalk (and depth) of curbs
###################################################
# Initial attribute settings
# (to get a diversified default appeareance depending on initial shape, connection object attributes and randomness)
#
_getInitialNbrOfRightLanes =
case initialShape.startRule=="Roundabout": nLanesTotal
case nLanesTotal>2 || _through || p(0.3) : rint(nLanesTotal/2)
case p(0.5) : nLanesTotal
else : 0
_getInitialCenterline =
case oneWay || initialShape.startRule=="Junction": "none" # one way does not need centerline, neither do junctions nor roundabouts
case _through : "yellow" # to be consistent always yellow for through traffic (= a street/junction/freeway without stop markings at least on one side)
case (nLanesTotal<3 && p(0.5)) || p(0.1) : "none" # sometimes no fat centerlines
case p(0.7) : "yellow" # otherwise mostly yellow centerline
else : "white" # and a few times a white centerline
_getInitialStop(connection,nLanes) =
case _hasStop(connection) && nLanes>0 && (nLanesTotal>3 || streetLength>30):
case connection=="ROUNDABOUT": 60%: "with stop marking" else: "arrows for right turn"
case nLanes>2 : 20%: "line only" 20%: "with stop marking" 20%: "arrows on all lanes" 17%: "arrows on side lanes" 17%: "arrows for right turn" else: "none"
else : 35%: "line only" 35%: "with stop marking" 10%: "arrows on all lanes" 10%: "arrows on side lanes" else: "none"
else: "none"
_getInitialCrosswalk(connection) =
case _hasStop(connection) && streetLength>10: 50%: "continental" 10%: "transverse" 5%: "ladder" 5%: "dashed" else: "none"
else: "none"
###################################################
# Internal utilities
#
const streetLength = geometry.du(0,unitSpace) # REALWORLD-distance in U-direction corresponds to length of street
const nLanesTotal = case rint(streetWidth/laneWidth)>0: rint(streetWidth/laneWidth) else: 1
const nLanesLeft = nLanesTotal-NbrOfRightLanes
const rightHandTraffic = RoadTraffic=="right-hand"
const leftHandTraffic = !rightHandTraffic
const oneWay = NbrOfRightLanes<=0 || nLanesLeft<=0
const _oneWayForward = (rightHandTraffic && nLanesLeft<=0) || (leftHandTraffic && NbrOfRightLanes<=0) # in direction of graph segment?
const _oneWayReverse = oneWay && !_oneWayForward
const _stopBegin = case StopBegin=="none" || _oneWayForward: 0 else: 1
const _stopEnd = case StopEnd=="none" || _oneWayReverse: 0 else: 1
const _crosswalkWidth = case streetLength>10 && nLanesTotal>3: 4.5 else: 3.5
const _crosswalkBeginWidth = case CrosswalkBegin=="none": 0 else: _crosswalkWidth
const _crosswalkEndWidth = case CrosswalkEnd=="none" : 0 else: _crosswalkWidth
const _centerlineWidth = case oneWay: 0 else: 36/256
const _through = connectionEnd=="STREET" || connectionStart=="STREET" || connectionEnd=="JUNCTION" || connectionStart=="JUNCTION" || connectionEnd=="FREEWAY" || connectionStart=="FREEWAY"
_hasStop(neighbor) = neighbor=="CROSSING" || neighbor=="ROUNDABOUT" || neighbor=="JUNCTION_ENTRY"
_stopTex(stopType) = case stopType == "with stop marking" : case rightHandTraffic: "_stop_word" else: "_stop_word_mirrored"
case stopType == "arrows on all lanes" : "_stop_arrows_all"
case stopType == "arrows on side lanes" : "_stop_arrows_sides"
case stopType == "arrows for right turn": "_stop_arrows_right"
else : "_stop"
_uScale = case geometry.du(0,unitSpace)>10: 1
case geometry.du(0,unitSpace)>4 : 1/2 # in case the street is too short, we only use half of the texture
else : 1/6 # if even shorter, we use only the start of the texture (i.e. centerline only)
###################################################
###################################################
##
## RULES
##
##
###################################################
# Street Lane Texturing
#
@StartRule
# split away the crosswalks at the beginning (if any) using the special UVSET 1
Street -->
split(u,uvSpace,1){ _crosswalkBeginWidth/3: Asphalt
| _crosswalkBeginWidth : Crosswalk(CrosswalkBegin,1)
| _crosswalkBeginWidth/4: Asphalt
| _stopBegin*0.5 : StopLine(true)
| ~1 : StreetWithCrosswalkEnd }
# split away the crosswalks at the end (if any) using the special UVSET 2
StreetWithCrosswalkEnd -->
split(u,uvSpace,2){ _crosswalkEndWidth/3 : Asphalt
| _crosswalkEndWidth : Crosswalk(CrosswalkEnd,2)
| _crosswalkEndWidth/4 : Asphalt
| _stopEnd*0.5 : StopLine(false)
| ~1 : StreetWithEntries }
# split away the side geometry on the streets
StreetWithEntries -->
split(v,uvSpace,0){ -geometry.vMin: Asphalt # the lanes start at v-coord 0 i.e. everything below can be splitted away (= asphalt)
| nLanesTotal : Lanes # the lanes end at v-coord nLanesTotal
| ~1 : Asphalt } # all remaining geometry beyond v-coord nLanesTotal can be split away
# split into the two street sides (if not oneway)
Lanes -->
split(v,uvSpace,0){ NbrOfRightLanes-_centerlineWidth/2: Lanes(case rightHandTraffic: StopEnd else: StopBegin) # in case of right-hand traffic, these lanes are in the direction of the graph segment
| ~_centerlineWidth : CenterLine
| nLanesLeft-_centerlineWidth/2 : translateUV(0,0,-geometry.vMax) scaleUV(0,-1,-1) # mirror the uv coords
Lanes(case rightHandTraffic: StopBegin else: StopEnd) } # in case of left-hand traffic, these lanes are in the direction of the graph segment
# split lanes into a single lane each
Lanes(stopType) -->
scaleUV(0, case rightHandTraffic: 1 else: -1, # flip the u-coords in case of left hand traffic
case oneWay: nLanesTotal*256/(nLanesTotal*256+18) else: 1) # stretch the v-coords in case of a oneway (to get rid of the repeating line at the end)
split(v,uvSpace,0){ 1: Lane(stopType) }*
# initiate the markings
Lane(stopType) -->
case stopType == "none":
LaneMarkings("_stripes_white")
else:
split(u,unitSpace,0){ ~1: LaneMarkings("_stripes_white")
| 14: LaneMarkings(_stopTex(stopType)) }
# prepare the uv coordinates and texture the shape
LaneMarkings(markings) -->
tileUV(0,~14,0) # the tileUV operation makes sure that one unit in u-space corresponds to approx 14 meters, the v-coord is not touched in the case of 0 as parameter
scaleUV(0,_uScale,1/4) # flip direction if needed, handle short lanes with _uScale, and scaling the v coord for the texture (e.g. a street with 2 lanes has v coords from 0 to 2, this means it has to map onto 0 to 2/8 on our texture with its 8 lanes)
texture(StreetTextureFolder + "/Lanes/lanes_4"+markings+"_14x14m.jpg")
color(Brightness)
###################################################
# Centerline
#
CenterLine -->
case Centerline=="none":
split(u,unitSpace,0){ _stopBegin*21: CenterLineMarkings("single_white")
| ~1 : CenterLineMarkings("stripes_white")
| _stopEnd*21 : CenterLineMarkings("single_white") }
else:
CenterLineMarkings("double_"+Centerline)
CenterLineMarkings(tex) -->
normalizeUV(0,v,collectiveAllFaces)
tileUV(0,~14,0)
texture(StreetTextureFolder + "/Lanes/centerline_" + tex + "_14m.jpg")
color(Brightness)
###################################################
# Stop
#
_centerlinePxOffset = case Centerline=="none": 7 else: 14
StopLine(begin) -->
case oneWay: AsphaltPainted("white")
case (rightHandTraffic && begin) || (leftHandTraffic && !begin):
split(v,uvSpace,0){ -geometry.vMin+NbrOfRightLanes-_centerlinePxOffset/256: Asphalt | ~1: AsphaltPainted("white") }
else:
split(v,uvSpace,0){ -geometry.vMin+NbrOfRightLanes+_centerlinePxOffset/256: AsphaltPainted("white") | ~1: Asphalt }
###################################################
# Crosswalk
#
Crosswalk(crosswalkType,uvSet) -->
case crosswalkType == "transverse": CrosswalkTransverse(uvSet)
case crosswalkType == "dashed" : CrosswalkDashed(uvSet)
case crosswalkType == "ladder" : CrosswalkLadder(uvSet)
case crosswalkType == "solid" : AsphaltPainted(CrosswalkColor)
else : CrosswalkContintential
CrosswalkContintential -->
split(v,uvSpace,0){ (ceil(geometry.vMin-0.01)-geometry.vMin): Asphalt
| ~1: CrosswalkStripes(1)
| geometry.vMax-floor(geometry.vMax+0.01): Asphalt }
CrosswalkLadder(uvSet) -->
split(u,uvSpace,uvSet){ 0.17: AsphaltPainted(CrosswalkColor)
| ~1 : CrosswalkStripes(1)
| 0.17: AsphaltPainted(CrosswalkColor) }
CrosswalkTransverse(uvSet) -->
split(u,uvSpace,uvSet){ 0.27: AsphaltPainted(CrosswalkColor)
| ~1 : Asphalt
| 0.27: AsphaltPainted(CrosswalkColor) }
CrosswalkDashed(uvSet) -->
split(u,uvSpace,uvSet){ 0.17: CrosswalkStripes(0.6)
| ~1 : Asphalt
| 0.17: CrosswalkStripes(0.6) }
CrosswalkStripes(stripeWidth) -->
cleanupGeometry(all, 0.001)
tileUV(0,0,~1) scaleUV(0,1,1/8/stripeWidth) # to setup the v-direction: a continental crosswalk line is 1m width, and the texture contains 8 of these.
texture(StreetTextureFolder + "/Lanes/crosswalk_continental_"+CrosswalkColor+".jpg")
color(Brightness)
###################################################
# Other default Start Rules of the graph
#
# drive-through street segments
Joint --> Lanes
Junction --> Lanes
Freeway --> Lanes
# crossing is just Asphalt for now
Crossing --> Asphalt
# freeway entries have an additional striped line (splits the shape into lanes but also splits away a shape just for the striped line using special UVSET 1
FreewayEntry -->
set(streetWidth,geometry.dv(0,unitSpace))
set(laneWidth,streetWidth/geometry.dv(0,uvSpace))
split(v,unitSpace,1){ laneWidth*18/256: tileUV(0,0,-laneWidth) LaneMarkings("_stripes_white") # with tileUV we make sure that the v-coord starts always at zero (independent of the direction of the segment) and since the last stripe is on the top of the texture, we have to reverse the v-coord
| { laneWidth : LaneMarkings("_stripes_white") }* }
###################################################
# Roundabout
#
Roundabout -->
case valency>1: split(u,uvSpace,0){ '0.99: Lanes }* # split used for a workaround to solve a v-split problem with donut-like polygons
else : Asphalt # cul-de-sac is Asphalt only
RoundaboutIsland -->
case valency>1: IslandWithGreen
else : Asphalt # cul-de-sac is Asphalt only
IslandWithGreen -->
offset(-SidewalkHeight)
comp(f){ inside: Green | border: setupProjection(0,scope.xy,'1,'1) projectUV(0) Curbs }
Green -->
translate(rel,world,0,SidewalkHeight,0)
setupProjection(0,scope.yx,'1,'1) projectUV(0)
texture(fileRandom(GreenTextureFolder + "/green*.jpg"))
###################################################
# Sidewalk
#
Sidewalk -->
split(v,unitSpace,0){ SidewalkHeight: Curbs | ~1: Pavement }
Curbs -->
extrude(world.y,SidewalkHeight)
tileUV(0,~2,'1) texture(StreetTextureFolder + "/Sidewalks/curbs_2m.jpg")
Pavement -->
translate(rel,world,0,SidewalkHeight,0)
tileUV(0,~2,'1) texture(StreetTextureFolder + "/Sidewalks/pavement_01_2x2m.jpg")
###################################################
# Misc
#
Asphalt -->
tileUV(0,14,14)
cleanupGeometry(all, 0.001)
texture(StreetTextureFolder + "/Lanes/asphalt_14x14m.jpg")
color(Brightness)
AsphaltPainted(paintColor) -->
tileUV(0,7,7)
cleanupGeometry(all, 0.001)
texture(StreetTextureFolder + "/Lanes/asphalt_painted_" + paintColor + "_7x7m.jpg")
color(Brightness)