/** * File: sternwarte.cga * Created: 26 May 2015 11:46:03 GMT * Author: Esri R&D Center Zurich */ version "2019.1" // ------------------------------ // Attributes and Variables // ------------------------------ @Group("Main", 1) @Order(1) @Handle(shape=Main, axis=x, skin=diameterArrow) @Range(min=6.4, max=100, restricted=false) @Distance // 6.4 < main_width (for one facade tile) @Description("width of main rectangular part") attr main_width = 6.8 @Order(2) @Handle(shape=Main, axis=z, skin=diameterArrow) @Range(min=6.4, max=100, restricted=false) @Distance // 6.4 < main_depth (for one facade tile) @Description("depth of main rectangular part") attr main_depth = 18 @Order(3) @Handle(shape=Tower, slip=screen, reference=center, extensionLines=fade) @Range(min=11.2, max=100, restricted=false) @Distance // 11.2 < tower_height, (for ground floor, top floor, dome base) @Description("height of cylindrical part of tower, without dome") attr tower_height = 15.2 @Order(4) //@Handle(shape=Terrace, axis=z-) @Range(min=3.3, max=20, restricted=false) @Distance // 3.3 < terrace_depth, (for tower door to line up with stairs) @Description("depth of terrace") attr terrace_depth = 8.9 // ------ @Group("Left Wing", 2) @Order(1) @Handle(shape=LeftWing, axis=x-) @Range(min=3.6, max=100, restricted=false) @Distance // 3.6 < leftWing_width, (for pillars and margins) @Description("width of left wing") attr leftWing_width = 6.4 @Handle(shape=LeftWing, axis=z-) @Order(2) @Range(min=6.4, max=100, restricted=false) @Distance // 6.4 < leftWing_depth, (for one facade tile) @Description("depth of left wing") attr leftWing_depth = max(main_depth - 0.4, 6.4) // 17.6 @Order(3) @Handle(shape=LeftWingTranslateXHandle, axis=x, reference=center, slip=inside, occlusion=false, skin=Sphere, color="#e9e926") @Distance @Description("left wing x position") attr leftWing_pos_x = main_offset_x // front right corner @Order(4) @Handle(shape=LeftWingTranslateZHandle, axis=z, reference=center, slip=inside, occlusion=false, skin=Sphere, color="#e9e926") @Distance @Description("left wing z position") attr leftWing_pos_z = main_offset_z + main_depth - tileWithMargin_width + pillar_width // front right corner, LeftWing stays with front of Main, windows in LeftWing and Main align // ------ @Group("Right Wing", 3) @Order(1) @Handle(shape=RightWing, axis=x) @Range(min=5, max=100, restricted=false) @Distance // 5 < rightWing_width, (for one right wing facade tile) @Description("width of right wing") attr rightWing_width = 17.2 @Order(2) @Handle(shape=RightWing, axis=z-) @Range(min=6.4, max=100, restricted=false) @Distance // 6.4 < rightWing_depth, (for one yellow facade tile) @Description("depth of right wing") attr rightWing_depth = 6.6 @Order(3) @Handle(shape=RightWingTranslateXHandle, axis=x, reference=center, slip=inside, occlusion=false, skin=Sphere, color="#e9e926") @Distance @Description("right wing x position") attr rightWing_pos_x = main_offset_x + main_width // front left corner @Order(4) @Handle(shape=RightWingTranslateYHandle, axis=y, reference=center, slip=inside, occlusion=false, skin=Sphere, color="#e9e926") @Distance @Description("right wing y position") attr rightWing_pos_y = 0 @Order(5) @Handle(shape=RightWingTranslateZHandle, axis=z, reference=center, slip=inside, occlusion=false, skin=Sphere, color="#e9e926") @Distance @Description("right wing z position") attr rightWing_pos_z = main_offset_z + main_depth // front left corner @Order(6) @Handle(type=angular, Shape=RightWing, axis=y, translate={0, 0.5, 0}, occlusion=false, color="#e9e926") @Range(min=-180, max=180) @Angle @Description("right wing rotation angle (deg)") attr rAngle = 0 // ------ @Group("Facade", 4) @Order(2) @Range(min=0.6, max=2.2, restricted=false) @Distance // 0.6 < window_width < 2.2, (to fit all vertical railing pieces, to fit window height in tile) @Description("window width") attr window_width = 1.7 @Order(3) @Range(min=0.6, max=3.5, restricted=false) @Distance // window_height < 3.5, (to fit in tile) @Description("window height") attr window_height = window_width*1.529 // 2.6 @Order(4) @Range(min=0.6, max=2.4, restricted=false) @Distance // groundWindow_width < 2.4, (to fit window height in tile) @Description("ground floor window width") attr groundWindow_width = window_width // window on ground floor @Order(5) @Range(min=0.6, max=3.8, restricted=false) @Distance // groundWindow_height < 3.8, (to fit in tile) @Description("ground floor window height") attr groundWindow_height = groundWindow_width*1.529 @Order(6) @Range(min=0.3, max=1.2, restricted=false) @Distance // topWindow_width < 1.2, (to fit window height in tile) @Description("width of single window on top floor") attr topWindow_width = window_width*0.647 // 1.1, single window on top floor @Order(7) @Range(min=0.6, max=2.5, restricted=false) @Distance // topWindow_height < 2.5, (to fit in tile) @Description("height of single window on top floor") attr topWindow_height = topWindow_width*1.636 // 1.8 @Order(8) @Range(min=1, max=6.5, restricted=false) @Distance // 1 < door_width < 6.5, (for skinny door, for min facade width) @Description("door width") attr door_width = 2.6 @Order(9) @Range(min=2, max=5, restricted=false) @Distance // 2 < door_height < 5, (standard door height, for ground floor height) @Description("door height") attr door_height = 4.4 @Order(10) @Range(min=5.4, max=6.9, restricted=false) @Distance // 5.4 < groundFloor_height < 6.9 (for door height, to keep mid floor windows) @Description("ground floor height") attr groundFloor_height = 6 @Order(110) @Range(min=4, max=8, restricted=false) @Distance // 4 < floor_height, (fewer cases without windows when tower_height is increased) @Description("height of middle floors") attr floor_height = 4 // height of middle floors @Order(12) @Range(min=2.3, max=7, restricted=false) @Distance // 2.3 < topFloor_height < 7, (keep window in tile, ground floor and top floor takes up main_height) @Description("top floor height") attr topFloor_height = 3 @Order(13) @Range(min=0.2, max=0.7, restricted=false) @Distance // 0.2 < pillar_width > 0.7, (so right wing doesn't occlude window, for cylinder face) @Description("width of pillar decorations flanking windows") attr pillar_width = 0.4 // width of pillars on facades @Order(14) @Range(min=0.4, max=1.1, restricted=false) @Distance @Description("height of railings on roofs") attr roofRailing_height = 0.7 // ------ @Group("Materials", 5) @Order(0) @Enum("CE Blue","CE Dark Blue","CE Green","CE Brown","CE Black","iRay Glass") attr glass_material = "CE Black" @Order(1) @Color @Description("wall color of upper floors") attr wall_color = "#EED6A2" // yellow wall of upper floors @Order(2) @Color @Description("brick color of upper part of ground floor") attr brick_color = "#929280" // brick color of upper part of ground floor (lighter gray) @Order(3) @Color @Description("brick color of lower part of ground floor") attr lowerBrick_color = "#7C807E" // brick color of lower part of ground floor (darker gray) @Order(4) @Color @Description("white column in right wing facade") attr column_color = "#DADBD0" // white column in right wing facade @Order(5) @Color @Description("roof color") attr roof_color = "#555056" // roof color @Order(6) @Color @Description("dome color") attr dome_color = "#393D39" // dome color // positioning of parts: main, terrace, left wing, right wing const bound_x = 70 // bounds for building part translation (by handles) const bound_z = 70 const building_width = 6.4 + main_width + 17.2 // building size, center building over Lot but only Main changes centering const building_depth = 13.4 + main_depth const main_offset_x = bound_x/2 - building_width/2 + 6.4 // center building and place Main correctly relative to centered building const main_offset_z = bound_z/2 - building_depth/2 + 13.4 const terrace_offset_x = main_offset_x // back left corner, translation offset for terrace const terrace_offset_z = main_offset_z - towerSection_depth - terrace_depth const leftWing_offset_x = leftWing_pos_x - leftWing_width // back left corner, translation offset for left wing const leftWing_offset_z = leftWing_pos_z - leftWing_depth const rightWing_offset_x = rightWing_pos_x // back left corner, translation offset for right wing const rightWing_offset_y = rightWing_pos_y const rightWing_offset_z = rightWing_pos_z - rightWing_depth // positioning of tower const towerOverlapWithTerrace = 1.3 // should be > 0.2, overlap values and initial depths cause main+tower+terrace depth = 31.4 const towerOverlapWithMain = 1 // should be > 0.2 const towerOverlapWithLeftWing = 0.1 // this overlap extends scope in x and z to keep cylinder circular, increases dome height to keep dome spherical const towerSection_depth = main_width - towerOverlapWithTerrace - towerOverlapWithMain // depth of non-overlapping region for tower const tower_offset_x = main_offset_x - towerOverlapWithLeftWing // back left corner, translation offset for tower const tower_offset_z = main_offset_z - towerSection_depth - towerOverlapWithTerrace - towerOverlapWithLeftWing // heights calculated from other attributes const main_height = tower_height - domeBase_height // 13, not including railing const leftWing_height = main_height - topFloor_height // 10, not including roof const rightWing_height = groundFloor_height // 6, not including railing // terrace dimensions const terrace_width = main_width const terrace_height = 2.2 const terraceStairs_width = 1.8 // handle box dimensions const handle_width = 0.1 // width of bounding boxes for handles const handle_length = 5 // length of bounding boxes for handles // floor heights const lowerGround_height = groundFloor_height*0.2 // 1.2, lower part of ground floor (darker bricks) const upperGround_height = groundFloor_height - base_height - lowerGround_height // upper part of ground floor (lighter bricks) const dome_height = main_width/2 + towerOverlapWithLeftWing // 3.5, keep spherical when tower diameter increases const domeBase_height = 2.2 // facade element sizes const base_height = 0.7 // base around bottom of entire building const base_depth = 0.1 const pillar_depth = 0.1 const wallMargin_width = min(max(window_width*0.706, pillar_width), 1.2) // 1.2, yellow wall margin const tile_width = window_width*1.412 // 2.4, facade tile const tileWithMargin_width = pillar_width*4 + wallMargin_width*2 + tile_width // 6.4, single window facade unit: pillar, margin, pillar, tile (wall, window, wall), pillar, margin, pillar const window_depth = 0.3 const maxWindow_width = max(2*topWindow_width, max(window_width, groundWindow_width)) // largest window width const door_depth = 1.8 // ledge sizes const lowerLedge_height = 0.2 const lowerLedge_depth = 0.1 const midLedge_height = 0.3 const midLedge_depth = 0.2 const topLedge_height = 0.5 const topLedge_depth = 0.3 // stairs const step_width = 0.34 const step_height = 0.14 // right wing facade element sizes const rightWingTile_width = groundWindow_width*1.588 // 2.7, right wing facade tile const whiteColumn_width = pillar_width*1.425 // 0.57, white column between tiles on right wing const rightWingMargin_width = min(max(groundWindow_width*0.882, pillar_width), 1.5) // 1.5, margin on left side of right wing const rightWingDecoSpacing = 1.15 // spacing between ledge decorations on side of right wing on top ledge // tower elements const towerGroundDoor_width = 1.0 // don't make this an attribute because pillar pattern on cylinder depends on it const towerGroundDoor_height = 2 const towerRoofDoor_width = towerGroundDoor_width const towerRoofDoor_height = towerGroundDoor_height const towerWindow_width = 1.3 // don't make this an attribute because pillar pattern on cylinder depends on it const towerWindow_height = towerWindow_width*1.7 const towerWindowSpacing = groundFloor_height - 0.5*towerWindow_height - towerGroundDoor_height - terrace_height const showSplitWindow = case tower_height > groundFloor_height + 0.5*towerWindow_height + towerWindowSpacing + domeBase_height : true // check if there's enough room to show split window else : false // roof elements const roofRailingHBar_height = 0.1 const roofRailingHBar_depth = roofRailingVBar_width + 0.2 const roofRailingVBar_width = pillar_width const mainRoofRailingSpacing = 0.5*(wallMargin_width - pillar_width) const leftWingRoofAngle = 20 // initial angle of left wing roof, changes when left wing is resized in order to keep height constant const leftWingRoof_height = 2.3 // height of left wing roof // terrace element sizes const terraceStep_width = 0.28 const terraceStep_height = 0.16 const terraceRailing_height = roofRailing_height const terraceRailingHBar_height = roofRailingHBar_height const terraceRailingHBar_depth = roofRailingHBar_depth // brick texture const brickTex_width = 3.25 const brickTex_height = 1.75 const nBricks_y = 5 // 5 bricks in y dir in brick texture const brick_height = brickTex_height/nBricks_y // small float epsilon const eps = 0.000001 // colors const pillar_color = brick_color const ledge_color = brick_color const base_color = lowerBrick_color const stairs_color = lowerBrick_color const railingHBar_color = brick_color const railingVBar_color = brick_color const terrace_color = brick_color const terraceStairs_color = lowerBrick_color // ------------------------------ // Assets // ------------------------------ // assets cylinder_asset = "cylinder.obj" dome_asset = "hemisphere.obj" windowFrame_asset = "window_frame.obj" windowGlass_asset = "window_glass.obj" windowWall_asset = "window_wall.obj" midPillar_asset = "pillar_middle.obj" topPillar_asset = "pillar_top.obj" base_asset = "base.obj" doorFrame_asset = "door_frame.obj" doorWall_asset = "door_wall.obj" doorPlane_asset = "door_plane.obj" lowerLedge_asset = "lowerLedge.obj" midLedge_asset = "midLedge.obj" topLedge_asset = "topLedge.obj" ledgeDecoration_asset = "ledgeDecoration.obj" roofRailingHBar_asset = "railing_top.obj" roofRailingVBar_asset = "railing_base.obj" squareBrick_asset = "squareBrick.obj" // textures brickWall_tex = "brickWall.jpg" door_tex = "door.jpg" // ------------------------------ // Start Rule // ------------------------------ // start rule // non-rectangular lot needs to have appropriate first edge so that front of building has edge 0 after primitiveQuad call @StartRule Lot --> primitiveQuad s(bound_x, 0, bound_z) center(xz) MainLot TerraceLot TowerLot LeftWingLot RightWingLot // ------------------------------ // Volumes // ------------------------------ // set size and position of Main MainLot --> s(main_width, 0, main_depth) t(main_offset_x, 0, main_offset_z) extrude(main_height) Main // main rectangular part of building Main --> comp(f) { front : MainFrontFacade | left : MainLeftFacade | right : MainRightFacade | back : MainBackFacade | top : MainRoof } // set size and position of terrace TerraceLot --> s(terrace_width, 0, terrace_depth) t(terrace_offset_x, 0, terrace_offset_z) extrude(terrace_height) Terrace // terrace next to tower Terrace --> split(z) { terraceStairs_width : TerraceStairsArea | ~1 : TerraceArea } // set size and position of scope for tower, insert cylinder TowerLot --> s(main_width + 2*towerOverlapWithLeftWing, 0, main_width + 2*towerOverlapWithLeftWing) // diameter = main_width + 2*towerOverlapWithLeftWing t(tower_offset_x, 0, tower_offset_z) extrude(tower_height + dome_height) split(y) { tower_height : i(cylinder_asset) Tower | dome_height : Dome } // set size and position of left wing LeftWingLot --> s(leftWing_width, 0, leftWing_depth) t(leftWing_offset_x , 0, leftWing_offset_z) extrude(leftWing_height) LeftWing LeftWingTranslationHandles // left wing LeftWing --> comp(f) { front : LeftWingFacade | side : LeftWingFacade | top : LeftWingRoof } // set size and position of right wing RightWingLot --> s(rightWing_width, 0, rightWing_depth) t(rightWing_offset_x, rightWing_offset_y, rightWing_offset_z) r(0, rAngle, 0) extrude(rightWing_height) RightWing RightWingTranslateHandles // right wing RightWing --> comp(f) { front : RightWingFacade("front") | left : RightWingSideFacade | right : RightWingSideFacade | back : RightWingFacade("back") | top : RightWingRoof } // ------------------------------ // Handles // ------------------------------ // LeftWing translation handles should appear centered on top of obj LeftWingTranslationHandles --> t('0.5, '1.2, '0.5) // move to center of scope [ s(handle_width, handle_width, handle_length) // set scope to handle size t('-0.5, 0, '-0.5) // center handle over obj LeftWingTranslateZHandle ] [ s(handle_length, handle_width, handle_width) t('-0.5, 0, '-0.5) LeftWingTranslateXHandle ] LeftWingTranslateZHandle --> NIL LeftWingTranslateXHandle --> NIL // RightWing translation handles should appear centered on top of obj RightWingTranslateHandles --> t('0.5, '1, '0.5) // move to center of scope [ s(handle_width, handle_width, handle_length) // set scope to handle size r(0, -rAngle, 0) // rotate to align to coord frame of main t('-0.5, 0, '-0.5) // center handle over obj RightWingTranslateZHandle ] [ s(handle_length, handle_width, handle_width) r(0, -rAngle, 0) t('-0.5, 0, '-0.5) RightWingTranslateXHandle ] [ s(handle_width, handle_length, handle_width) r(0, -rAngle, 0) t('-0.5, '-0.5, '-0.5) RightWingTranslateYHandle ] RightWingTranslateZHandle --> NIL RightWingTranslateXHandle --> NIL RightWingTranslateYHandle --> NIL // ------------------------------ // Facades: Main, LeftWing // ------------------------------ // main building, front facade with door MainFrontFacade --> split(y) { groundFloor_height : GroundFloorDoor | {~floor_height : Floor("midFloor", 1, 1, 1)}* | topFloor_height : Floor("topFloor", 1, 1, 1) } // main building, left side facade MainLeftFacade --> split(x) { ~1 : split(y) { groundFloor_height : GroundFloor(1, 0) | {~floor_height : Floor("midFloor", 1, 1, 0)}* | topFloor_height : Floor("topFloor", 1, 1, 0)} | tileWithMargin_width : split(y) { groundFloor_height : GroundFloor(1, 1) | {~floor_height : Floor("midFloor", 1, 1, 1)}* | topFloor_height : Floor("topFloor", 1, 1, 1)} } // main building, right side facade MainRightFacade --> split(x) { tileWithMargin_width : split(y) { groundFloor_height : GroundFloor(1, 1) | {~floor_height : Floor("midFloor", 1, 1, 1)}* | topFloor_height : Floor("topFloor", 1, 1, 1)} | ~1 : split(y) { groundFloor_height : GroundFloor(0, 1) | {~floor_height : Floor("midFloor", 0, 0, 1)}* | topFloor_height : Floor("topFloor", 0, 0, 1)} } // main building, back facade mostly covered by tower MainBackFacade --> split(y) { groundFloor_height : MainBackGroundFloor | { ~floor_height : MainBackUpper }* | topFloor_height : MainBackUpper } // left wing facade LeftWingFacade --> split(y) { groundFloor_height : GroundFloor(1, 1) | {~floor_height : Floor("midFloor", 1, 1, 1)}* } // ------------------------------ // Floors: Main, LeftWing // ------------------------------ // ground floor of Main and LeftWing, with windows // withLeftPillar [0,1] include left pillar // withRightPillar [0,1] include right pillar GroundFloor(withLeftPillar, withRightPillar) --> split(y) { base_height : Base | lowerGround_height - lowerLedge_height : setupProjection(0, scope.xy, brickTex_width, brickTex_height) LowerBrickWall | lowerLedge_height : LowerLedge | upperGround_height - midLedge_height : GroundFloorPanel(withLeftPillar, withRightPillar) | midLedge_height : MidLedge } // upper panel of ground floor, panel containing light bricks and windows // withLeftPillar [0,1] include left pillar // withRightPillar [0,1] include right pillar GroundFloorPanel(withLeftPillar, withRightPillar) --> setupProjection(0, scope.xy, brickTex_width, brickTex_height) split(x) { withLeftPillar*pillar_width : BrickWall | wallMargin_width : BrickWall | ~1 : GroundFloorRepeatingPatternSection | pillar_width : BrickWall | wallMargin_width : BrickWall | withRightPillar*pillar_width : BrickWall } // number of repeating patterns and actual tile width // calculate actual tile width so that tiles are big enough to contain windows numRepeats = floor(scope.sx/(pillar_width + maxWindow_width)) actualTile_width = case numRepeats == 0 : maxWindow_width else : scope.sx/numRepeats - pillar_width // repeating pattern on ground floor of Main and LeftWing: pillar, tile (tile: wall, window, wall) GroundFloorRepeatingPatternSection --> case scope.sx >= pillar_width : split(x) { pillar_width : BrickWall | ~actualTile_width : Tile("groundFloor") }* else : BrickWall // ground floor of Main with door GroundFloorDoor --> split(y) { base_height : Base | lowerGround_height - lowerLedge_height : LowerDoorPanel(false) | lowerLedge_height : LowerLedgePanel(false) | upperGround_height - midLedge_height : UpperDoorPanel(false) | midLedge_height : MidLedge } // mid and top floors // floorType ["midFloor", "topFloor"] // withLeftPillar [0,1] include left pillar // showMiddlePillars [0,1] 1: show pillar, 0: show wall // withRightPillar [0,1] include right pillar Floor(floorType, withLeftPillar, showMiddlePillars, withRightPillar) --> case split.index == split.total - 1 : // top floor split(y) { ~1 : FloorPanel(floorType, withLeftPillar, showMiddlePillars, withRightPillar, 1) | topLedge_height : TopLedge } else : // middle floor split(y) { ~1 : FloorPanel(floorType, withLeftPillar, showMiddlePillars, withRightPillar, 0) | midLedge_height : MidLedge } // pattern for each floor/subfloor (except GroundFloor): margin, repeating tiles, margin // floorType ["midFloor", "topFloor"] // withLeftPillar [0,1] include left pillar // showMiddlePillars [0,1] 1: show pillar, 0: show wall // withRightPillar [0,1] include right pillar // showLedgeDecoration [0,1] show ledge decoration on top of pillar on top floor FloorPanel(floorType, withLeftPillar, showMiddlePillars, withRightPillar, showLedgeDecoration) --> split(x) { withLeftPillar*pillar_width : Pillar(floorType, 1, showLedgeDecoration) | wallMargin_width : YellowWall | ~1 : RepeatingPatternSection(floorType, showMiddlePillars, showLedgeDecoration) | pillar_width : Pillar(floorType, showMiddlePillars, showLedgeDecoration) | wallMargin_width : YellowWall | withRightPillar*pillar_width : Pillar(floorType, 1, showLedgeDecoration) } // repeating pattern on each floor/subfloor: pillar, tile (tile: wall, window, wall) // floorType ["midFloor", "topFloor"] // showMiddlePillars [0,1] 1: show pillar, 0: show wall // showLedgeDecoration [0,1] show ledge decoration on top of pillar on top floor RepeatingPatternSection(floorType, showMiddlePillars, showLedgeDecoration) --> case scope.sx >= pillar_width : split(x) { pillar_width : Pillar(floorType, showMiddlePillars, showLedgeDecoration) | ~actualTile_width : Tile(floorType) }* else : YellowWall // back of main part, ground floor MainBackGroundFloor --> split(y) { base_height : Base | lowerGround_height - lowerLedge_height : setupProjection(0, scope.xy, brickTex_width, brickTex_height) LowerBrickWall | lowerLedge_height : LowerLedge | upperGround_height - midLedge_height : setupProjection(0, scope.xy, brickTex_width, brickTex_height) BrickWall | midLedge_height : MidLedge } // back of main part, upper floors MainBackUpper --> case split.index == split.total - 1 : // top floor split(y) { ~1 : YellowWall | topLedge_height : TopLedge } else : // middle floor split(y) { ~1 : YellowWall | midLedge_height : MidLedge } // ------------------------------ // Door Panels for Main and RightWing // ------------------------------ // facade with door, lower/darker brick wall // hideDoor [true, false] true: do not show door, show bricks LowerDoorPanel(hideDoor) --> case hideDoor : setupProjection(0, scope.xy, brickTex_width, brickTex_height) LowerBrickWall else : setupProjection(0, scope.xy, brickTex_width, brickTex_height) split(x) { ~1 : LowerBrickWall | door_width : DoorPart("lowerBrick") | ~1 : LowerBrickWall } // facade with door, ledge that splits door // hideDoor [true, false] true: do not show door, show ledge LowerLedgePanel(hideDoor) --> case hideDoor : LowerLedge else : split(x) { ~1 : LowerLedge("left") | door_width : DoorPart("lowerLedge") | ~1 : LowerLedge("right") } // facade with door, upper/lighter brick wall // hideDoor [true, false] true: do not show door, show bricks UpperDoorPanel(hideDoor) --> case hideDoor : setupProjection(0, scope.xy, brickTex_width, brickTex_height) BrickWall else : setupProjection(0, scope.xy, brickTex_width, brickTex_height) split(x) { ~1 : BrickWall | door_width : DoorPart("upperBrick") | ~1 : BrickWall } // grow shape to door size, test if door intersects other geometry // fromType ["lowerBrick", "lowerLedge", "upperBrick"] set door size starting from this shape DoorPart(fromType) --> case fromType == "lowerBrick" : set(trim.vertical, false) // disable vertical trimming so scope is not cut off t(0, 0, -door_depth) s('1, door_height, door_depth) primitiveCube() DoorTest(fromType) case fromType == "lowerLedge" : set(trim.vertical, false) t(0, -lowerGround_height + lowerLedge_height, -door_depth) s('1, door_height, door_depth) primitiveCube() DoorTest(fromType) else : set(trim.vertical, false) t(0, -lowerGround_height, -door_depth) s('1, door_height, door_depth) primitiveCube() DoorTest(fromType) // insert door if doesn't intersect other geometry, otherwise insert wall // fromType ["lowerBrick", "lowerLedge", "upperBrick"] reset size from door shape to this shape DoorTest(fromType) --> case touches(intra) : case fromType == "lowerBrick" : t(0, 0, door_depth) s('1, lowerGround_height - lowerLedge_height, 0) LowerBrickWall case fromType == "lowerLedge" : set(trim.vertical, true) t(0, lowerGround_height - lowerLedge_height, door_depth) s('1, lowerLedge_height, 0) LowerLedge else : t(0, lowerGround_height, door_depth) s('1, upperGround_height - midLedge_height, 0) BrickWall else : case fromType == "lowerBrick" : NIL case fromType == "lowerLedge" : NIL else : t(0, 0, door_depth) s('1, lowerGround_height + upperGround_height - midLedge_height, 0) split(y) { door_height : Door Stairs | ~1 : BrickWall } // stairs leading up to doors Stairs --> s(door_width, base_height, '1) t(0, -base_height, 0) center(x) setPivot(xyz, 5) split(y) { ~step_height : Step }* // single step in staircase leading up to doors Step --> s(scope.sx + 2*step_width*(split.index + 1), '1, step_width*(split.index + 1) ) center(x) primitiveCube() color(stairs_color) // ------------------------------ // Tiles for Main and LeftWing // ------------------------------ // tile for each floor: wall, window, wall // floorType ["groundFloor", "midFloor", "topFloor"] Tile(floorType) --> case touches(intra) : case floorType == "groundFloor" : BrickWall else : YellowWall else : case floorType == "groundFloor" : split(x) { ~1 : BrickWall | groundWindow_width : split(y) { groundWindow_height : Window("brickWall") | ~1 : BrickWall } | ~1 : BrickWall } case floorType == "midFloor" : split(x) { ~1 : YellowWall | window_width : split(y) { window_height : Window("yellowWall") | ~1 : YellowWall } | ~1 : YellowWall } case floorType == "topFloor" : split(x) { ~1 : YellowWall | topWindow_width : split(y) { topWindow_height : Window("yellowWall") | ~1 : YellowWall } | topWindow_width : split(y) { topWindow_height : Window("yellowWall") | ~1 : YellowWall } | ~1 : YellowWall } else : case floorType == "groundFloor" : BrickWall else : YellowWall // ------------------------------ // Right Wing Facade/Floors // ------------------------------ // right wing facade with windows // similar to GroundFloor // faceType ["front", "back"] RightWingFacade(faceType) --> split(y) { base_height : Base | lowerGround_height - lowerLedge_height : setupProjection(0, scope.xy, brickTex_width, brickTex_height) LowerBrickWall | lowerLedge_height : LowerLedge | upperGround_height - midLedge_height : RightWingPanel(faceType) | midLedge_height : TopLedge } // right wing, panel with windows and lighter color bricks // faceType ["front", "back"] RightWingPanel(faceType) --> case faceType == "front" : split(x) { {pillar_width : BrickColumn | ~rightWingTile_width : RightWingTile | pillar_width : BrickColumn | whiteColumn_width : WhiteColumn }* | pillar_width : BrickColumn | ~rightWingTile_width : RightWingTile | pillar_width : BrickColumn | rightWingMargin_width : RightWingMargin(faceType)} else : split(x) { rightWingMargin_width : RightWingMargin(faceType) | {pillar_width : BrickColumn | ~rightWingTile_width : RightWingTile | pillar_width : BrickColumn | whiteColumn_width : WhiteColumn }* | pillar_width : BrickColumn | ~rightWingTile_width : RightWingTile | pillar_width : BrickColumn } // right wing, margin on left side of facade // faceType ["front", "back"] RightWingMargin(faceType) --> case faceType == "front" : split(x) { ~1 : NIL | pillar_width : RightWingLedgeDecoration } setupProjection(0, scope.xy, brickTex_width, brickTex_height) BrickWall else : split(x) { pillar_width : RightWingLedgeDecoration | ~1 : NIL} setupProjection(0, scope.xy, brickTex_width, brickTex_height) BrickWall // right wing tile: bricks, window, bricks RightWingTile --> case touches(intra) : setupProjection(0, scope.xy, brickTex_width, brickTex_height) BrickWall else : case scope.sx + eps >= groundWindow_width && scope.sy + eps >= groundWindow_height : RightWingTileLedgeDecoration setupProjection(0, scope.xy, brickTex_width, brickTex_height) split(x) { ~1 : BrickWall | groundWindow_width : split(y) { groundWindow_height : Window("brickWall") | ~1 : BrickWall } | ~1 : BrickWall } else : setupProjection(0, scope.xy, brickTex_width, brickTex_height) BrickWall // ledge decoration above windows in Right Wing RightWingTileLedgeDecoration --> s(pillar_width, '1, '1) center(x) RightWingLedgeDecoration // don't show right wing door if right wing is not on the ground noRightWingDoor = case rightWing_offset_y == 0 : false else : true // right wing side facade, with door // similar to GroundFloorDoor RightWingSideFacade --> RightWingDoorLedgeDecorations split(y) { base_height : Base | lowerGround_height - lowerLedge_height : LowerDoorPanel(noRightWingDoor) | lowerLedge_height : LowerLedgePanel(noRightWingDoor) | upperGround_height - midLedge_height : UpperDoorPanel(noRightWingDoor) | midLedge_height : TopLedge } // ledge decorations on top of right wing door panel RightWingDoorLedgeDecorations --> split(y) { ~1 : split(x) { { pillar_width : RightWingLedgeDecoration | rightWingDecoSpacing : NIL }* | pillar_width : RightWingLedgeDecoration } | midLedge_height : NIL } // ------------------------------ // Tower Facade/Floors // ------------------------------ // whole tower Tower --> r(scopeCenter, 0, -90, 0) // rotate to set origin of uv coords on left side of tower rotateScope(0, 90, 0) split(y) { groundFloor_height : TowerGround | ~1 : TowerMiddle | domeBase_height : DomeBase } // ground floor of tower TowerGround --> tileUV(0, brickTex_width, brickTex_height) split(y) { base_height : TowerBase | lowerGround_height : TowerGroundLowerPart | upperGround_height : TowerGroundUpperPart } // base geometry at bottom of tower TowerBase --> comp(f) { side : Base } // lower part of ground floor of tower, contains darker colored bricks TowerGroundLowerPart --> translateUV(0, 0, -base_height/brickTex_height) split(y) { ~1 : TowerLowerBrickWall | lowerLedge_height : TowerLowerLedge } // lower ledge on tower TowerLowerLedge --> comp(f) { side : LowerLedge } // upper part of ground floor of tower, contains lighter colored bricks TowerGroundUpperPart --> translateUV(0, 0, -(base_height + lowerGround_height)/brickTex_height) split(u, unitSpace, 0) { ~1 : split(u, unitSpace, 0) { ~1 : TowerBrickWall | towerGroundDoor_width : TowerGroundDoorPanel | ~1 : TowerBrickWall } | ~1 : TowerBrickWall } // vertical strip with tower door on ground floor TowerGroundDoorPanel --> split(y) { terrace_height - base_height - lowerGround_height : TowerBrickWall | towerGroundDoor_height : TowerGroundDoor | ~1 : TowerBrickWall } // tower door on ground floor TowerGroundDoor --> rotateScope(0, 180, 0) TowerDoor // middle part of tower with yellow wall TowerMiddle --> split(y) { ~1 : TowerMiddlePanel | topLedge_height : TowerMiddleLedge } // middle part of tower with yellow wall, except ledge TowerMiddlePanel --> YellowWall TowerPillarPattern("tower") split(u, unitSpace, 0) { ~1 : split(u, unitSpace, 0) { ~1 : NIL | towerWindow_width : TowerWindowPanel | ~1 : NIL } | ~1 : NIL } // small constant to get rid of top/bottom of cylinder during split (comp will change scope orientation) const split_eps = 0.01 // vertical strip with the tower windows TowerWindowPanel --> split(y) { split_eps : NIL // to get rid of bottom of cylinder | 0.5*towerWindow_height - split_eps : TowerSplitWindow | { towerWindowSpacing : NIL | towerWindow_height : rotateScope(0, 180, 0) TowerWindow }* | towerWindowSpacing : NIL } // tower window above door, splits bricks and yellow wall TowerSplitWindow --> case showSplitWindow : s('1, 2*(scope.sy + split_eps ), '1) t(0, -0.5*scope.sy - split_eps , 0) rotateScope(0, 180, 0) TowerWindow else : NIL // pillar pattern on tower // towerPart ["tower", "domeBase"] part of tower to put pillars on TowerPillarPattern(towerPart) --> split(u, unitSpace, 0) { ~wallMargin_width : NIL | pillar_width : TowerPillar(towerPart) | ~wallMargin_width : NIL | pillar_width : TowerPillar(towerPart) | ~2.1 : NIL | pillar_width : ImagTowerPillar(towerPart) | ~2.1 : NIL | pillar_width : TowerPillar(towerPart) | ~wallMargin_width : NIL | pillar_width : TowerPillar(towerPart) | ~(2*wallMargin_width) : NIL | pillar_width : TowerPillar(towerPart) | ~wallMargin_width : NIL | pillar_width : TowerPillar(towerPart) | ~4.6 : NIL | pillar_width : TowerPillar(towerPart) | ~wallMargin_width : NIL | pillar_width : TowerPillar(towerPart) | ~wallMargin_width : NIL } // pillar on tower // towerPart ["tower", "domeBase"] part of tower to put pillars on TowerPillar(towerPart) --> case towerPart == "tower" : comp(f) { vertical = Pillar("midFloor", 1, 1) } else : comp(f) { vertical = Pillar("topFloor", 1, 0) } // imaginary pillar for ledge decorations on top of tower windows // towerPart ["tower", "domeBase"] part of tower with ledge decoration on top, don't put ledge decoration on domeBase ImagTowerPillar(towerPart) --> case towerPart == "tower" : comp(f) { vertical = LedgeDecoration(1) } else : NIL // create ledge above tower's middle part TowerMiddleLedge --> comp(f) { side : TopLedge } // base below dome DomeBase --> split(y) { ~1 : DomeBasePanel | lowerLedge_height : DomeBaseLedge } // base below dome, below ledges DomeBasePanel --> split(u, unitSpace, 0) { ~1 : YellowWall | ~1 : split(u, unitSpace, 0) { ~1 : YellowWall | towerRoofDoor_width : TowerRoofDoorPanel | ~1 : YellowWall } } TowerPillarPattern("domeBase") // tower door, roof entrance TowerRoofDoorPanel --> split(y) { towerRoofDoor_height : TowerDoor | ~1 : YellowWall } // create ledge above dome base (below dome) DomeBaseLedge --> comp(f) { side : ColorLedge(pillar_color) } // hemispherical dome on top of tower Dome --> i(dome_asset) color(dome_color) DomeStructure. comp(f) { bottom : NIL | all = DomeHemisphere } // take bottom off dome (equals sign keeps rest of hemisphere intact as connected geometry, DomeHemisphere rule is called once) // dome without bottom DomeHemisphere --> comp(f){ border : DomePanel } // dome faces with ledge, each face is a panel DomePanel --> alignScopeToGeometry(zUp, 0, 3) split(y) { lowerLedge_height/2 : NIL | lowerLedge_height : ColorLedge (dome_color) | ~1 : NIL } // ------------------------------ // Terrace // ------------------------------ // area of terrace with railings TerraceArea --> [ color(terrace_color) TerraceAreaFloor. ] comp(f) { top : TerraceRailing } // railings on terrace TerraceRailing --> split(x) { terraceRailingHBar_depth : TerraceRailingPiece | ~1 : NIL | terraceRailingHBar_depth : TerraceRailingPiece } // single terrace railing, top horizontal piece and wall support TerraceRailingPiece --> extrude(terraceRailing_height) split(y) { ~1 : TerraceRailingWall | terraceRailingHBar_height : TerraceRailingHBar } // wall part of terrace railing TerraceRailingWall --> s(0.5*terraceRailingHBar_depth, '1, '1) center(x) comp(f) { all : TerraceRailingWallFace } // planar face of terrace railing wall TerraceRailingWallFace --> setupProjection(0, scope.xy, brickTex_width, brickTex_height) BrickWall // horizontal part on top of terrace railing TerraceRailingHBar --> setPivot(xyz, 1) i(roofRailingHBar_asset) color(terrace_color) // stairs (on both sides) leading to terrace TerraceStairsArea --> color(terraceStairs_color) TerraceStairsFlatArea. comp(f) { left : TerraceStairs | right : TerraceStairs } // single staircase up to terrace TerraceStairs --> rotateScope(0, 0, 180) split(y) { ~terraceStep_height : TerraceStep }* // single step in terrace staircase TerraceStep --> extrude(split.index*terraceStep_width) // ------------------------------ // Roofs // ------------------------------ // roof of main part MainRoof --> [ color(roof_color) RoofFloor. ] MainRoofRailing // railings on roof of main part MainRoofRailing --> extrude(roofRailing_height) comp(f) { side : MainRailing } // railing piece along one side of building on main roof MainRailing --> t(0, 0, -roofRailingHBar_depth) extrude(roofRailingHBar_depth) setPivot(yzx, 3) split(y) { ~1 : MainRailingVBars | roofRailingHBar_height : HBar } // vertical bars on railing piece on main roof MainRailingVBars --> s(scope.sx - roofRailingHBar_depth + roofRailingVBar_width, '1, roofRailingVBar_width) center(xz) split(x) { { roofRailingVBar_width : VBar | ~mainRoofRailingSpacing : NIL }* | roofRailingVBar_width : NIL} // roof of right wing RightWingRoof --> // roof floor [ color(roof_color) RightWingRoofFloor. ] // Note: no railing on left side so that window is not occluded (also why extruding the roof followed by comp doesn't work) // railing above front and back facades (facades with windows) [ split(y) { roofRailingHBar_depth : extrude(roofRailing_height) comp(f) { front : RightWingRailing("front") } // use comp to set trim planes | ~1 : NIL | roofRailingHBar_depth : extrude(roofRailing_height) comp(f) { back : RightWingRailing("back") } } ] // railing above side facade (facade with door) [ split(x) { ~1 : NIL | roofRailingHBar_depth : extrude(roofRailing_height) comp(f) { right : RightWingRailing("side") } } ] // railing for a facade side on top of RightWing roof // faceType ["front", "back", "side"] RightWingRailing(faceType) --> case faceType == "front" : t(0, 0, -roofRailingHBar_depth) extrude(roofRailingHBar_depth) setPivot(yzx, 3) split(x) { {~rightWingTile_width + 2*pillar_width : RightWingRailingTile | whiteColumn_width : NIL }* | ~rightWingTile_width + 2*pillar_width : RightWingRailingTile | rightWingMargin_width : RightWingRailingMargin } case faceType == "back" : t(0, 0, -roofRailingHBar_depth) extrude(roofRailingHBar_depth) setPivot(yzx, 3) split(x) { rightWingMargin_width : RightWingRailingMargin | {~rightWingTile_width + 2*pillar_width : RightWingRailingTile | whiteColumn_width : NIL }* | ~rightWingTile_width + 2*pillar_width : RightWingRailingTile } else : // "side" t(0, 0, -roofRailingHBar_depth) extrude(roofRailingHBar_depth) setPivot(yzx, 3) split(y) { ~1 : RightWingSideRailingVBars | roofRailingHBar_height : HBar } // right wing roof, railing piece above window tile RightWingRailingTile --> set(trim.vertical, false) // disable vertical trimming, don't cut horizontal bars for railing tile split(y) { ~1 : split(x) { pillar_width : RightWingVBarBox | ~1 : NIL | pillar_width : RightWingVBarBox | ~1 : NIL | pillar_width : RightWingVBarBox } | roofRailingHBar_height : HBar } // horizontal roof railing piece over margin area of right wing RightWingRailingMargin --> split(y) { ~1 : NIL | roofRailingHBar_height : HBar } // vertical bars in railing over right side of right wing, with uniform spacing between vertical bars RightWingSideRailingVBars --> split(x) { roofRailingHBar_depth/2 - roofRailingVBar_width/2 : NIL | { pillar_width : RightWingVBarBox | ~rightWingDecoSpacing : NIL }* | pillar_width : RightWingVBarBox | roofRailingHBar_depth/2 - roofRailingVBar_width/2 : NIL } // scope box for vertical railing piece on right wing roof RightWingVBarBox --> s('1, '1, roofRailingVBar_width) center(z) VBar // roof of left wing LeftWingRoof --> s('2, '1, '1) // create roof on double sized roof footprint roofHip(leftWingRoofAngle) s('1, leftWingRoof_height, '1) // set roof height color(roof_color) split(x) { '0.5 : cleanupGeometry(vertices, 0.1) LeftWingRoofSolid. | '0.5 : NIL } // ------------------------------ // Materials and Assets // ------------------------------ // base of all building parts Base --> s(scope.sx + 2*base_depth, '1, base_depth) // extend in x past facade, will get trimmed center(x) i(base_asset) color(base_color) // door on Main and RightWing Door --> s('1, '1, door_depth) DoorFrame DoorWall // height of door asset door_assetHeight = assetInfo(doorWall_asset, ty) - assetInfo(doorFrame_asset, ty) + assetInfo(doorWall_asset, sy) // relative size of door frame height to total door asset height doorFrame_relSize = assetInfo(doorFrame_asset, sy)/door_assetHeight // relative size of door wall height to total door asset height doorWall_relSize = assetInfo(doorWall_asset, sy)/door_assetHeight // frame of door, including inner hall and ground DoorFrame --> t(0, 0, -door_depth*0.95) DoorPlane split(y) { scope.sy*doorFrame_relSize : i(doorFrame_asset) color(brick_color) DoorFrameAsset. | ~1 : NIL } // plane containing door texture DoorPlane --> i(doorPlane_asset) split(x) { ~1 : YellowWall | '0.7 : split(y) { '0.75 : DoorTextureArea | ~1 : YellowWall } | ~1 : YellowWall } // part of the door with the door texture DoorTextureArea --> setupProjection(0, scope.xy, '1, '1) texture(door_tex) projectUV(0) // wall pieces in the top corners above the rounded door frame DoorWall --> split(y) { ~1 : NIL | scope.sy*doorWall_relSize : i(doorWall_asset) BrickWall } // window // wallType ["brickWall", "yellowWall"] type of wall in top corners above rounded window frame Window(wallType) --> s('1, '1, window_depth) WindowFrame WindowGlass WindowWall(wallType) // frame and inner grid of window WindowFrame --> t(0, 0, '-0.8) i(windowFrame_asset) color(brick_color) // window glass WindowGlass --> t(0, 0, '-0.15) i(windowGlass_asset) Glass(false) // not transparent // relative size of window wall height to window height windowWall_relSize = assetInfo(windowWall_asset, sy)/assetInfo(windowFrame_asset, sy) // wall pieces in the top corners above the rounded window frame // wallType ["brickWall", "yellowWall"] type of wall in top corners above rounded window frame WindowWall(wallType) --> case wallType == "brickWall" : split(y) { ~1 : NIL | scope.sy*windowWall_relSize : i(windowWall_asset) BrickWall } else : split(y) { ~1 : NIL | scope.sy*windowWall_relSize : i(windowWall_asset) YellowWall } // lower part of GroundFloor (with darker gray bricks) LowerBrickWall --> color(lowerBrick_color) texture(brickWall_tex) projectUV(0) // upper part of GroundFloor (with lighter gray bricks) BrickWall --> color(brick_color) texture(brickWall_tex) projectUV(0) // on tower, lower part of GroundFloor (with darker gray bricks) TowerLowerBrickWall --> color(lowerBrick_color) texture(brickWall_tex) // on tower, upper part of GroundFloor (with lighter gray bricks) TowerBrickWall --> color(brick_color) texture(brickWall_tex) // yellow wall on upper floors YellowWall --> color(wall_color) // ledge below GroundFloor windows LowerLedge --> s(scope.sx + 2*lowerLedge_depth, '1, lowerLedge_depth) // extend in x past facade, will get trimmed center(x) i(lowerLedge_asset) color(lowerBrick_color) // ledge going through door, create each side separately // neighSide ["left", "right"] left or right of door? LowerLedge(neighSide) --> case neighSide == "left" : s(scope.sx + lowerLedge_depth, '1, lowerLedge_depth) // extend in x past facade in one dir, will get trimmed t(-lowerLedge_depth, 0, 0) i(lowerLedge_asset) color(lowerBrick_color) else : s(scope.sx + lowerLedge_depth, '1, lowerLedge_depth) // extend in x past facade in one dir, will get trimmed i(lowerLedge_asset) color(lowerBrick_color) // same asset as lower ledge, but allows a color parameter // param_ledge_color hex code for color of ledge ColorLedge (param_ledge_color) --> s(scope.sx + 2*lowerLedge_depth, '1, lowerLedge_depth) // extend in x past facade, will get trimmed center(x) i(lowerLedge_asset) color(param_ledge_color) // ledge above each floor except top floor MidLedge --> s(scope.sx + 2*midLedge_depth, '1, midLedge_depth) // extend in x past facade, will get trimmed center(x) color(ledge_color) i(midLedge_asset) color(ledge_color) // ledge above top floor of any building part TopLedge --> s(scope.sx + 2*topLedge_depth, '1, topLedge_depth) // extend in x past facade, will get trimmed center(x) i(topLedge_asset) color(ledge_color) // pillar/columns structure flanking the windows, also top ledge decorations that appear above pillars // floorType ["midFloor", "topFloor"] // showPillar [0,1] show pillar, 0: show wall // showLedgeDecoration [0,1] show ledge decoration on top of pillar on top floor Pillar(floorType, showPillar, showLedgeDecoration) --> case showPillar==0 : YellowWall LedgeDecoration(showLedgeDecoration) else : case floorType == "topFloor" : [ s('1, '1, pillar_depth) i(topPillar_asset) color(pillar_color) TopPillar. ] LedgeDecoration(showLedgeDecoration) else : [ s('1, '1, pillar_depth) i(midPillar_asset) color(pillar_color) MidPillar. ] LedgeDecoration(showLedgeDecoration) // ledge decoration above pillar on top floor // showLedgeDecoration [0,1] show ledge decoration on top of pillar on top floor LedgeDecoration(showLedgeDecoration) --> case showLedgeDecoration == 1 : [ t(0, scope.sy + 0.1*topLedge_height, 0) s('0.33, 0.5*topLedge_height, 0.15) i(ledgeDecoration_asset) color(ledge_color) LedgeDecoration1. ] [ t('0.67, scope.sy + 0.1*topLedge_height, 0) s('0.33, 0.5*topLedge_height, 0.15) i(ledgeDecoration_asset) color(ledge_color) LedgeDecoration2. ] else : NIL // ledge decorations on top ledge of right wing RightWingLedgeDecoration --> [ t(0, scope.sy + 0.15*midLedge_height, 0) s('0.33, 0.45*midLedge_height, 0.15) i(ledgeDecoration_asset) color(ledge_color) LedgeDecoration1. ] [ t('0.67, scope.sy + 0.15*midLedge_height, 0) s('0.33, 0.45*midLedge_height, 0.15) i(ledgeDecoration_asset) color(ledge_color) LedgeDecoration2. ] // brick columns flanking right wing windows BrickColumn --> RightWingLedgeDecoration split(y) { brick_height : SingleBrick }* // single brick in brick column on right wing facade SingleBrick --> s('1, '1, 0.07) i(squareBrick_asset) color(brick_color) // white column in between tiles in right wing facade WhiteColumn --> color(column_color) // flat, horizontal, top part of railing HBar --> i(roofRailingHBar_asset) color(railingHBar_color) // vertical part of railing, single piece VBar --> set(trim.vertical, false) // disable vertical trimming for the following elements to prevent the vertical corner bars from being cut i(roofRailingVBar_asset) color(railingVBar_color) // tower door, ground floor and rooftop entrances TowerDoor --> s('1, '1, 0.1) t(0, 0, -0.1) primitiveCube() reverseNormals() comp(f) { front : DoorTextureArea | back : NIL | all : color(brick_color) PlainWall. } // tower window TowerWindow --> case scope.sy + eps >= towerWindow_height : t(0, 0, scope.sz + 0.2*window_depth) s('1, '1, window_depth) WindowFrame WindowGlass else : YellowWall // ------ // glass material for windows // isTransparent [true, false] true: use default opacity, false: opacity=1 Glass(isTransparent) --> case glass_material == "CE Blue": case isTransparent : color(0.7,0.75,1) set(material.ambient.r,0) set(material.ambient.g,0) set(material.ambient.b,1) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,0.6) else : color(0.7,0.75,1) set(material.ambient.r,0) set(material.ambient.g,0) set(material.ambient.b,1) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,1) case glass_material == "CE Dark Blue": case isTransparent : color(0.2,0.2,0.25) set(material.ambient.r,0) set(material.ambient.g,0) set(material.ambient.b,0.1) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.6) set(material.shininess,50) set(material.opacity,0.8) else : color(0.2,0.2,0.25) set(material.ambient.r,0) set(material.ambient.g,0) set(material.ambient.b,0.1) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.6) set(material.shininess,50) set(material.opacity,1) case glass_material == "CE Green": case isTransparent : color(0.4,0.5,0.4) set(material.ambient.r,0) set(material.ambient.g,0.2) set(material.ambient.b,0.05) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,0.6) else : color(0.4,0.5,0.4) set(material.ambient.r,0) set(material.ambient.g,0.2) set(material.ambient.b,0.05) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,1) case glass_material == "CE Brown": case isTransparent : color(0.3,0.25,0.2) set(material.ambient.r,0.2) set(material.ambient.g,0.1) set(material.ambient.b,0) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,0.6) else : color(0.3,0.25,0.2) set(material.ambient.r,0.2) set(material.ambient.g,0.1) set(material.ambient.b,0) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.8) set(material.shininess,50) set(material.opacity,1) case glass_material == "CE Black": case isTransparent : color(0.1,0.1,0.1) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.7) set(material.shininess,50) set(material.opacity,0.8) else : color(0.1,0.1,0.1) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.7) set(material.shininess,50) set(material.opacity,1) case glass_material == "iRay Glass": case isTransparent : color(0.35,0.37,0.5) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.8) set(material.shininess,128) set(material.opacity,0.8) else : color(0.35,0.37,0.5) set(material.specular.r,0.8) set(material.specular.g,0.8) set(material.specular.b,0.8) set(material.reflectivity,0.8) set(material.shininess,128) set(material.opacity,1) else: case isTransparent : color(1,1,1) set(material.opacity,0.8) else : color(1,1,1) set(material.opacity,1)
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。