forked from jbdong/CityEngine_cga
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfacade_04.cga
319 lines (214 loc) · 7.87 KB
/
facade_04.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
/**
* File: facade_04.cga
* Created: 3 Nov 2008 15:31:30 GMT
* Author: andi
*/
version "2011.1"
/* Attributes *************************************/
@Group("Building",1) @Range(5,40)
attr height = 24
@Group("Floor",2) @Range(3,6)
attr groundfloor_height = 5.5
@Group("Floor") @Range(3,6)
attr floor_height = 4.5
@Group("Tile",3) @Range(2,5)
attr tile_width = 3.1
@Group("Tile")
attr wallColor = "#ffffff"
@Group("Tile") @Range(1,3)
attr window_width = 1.4
@Group("Tile") @Range(1,3)
attr door_width = 2.1
/* Assets *************************************/
# Geometries
const window_asset = "facades/elem.window.frame.obj"
const round_wintop_asset = "facades/round_windowtop.obj"
const tri_wintop_asset = "facades/triangle_windowtop.obj"
const halfarc_asset = "facades/arc_thin.obj"
const ledge_asset = "facades/ledge.03.twopart_lessprojection.obj"
const modillion_asset = "facades/ledge_modillion.03.for_cornice_ledge_closed.lod0.obj"
# Textures
const wall_tex = "facades/textures/brickwall2.tif"
const wall2_tex = "facades/textures/brickwall2_bright.tif"
const dirt_tex = "facades/textures/dirtmap.15.tif"
const doortop_tex = "facades/textures/doortoptex.jpg"
/* Functions *************************************/
# this function will return the requested texture string
# of the type facade/window.x.tif
randomWindowTex = fileRandom("*facades/textures/window.*.jpg")
randomDoorTex = fileRandom("*facades/textures/doortex.*.jpg")
const wall_inset = 0.4
/* Initial Shape starting rule *************/
# extrude the lot to building height
@StartRule
Lot --> extrude(height) Building
# we only need the front face for this example
Building --> comp(f) { front : FrontfacadeTex}
FrontfacadeTex -->
setupProjection(0, scope.xy, 2.25, 1.5, 1) // setup 2.25m x 1.5m texture tiles (and distortion in z)
setupProjection(2, scope.xy, '1, '1) // setup texture channel 2 for dirt mapping over whole facade
Frontfacade
# the front facade is subdivided into one front groundfloor
# and upper floors
Frontfacade -->
split(y){ groundfloor_height : Floor(split.index)
| floor_height : Floor(split.index)
| floor_height : Floor(split.index)
| {~floor_height : Floor(split.index)}*
| floor_height : Floor(999)
| 0.5 : s('1,'1,0.3) LedgeAsset}
# depending on the floor index, floors are split into bottom ledge, tile (window) and top ledge area
Floor(floorindex) -->
case floorindex == 0 :
// Groundfloor has tiles only, no ledges
Subfloor(floorindex)
case floorindex == 2 :
// because windows start at floor level, no bottom ledge for second floor
// but balcony instead
split(y){~1 : Subfloor(floorindex) Balcony | 0.5 : TopLedge}
else :
// all other floors have bottom ledge, tile and top ledge area
split(y){1 : BottomLedge(floorindex) | ~1 : Subfloor(floorindex) | 0.5 : TopLedge}
# ----------------------------------------
# Tiles
# ----------------------------------------
# Tiles consist of small wall areas on left and right edges and repeating tiles in between
Subfloor(floorindex) -->
split(x){ 0.5 : Wall(1)
| { ~tile_width : Tile(floorindex) }*
| 0.5 : Wall(1) }
# a tile consists of a centered window element and
# wall elements left and right.
Tile(floorindex) -->
case floorindex == 0 :
// the groundfloor has different dimensions and different shapes
split(x){ ~1 : SolidWall
| door_width : DoorTile
| ~1 : SolidWall }
else :
split(x){ ~1 : Wall(getWalltype(floorindex))
| window_width : WindowTile(floorindex)
| ~1 : Wall(getWalltype(floorindex)) }
# ----------------------------------------
# Windows
# ----------------------------------------
# different window ornaments for windowtiles on different floors
WindowTile(floorindex) -->
case floorindex == 1 || floorindex == 999: Window
case floorindex == 2 : Window t(0,'1,0) WindowOrnamentRound
else : Window WindowLedge t(0,'1,0) WindowOrnamentTriangle
# set dimensions for the triangle window element and insert it
WindowOrnamentTriangle -->
s('1.7, 1.2, 0.3) center(x) i(tri_wintop_asset) Wall(0)
# set dimensions for the triangle window element and insert it
WindowOrnamentRound -->
s('1.7, 1.2, 0.4) center(x) i(round_wintop_asset) Wall(0)
split(x){~1 : WindowMod | window_width : NIL | ~1 : WindowMod }
WindowMod -->
// the modillion asset is scaled in negative y direction
// which aligns its top at the window top edge
s(0.2,'1.3,'0.6) t(0,'-1,0) center(x) i(modillion_asset) Wall(0)
WindowLedge -->
s('1.5, 0.2, 0.1) t(0,-0.2,0) center(x) i("builtin:cube") Wall(0)
# firstly, the depth and the depth position of the future window is set
# secondly, one of nine window textures is randomly selected
# finally, the window geometry asset is inserted
Window -->
s('1,'1,0.2) t(0,0,-0.2)
t(0,0,0.02)
[ i(window_asset) Wall(0) ]
Glass
Glass -->
setupProjection(0,scope.xy, '1, '1)
projectUV(0)
texture(randomWindowTex)
set(material.specular.r, 1) set(material.specular.g, 1) set(material.specular.b, 1)
set(material.shininess, 4)
# ----------------------------------------
# Door
# ----------------------------------------
# The door tile is split vertically into door, arc and top area
DoorTile -->
// to ensure non-elliptic arcs, the height of the arc area need to
// be half the width of the door (the current x scope)
split(y){~1 : Door | scope.sx/2 : Arcs | 0.5 : Arctop}
# Adds wall material and a centered modillion
Arctop -->
Wall(1)
s(0.5,'1,0.3) center(x) i(modillion_asset) Wall(1)
#
Arcs -->
s('1,'1,wall_inset) t(0,0,-wall_inset) Doortop
i("builtin:cube")
split(x){ ~1 : ArcAsset
| ~1 : r(0,0,-90) t('-1,0,0) ArcAsset}
Doortop -->
setupProjection(0, scope.xy, '1, '1)
texture(doortop_tex)
projectUV(0)
# inserts the actual arc asset
ArcAsset --> i(halfarc_asset) Wall(1)
Door -->
t(0,0,-wall_inset)
setupProjection(0,scope.xy, '1, '1)
texture(randomDoorTex)
projectUV(0)
# ----------------------------------------
# Ledges
# ----------------------------------------
TopLedge --> WallStripe
BottomLedge(floorindex) -->
case floorindex == 1 : split(y){~1 : Wall(0) | ~1 : s('1,'1,0.2) LedgeAsset}
case floorindex == 999 : split(y){~1 : WallStripe | ~1 : s('1,'1,0.2) LedgeAsset}
else : WallStripe
WallStripe --> split(x){ 0.5 : Wall(1) | ~1 : Wall(2) | 0.5 : Wall(1) }
LedgeAsset --> i(ledge_asset) Wall(0)
# ----------------------------------------
# Balcony
# ----------------------------------------
Balcony -->
s('1,2,1) t(0,-0.3,0) i("builtin:cube")
split(y){0.2 : BalconyBeams
| 0.3 : BalconyFloor
| 1 : RailingBox }
# The beams supporting the balcony are created with a repeating split
BalconyBeams -->
split(x){ ~0.4 : s(0.2,'1,'0.9) center(x) Wall(0) }*
# Get the front, left and right components (faces) of the RailingBox shape
RailingBox -->
comp(f){front : Rail | left : Rail | right : Rail} // | left : Rail | right : Rail}}
# set rail dimensions and insert cube to create balconyony rails
Rail -->
s('1.1,'1,0.1) t(0,0,-0.1) center(x) i("builtin:cube") Wall(0)
BalconyFloor --> Wall(0)
# ----------------------------------------
# Wall
# ----------------------------------------
# for the wall asset, setting the texture scale params u and v
# guarantees a texture mapping that nicely fits over the whole facade
getWalltype(floorindex) =
case floorindex == 0 : 1
case floorindex == 1 : 1
else : 2
Wall(walltype) -->
// dark bricks with dirt
case walltype == 1 :
color(wallColor)
texture(wall_tex)
set(material.dirtmap, dirt_tex)
projectUV(0) projectUV(2)
// bright bricks with dirt
case walltype == 2 :
color(wallColor)
texture(wall2_tex)
set(material.dirtmap, dirt_tex)
projectUV(0) projectUV(2)
// dirt only
else :
color(wallColor)
set(material.dirtmap, dirt_tex)
projectUV(2)
SolidWall -->
s('1,'1,wall_inset) t(0,0,-wall_inset)
i("builtin:cube:notex")
Wall(1)