def patio_chair(width=0.45, length=0.45, seat_height=0.40): seat_thick = 0.05 seat = ddd.rect([0, 0, width, length], name="Chair seat").recenter().extrude(seat_thick) seat = ddd.uv.map_cubic(seat) seat = seat.translate([0, 0, seat_height - seat_thick]) stool = ddd.group3([seat], name="Chair stool") leg_thick = 0.05 leg_padding = leg_thick for c in [(1, 1), (-1, 1), (-1, -1), (1, -1)]: leg = ddd.point([c[0] * (width / 2 - leg_padding), c[1] * (length / 2 - leg_padding)]).buffer(leg_thick / 2).extrude(seat_height - seat_thick) leg = ddd.uv.map_cylindrical(leg) stool.append(leg) stool = stool.material(ddd.mats.steel) stool = ddd.collision.aabox_from_aabb(stool) back_height = 0.3 back = ddd.rect([width, seat_thick], name="Chair Back").recenter().extrude(back_height) back = back.material(ddd.mats.steel) back = ddd.uv.map_cubic(back) back = back.translate([0, length / 2 - seat_thick, seat_height]) back = ddd.collision.aabox_from_aabb(back) chair = ddd.group3([stool, back], name="Chair") chair.extra['ddd:mass'] = 2.5 chair = ddd.meshops.batch_by_material(chair).clean(remove_degenerate=False) return chair
def childrens_playground_arc(length=3.25, width=1.0, sides=7, height=None): arc_thick = 0.08 bar_thick = 0.05 if height is None: height = length / 2 * 0.9 circleline = ddd.regularpolygon(sides * 2, name="Childrens Playground Arc Side Arc").rotate(-math.pi / 2).outline().scale([length / 2, height]) arcline = circleline.intersection(ddd.rect([-length, 0.1, length, height * 2])) arc = circleline.buffer(arc_thick / 2).intersection(ddd.rect([-length, 0, length, height * 2])) arc = arc.extrude(arc_thick, center=True).material(ddd.mats.metal_paint_red) arc = arc.rotate(ddd.ROT_FLOOR_TO_FRONT) arc = ddd.uv.map_cubic(arc) arc1 = arc.copy().translate([0, -width / 2, 0]) arc2 = arc.copy().translate([0, +width / 2, 0]) item = ddd.group([arc1, arc2]) bar = ddd.point(name="Childrens Playground Arc Bar").buffer(bar_thick / 2).extrude(width - arc_thick, center=True).rotate(ddd.ROT_FLOOR_TO_FRONT) bar = ddd.uv.map_cubic(bar) mats = [ddd.mats.metal_paint_white, ddd.mats.metal_paint_red] for idx, p in enumerate(arcline.geom.coords[1:-1]): pbar = bar.copy().translate([p[0], 0, p[1]]) pbar = pbar.material(mats[idx % 2]) item.append(pbar) item = ddd.meshops.batch_by_material(item).clean(remove_degenerate=False) return item
def bench(length=1.40, height=1.00, width=0.8, seat_height=0.45, legs=2, hangout=0.20): seat_thick = 0.05 leg_thick = 0.05 leg_padding = 0.3 leg_width = width - leg_padding leg_height = seat_height - seat_thick seat = ddd.rect([-length/ 2.0, -width / 2.0, length / 2.0, width / 2.0], name="Bench Seat") seat = seat.extrude(-seat_thick).translate([0, 0, seat_height]) legs_objs = [] leg_spacing = (length - leg_padding * 2) / (legs - 1) for leg_idx in range(legs): leg = ddd.rect([-leg_thick / 2, -leg_width / 2.0, leg_thick / 2, leg_width / 2], name="Bench Leg").extrude(leg_height) leg = leg.translate([-(length / 2) + leg_padding + leg_spacing * leg_idx, 0, 0]) legs_objs.append(leg) bench = ddd.group([seat] + legs_objs, name="Bench") bench = bench.material(ddd.mats.stone) bench = ddd.uv.map_cubic(bench) bench.name = "Bench" bench.mat = None # to avoid batching issues bench = ddd.meshops.batch_by_material(bench).clean(remove_degenerate=False) return bench
def powertower(height=14.0): obj_pole = ddd.rect([-0.5, -0.5, 0.5, 0.5]).extrude(height) obj_horz1 = ddd.rect([-2.5, -0.3, 2.5, 0.3]).extrude(0.6).translate([0, 0, height - 2]) obj_horz2 = ddd.rect([-3, -0.3, 3, 0.3]).extrude(0.6).translate([0, 0, height - 4]) obj = ddd.group([obj_pole, obj_horz1, obj_horz2]) obj = obj.material(ddd.mats.steel) obj = ddd.uv.map_cubic(obj) obj = obj.combine() return obj
def portal(width=3.6, height=2.8, frame_width=0.08, frame_depth=0.05, door_width=1.4, top_panel_height=0.8, bottom_panel_height=0.4): """ A portal door set. """ pdoor = door(door_width, height - top_panel_height) obj = ddd.rect([-width * 0.5, 0, width * 0.5, height], name="Door Frame") obj = obj.subtract( ddd.rect([ -width * 0.5 + frame_width, -1, width * 0.5 - frame_width, height - frame_width ])) if top_panel_height > 0: obj = obj.union( ddd.rect([ -width * 0.5, height - top_panel_height, width * 0.5, height - top_panel_height + frame_width ])) if bottom_panel_height > 0: obj = obj.union( ddd.rect([-width * 0.5, 0, width * 0.5, bottom_panel_height])) obj = obj.extrude(frame_depth) obj = obj.material(ddd.mats.wood) obj = ddd.uv.map_cubic(obj) glass = ddd.rect([ -width * 0.5 + frame_width, bottom_panel_height, width * 0.5 - frame_width, height - frame_width ], name="Window") #obj = obj.extrude(depth) glass = glass.triangulate() glass = glass.translate([0, 0, 0.02]) # Translate a bit to avoid z-fighting glass = glass.material(ddd.mats.glass) glass = ddd.uv.map_cubic(glass) obj.append(glass) obj = obj.rotate(ddd.ROT_FLOOR_TO_FRONT) obj.append(pdoor) return obj
def char(self, ch): #print(ch) try: glyph = self.atlas.index['faces'][self.fontface]['glyphs'][str(ord(ch))] except KeyError as e: logger.error("Could not find font character (font=%s, char=%s)", self.fontface, ch) return (None, None) #print(glyph) quad = ddd.rect().triangulate() quad = ddd.uv.map_cubic(quad) texture_size = 4096 font_size = 64 font_size_norm = font_size / texture_size x0 = glyph['x0'] / texture_size y0 = glyph['y0'] / texture_size width = glyph['width'] / texture_size height = glyph['height'] / texture_size quad.extra['uv'] = [(x * width + x0, 1.0 - y0 - height + (y * height)) for x, y in quad.extra['uv']] #quad.extra['uv'] = [[x * 0.1 + 0.5, y * 0.1 + 0.8] for x, y in quad.extra['uv']] #print(quad.extra['uv']) #kerning = face.get_kerning(ch, 'x') # or from previous, actually? #print(kerning) result = quad if width > 0 and height > 0: result = result.scale([width / font_size_norm, height / font_size_norm, 1]) return (result, glyph)
def waste_container(width=1.41, length=0.76, height=1.23): base = ddd.rect([width, length]).recenter() wheelaxis_height = 0.175 base_size_factor = 0.85 steps = ((base_size_factor, 0.00), (0.92, 0.07), (0.95, 0.95), (1.0, 0.95), (1.0, 1.0), (0.90, 1.0), (base_size_factor - 0.05, 0.15)) obj = extrude_step_multi(base, steps, cap=True, base=True, scale_y=height-wheelaxis_height, scale_x=1.0) obj.name = "Waste Container" # (Open) obj = obj.material(ddd.mats.plastic_green) obj = ddd.uv.map_cubic(obj) # Wheels wheels_padding = 0.08 wheelpos = base.scale([base_size_factor, base_size_factor]).buffer(-wheels_padding) wheel_axis = vehicles.cart_wheel_and_axis().rotate(ddd.ROT_TOP_CW) wheels = ddd.align.clone_on_coords(wheel_axis, wheelpos) for w in wheels.children: nw = w.rotate([0, 0, random.uniform(-1, 1) * math.pi * 0.3], origin="bounds_center") w.replace(nw) obj.append(wheels) obj = obj.translate([0, 0, wheelaxis_height]) return obj
def osm_structured_generate_areas_ground_fill(osm, root, logger): """ Generates (fills) remaining ground areas (not between ways or otherwise occupied by other areas). Ground must come after every other area (interways, etc), as it is used to "fill" missing gaps. """ area_crop = osm.area_filter logger.info("Generating terrain (bounds: %s)", area_crop.bounds) union = ddd.group2([root.find("/Ways").select('["ddd:layer" ~ "^(0|-1a)$"]'), root.find("/Areas").select('["ddd:layer" ~ "^(0|-1a)$"]'), #root.find("/Water") ]) #union = union.clean_replace(eps=0.01) ##union = union.clean(eps=0.01) union = osm.areas2.generate_union_safe(union) union = union.clean(eps=0.01) # Removing this causes a core dump during 3D generation terr = ddd.rect(area_crop.bounds, name="Ground") terr = terr.material(ddd.mats.terrain) terr.extra["ddd:layer"] = "0" terr.extra["ddd:height"] = 0 try: terr = terr.subtract(union) terr = terr.clean(eps=0.0) #eps=0.01) except Exception as e: logger.error("Could not subtract areas_2d from terrain.") return root.find("/Areas").append(terr)
def basketball_hoop(): """ """ ring_r = 0.45 / 2 ring = ddd.disc( r=ring_r, name="Basketball hoop ring").outline().buffer(0.015).extrude(-0.03) ring = ring.material(ddd.mats.steel) #ring = ddd.uv.map_cubic(ring) board_w = 1.80 board_h = 1.20 board_ring_h = 0.30 board_shape = ddd.rect( [board_w, board_h], name="Basketball hoop board").recenter().extrude(-0.05) board_shape = board_shape.material(ddd.mats.plastic_transparent) #board_shape = ddd.uv.map_cubic(board_shape) board_shape = board_shape.rotate(ddd.ROT_FLOOR_TO_FRONT) board_shape = board_shape.translate( [0, ring_r + 0.15, board_h / 2 - board_ring_h]) board = ddd.group3([ring, board_shape], name="Basketball hoop") board = board.translate([0, 0, 3.05]) pole = curvedpost(3.25, arm_length=1.5, corner_radius=0.4).rotate(ddd.ROT_TOP_CCW) pole = pole.material(ddd.mats.metal_paint_red) pole.prop_set('uv', None, True) pole = pole.translate([0, ring_r + 0.15 + 0.05 + 1.5, 0]) hoop = ddd.group3([pole, board], name="Basketball hoop with pole") return hoop
def waste_container_lid(width=1.41, length=0.76, height=0.15): base = ddd.rect([width, length]).recenter() obj = base.extrude_step(base, height * 0.3) obj = obj.extrude_step(base.buffer(-length * 0.2).translate([0, length * 0.1, 0]), height * 0.7) obj.name = "Waste Container Lid" # (Open) obj = obj.material(ddd.mats.plastic_green) obj = ddd.uv.map_cubic(obj) return obj
def door_handle_bar(width=0.1, height=0.3, depth=0.05, separation=0.06): """ """ shape = ddd.rect([width, height], name="Door Handle").recenter() obj = shape.scale([0.5, 0.5]).extrude_step(shape, separation, base=False) obj = obj.extrude_step(shape, depth) obj = obj.material(ddd.mats.metal) obj = ddd.uv.map_cubic(obj) obj = obj.rotate(ddd.ROT_FLOOR_TO_FRONT) return obj
def pipeline_logo(pipeline, root): """ """ logo = ddd.group3() thick = 0.125 margin = 0.4 line_out = ddd.line([ (1.0, 0.0, 0.4), (1.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 0.0, 1.0), (1.0, 0.0, 0.6), ]) base = ddd.rect([thick, thick], name="Logo exterior").recenter() item = base.extrude_along(line_out) item = item.material(ddd.mats.steel) #item = item.rotate([0, 0, 0.2]) item = ddd.uv.map_cubic( item ) # FIXME: One of the corner vertices are not being split (but they are if slightly rotated) logo.append(item) line_in = ddd.line([ (1.0 - margin, 1.0 - margin - 0.1, 1), (1.0 - margin, 1.0 - margin, 1), (0.0, 1.0 - margin, 1), (0.0, 0.0, 1), (1.0 - margin, 0.0, 1), (1.0 - margin, 0.0, margin), (0.0, 0.0, margin), (0.0, 1.0 - margin, margin), (0.0, 1.0 - margin, 1.0 - margin), (0.0, 1.0 - margin - 0.1, 1.0 - margin), ]) item = base.extrude_along(line_in) item = item.material(ddd.mats.green) item = ddd.uv.map_cubic(item) logo.append(item) #logo = logo.scale([2, 2, 2]) logo.show() root.append(logo) root.append(ddd.helper.all(center=[10, 10, 1]))
def patio_umbrella(side=2.5, height=2.5): base_height = 0.04 base_side = 0.4 base_weight = ddd.rect([base_side, base_side], name="Base weight").recenter() base_weight = base_weight.extrude(base_height).material(ddd.mats.metal_paint_white) base_weight = ddd.uv.map_cubic(base_weight) pole_r = 0.04 pole = ddd.point(name="Pole").buffer(pole_r).extrude(height - base_height).translate([0, 0, base_height]) pole = pole.material(ddd.mats.metal_paint_white) pole = ddd.uv.map_cylindrical(pole) umbrella_height = height - 1.8 umbrella = ddd.rect([side, side], name="Umbrella").recenter().material(ddd.mats.rope) umbrella = umbrella.extrude_step(ddd.point(), umbrella_height, base=False, cap=False) umbrella = umbrella.twosided().translate([0, 0, height - umbrella_height - 0.02]) umbrella = ddd.uv.map_cubic(umbrella) #EXTRUSION_METHOD_WRAP item = ddd.group([base_weight, pole, umbrella]) return item
def image_textured(self, feature): key = feature['properties']['key'] filename = "_cache/images/mapillary/%s-%s.jpg" % (key, 1024) material = ddd.material(texture_path=filename) plane = ddd.rect( name="Mapillary Image").triangulate().material(material) plane = ddd.uv.map_cubic(plane) plane = plane.recenter() plane = plane.rotate(ddd.ROT_FLOOR_TO_FRONT) return plane
def image_textured(filename): material = ddd.material( texture_path=filename) # name="Image: %s" % filename plane = ddd.rect(name="Image Rect").triangulate().material(material) plane = ddd.uv.map_cubic(plane) plane = plane.rotate(ddd.ROT_FLOOR_TO_FRONT) plane = plane.scale([5, 1, 5]) plane = plane.translate([0, 1, 0]) return plane
def drinking_water(height=1.4, r=0.2): base = ddd.rect([r * 2, r * 2], name="Drinking water").recenter() item = base.scale(0.8) item = item.extrude_step(base, height) item = item.extrude_step(base.scale(0.8), 0) item = item.extrude_step(base.scale(0.8), -0.04) item = item.material(ddd.mats.stone) item = ddd.uv.map_cubic(item) tap = interior.tap() tap = tap.translate([0, r * 0.9, height]) item.append(tap) return item
def trafficlights_head(height=0.8, depth=0.3): head = ddd.rect([-0.15, 0, 0.15, height], name="TrafficLight Box").material(ddd.mats.metal_paint_green).extrude(depth) disc_green = ddd.disc(ddd.point([0, 0.2]), r=0.09, name="TrafficLight Disc Green").material(ddd.mats.light_green).extrude(0.05) disc_orange = ddd.disc(ddd.point([0, 0.4]), r=0.09, name="TrafficLight Disc Green").material(ddd.mats.light_orange).extrude(0.05) disc_red = ddd.disc(ddd.point([0, 0.6]), r=0.09, name="TrafficLight Disc Green").material(ddd.mats.light_red).extrude(0.05) discs = ddd.group([disc_green, disc_orange, disc_red], name="TrafficLight Discs").translate([0, 0, depth]) # Put discs over head head = ddd.group([head, discs], name="TrafficLight Head").translate([0, -height / 2.0, 0]) # Center vertically head = head.rotate([math.pi / 2.0, 0, 0]) head = ddd.uv.map_cubic(head) return head
def process_xyztile(self): x, y, z = self.xyztile tile = Tile.from_google(x, y, zoom=z) point_min, point_max = tile.bounds min_lat, min_lon = point_min.latitude_longitude max_lat, max_lon = point_max.latitude_longitude center_lat = (min_lat + max_lat) / 2.0 center_lon = (min_lon + max_lon) / 2.0 self.center = (center_lon, center_lat) self.area = ddd.rect([min_lon, min_lat, max_lon, max_lat]).geom
def window_interior(width=1.6, height=1.2, depth=0.02): """ A window, centered on X and aligned to floor plane, lying on the XZ plane. """ obj = ddd.rect([-width * 0.5, 0, width * 0.5, height], name="Window") #obj = obj.extrude(depth) obj = obj.triangulate().translate([0, 0, depth]) #obj = obj.twosided() # shall be optional, as back is not seen in many cases obj = obj.material(ddd.mats.glass) obj = ddd.uv.map_cubic(obj) obj = obj.rotate(ddd.ROT_FLOOR_TO_FRONT) return obj
def create_sprite_rect(self, material): """ Createds a sprite rect using a single image (from a material). """ from ddd.ddd import ddd plane = ddd.rect( name="Sprite Rect") #.triangulate().material(material) plane = plane.material(material) plane = ddd.uv.map_2d_linear(plane) plane = plane.recenter() texture_size = material.get_texture().size sprite = TextureAtlasSprite("sprite", [0, 0, texture_size[0], texture_size[1]], [0.0, 0.0, 1.0, 1.0], False) if sprite.rot: plane.extra['uv'] = [ (sprite.bounds_norm[0] + (sprite.bounds_norm[3] - sprite.bounds_norm[1]) * v[1], 1.0 - (sprite.bounds_norm[1] + (sprite.bounds_norm[2] - sprite.bounds_norm[0]) * v[0])) for v in plane.extra['uv'] ] else: plane.extra['uv'] = [ (sprite.bounds_norm[0] + (sprite.bounds_norm[2] - sprite.bounds_norm[0]) * v[0], 1.0 - (sprite.bounds_norm[1] + (sprite.bounds_norm[3] - sprite.bounds_norm[1]) * (1 - v[1]))) for v in plane.extra['uv'] ] plane = plane.scale(texture_size) #plane = plane.translate([-0.5, -0.5, 0]).scale([plane, plane, 1]).translate([0, plane / 2, 0]) #decal = decal.rotate(ddd.ROT_FLOOR_TO_FRONT).translate([0, -thick / 2 - 0.005, 0]) #decal.extra['ddd:shadows'] = False #decal.extra['ddd:collider'] = False plane.extra['uv'] = [ (texture_size[1] - v[1] * texture_size[1], v[0] * texture_size[0]) for v in plane.extra['uv'] ] # temp: transposed and scaled plane.extra['ddd:sprite'] = True plane.extra['ddd:sprite:bounds'] = sprite.bounds_pixel return plane
def flowers_blade(material): """ Creates a grass blade quad (meant to be used through instancing). """ blade = ddd.rect() blade = blade.material(material) blade = blade.triangulate() blade = ddd.uv.map_cubic(blade) blade = blade.translate([-0.5, 0, 0]) blade = blade.scale([0.85, 1.0, 1.0]) blade = blade.rotate(ddd.ROT_FLOOR_TO_FRONT) return blade
def sign_pharmacy_side(size=1.0, depth=0.3, arm_length=1.0): ''' A pharmacy sign, attached sideways to a post arm. The post attaches centered (on the vertical plane). ''' arm_thick = depth / 2 sign = sign_pharmacy(size, depth) arm = ddd.rect([-arm_thick / 2, -arm_thick / 2, arm_thick / 2, arm_thick / 2]).extrude(arm_length) arm = arm.rotate([math.pi / 2.0, 0, 0]) arm = arm.material(ddd.material(color='#888888')) arm = ddd.uv.map_cubic(arm) sign = sign.rotate([0, 0, -math.pi / 2.0]).translate([depth / 2, 0, 0]) sign = sign.translate([0, -(arm_length + size * 0.66), 0]) return ddd.group([sign, arm], name="Pharmacy Side Sign with Arm")
def window_border_flat(width=1.6, height=1.2, border_depth=0.05, border_thick=0.1): obj = ddd.rect([-width * 0.5, 0, width * 0.5, height], name="Window Border") interior = obj.buffer(-border_thick) obj = obj.subtract(interior) obj = obj.extrude(border_depth) obj = obj.material(ddd.mats.stone) obj = ddd.uv.map_cubic(obj) obj = obj.rotate(ddd.ROT_FLOOR_TO_FRONT) return obj
def image_textured(self, bbox): # TODO: Reuse most of this (material, plane, etc) bbox = ",".join(["%f" % c for c in bbox]) filename = "_cache/images/wms/%s-%s.jpg" % (self.name, bbox) material = ddd.material(texture_path=filename, color="#ffffff") plane = ddd.rect(name="WMS Image (%s)" % self.name).triangulate().material(material) plane = ddd.uv.map_cubic(plane) #plane = plane.recenter() #plane = plane.rotate(ddd.ROT_FLOOR_TO_FRONT) return plane
def osm_init_params_xyztile(root, pipeline, logger): if not pipeline.data.get('ddd:osm:area:xyztile'): return x, y, z = pipeline.data['ddd:osm:area:xyztile'] tile = Tile.from_google(x, y, zoom=z) point_min, point_max = tile.bounds min_lat, min_lon = point_min.latitude_longitude max_lat, max_lon = point_max.latitude_longitude center_lat = (min_lat + max_lat) / 2.0 center_lon = (min_lon + max_lon) / 2.0 pipeline.data['ddd:osm:area:center'] = (center_lon, center_lat) pipeline.data['ddd:osm:area:shape'] = ddd.rect( [min_lon, min_lat, max_lon, max_lat]).geom
def waste_container_dome(base_side=1.4, r=0.65, height=1.6): base_height = 0.05 base = ddd.rect([base_side, base_side]).recenter() base = base.extrude_step(base, base_height) round_dome_height = r round_vertical_height = height - round_dome_height - base_height circle = ddd.point([0, 0]).buffer(r, resolution=3, cap_style=ddd.CAP_ROUND) obj = base.extrude_step(circle, 0) obj = obj.extrude_step(circle, round_vertical_height) obj = extrusion.extrude_dome(obj, round_dome_height, steps=4, base_shape=circle) obj = obj.material(ddd.mats.plastic_green) obj = ddd.uv.map_cylindrical(obj) obj.name = "Waste Container Dome" return obj
def door(width=1.4, height=2.2, depth=0.06): """ A door, centered on X and aligned to floor plane, lying on the XZ plane. """ obj = ddd.rect([-width * 0.5, 0, width * 0.5, height], name="Door") obj = obj.extrude(depth) # .translate([0, 0, depth]) obj = obj.material(ddd.mats.wood) obj = ddd.uv.map_cubic(obj) obj = obj.rotate(ddd.ROT_FLOOR_TO_FRONT) handle = door_handle_bar() handle = handle.translate([-width * 0.4, -depth, 1.07]) obj.append(handle) #handle = door_handle() #obj.append(handle) return obj
def create_sprite_from_atlas(self, material, sprite_key): """ """ from ddd.ddd import ddd sprite = material.atlas.sprite(sprite_key) plane = ddd.rect(name="Texture Atlas Sprite Rect: %s" % sprite_key) #.triangulate().material(material) plane = plane.material(material) plane = ddd.uv.map_2d_linear(plane) plane = plane.recenter() if sprite.rot: plane.extra['uv'] = [ (sprite.bounds_norm[0] + (sprite.bounds_norm[3] - sprite.bounds_norm[1]) * v[1], 1.0 - (sprite.bounds_norm[1] + (sprite.bounds_norm[2] - sprite.bounds_norm[0]) * v[0])) for v in plane.extra['uv'] ] else: plane.extra['uv'] = [ (sprite.bounds_norm[0] + (sprite.bounds_norm[2] - sprite.bounds_norm[0]) * v[0], 1.0 - (sprite.bounds_norm[1] + (sprite.bounds_norm[3] - sprite.bounds_norm[1]) * (1 - v[1]))) for v in plane.extra['uv'] ] #plane = plane.translate([-0.5, -0.5, 0]).scale([plane, plane, 1]).translate([0, plane / 2, 0]) #decal = decal.rotate(ddd.ROT_FLOOR_TO_FRONT).translate([0, -thick / 2 - 0.005, 0]) #decal.extra['ddd:shadows'] = False #decal.extra['ddd:collider'] = False # TODO: TEMP: Rope Cow / Godot export # plane.extra['uv'] = [(1024 - v[1] * 1024.0, v[0] * 1024.0) for v in plane.extra['uv']] # temp: transposed and scaled #print(plane.extra['uv']) plane.extra['ddd:sprite'] = True plane.extra['ddd:sprite:bounds'] = sprite.bounds_pixel return plane
def childrens_playground_swing(width=0.45, height=1.6, depth=0.2, width_top=None): if width_top is None: width_top = width * 1.1 seat_thick = 0.05 seat = ddd.rect([width, depth], name="Playground Swing Seat").recenter().extrude(seat_thick, center=True) seat = ddd.uv.map_cubic(seat) seat = seat.material(ddd.mats.plastic_black) chain_thick = 0.02 #chain = ddd.point(name="Playground Swing Chain").buffer(chain_thick / 2).extrude(height) #chain.translate([0, ]) chain1 = cable([-width / 2, 0, 0], [-width_top / 2, 0, height], thick=chain_thick) chain1 = chain1.material(ddd.mats.chain) chain2 = cable([width / 2, 0, 0], [width_top / 2, 0, height], thick=chain_thick) chain2 = chain2.material(ddd.mats.chain) swing = ddd.group3([seat, chain1, chain2], name="Swing") swing = swing.translate([0, 0, -height]) return swing
def panel(height=1.0, width=2.0, depth=0.2, text=None, text_back=None, texture=None, center=False): ''' A panel, like what commerces have either sideways or sitting on the facade. Also road panels. TODO: Provide anchor points w/size to allow for "document" objects (to allow for styling, rotation...). ''' panel = ddd.rect([-width / 2.0, -height / 2.0, width / 2.0, height / 2.0]).extrude(depth, center=True) panel = panel.rotate(ddd.ROT_FLOOR_TO_FRONT) panel = panel.material(ddd.material(color='#f0f0ff')) panel = ddd.uv.map_cubic(panel) panel.name = "Panel" if text: #textobj = ddd.marker(name="Panel Text Marker").translate([0, -depth * 0.5 - 0.02, 0]) textobj = ddd.instance(None, name="Panel Text Marker").translate([0, -depth * 0.5 - 0.02, 0]) textobj.extra['ddd:text'] = text textobj.extra['ddd:text:width'] = width * 0.9 textobj.extra['ddd:text:height'] = height * 0.9 textobj.extra['ddd:collider'] = False textobj.extra['ddd:shadows'] = False textobj.extra['ddd:occluder'] = False #textobj.extra['ddd:layer'] = "Texts" if text_back: #textbackobj = ddd.marker(name="Panel Text Marker").rotate([0, 0, math.pi]).translate([0, +depth * 0.5 + 0.02, 0]) textbackobj = ddd.instance(None, name="Panel Text Marker").rotate([0, 0, math.pi]).translate([0, +depth * 0.5 + 0.02, 0]) textbackobj.extra['ddd:text'] = text textbackobj.extra['ddd:text:width'] = width * 0.9 textbackobj.extra['ddd:text:height'] = height * 0.9 textbackobj.extra['ddd:collider'] = False textbackobj.extra['ddd:shadows'] = False textbackobj.extra['ddd:occluder'] = False panel = ddd.group3([panel]) if text: panel.append(textobj) if text_back: panel.append(textbackobj) if not center: panel = panel.translate([0, - depth * 0.5, 0]) return panel