def _macro_stairs_core(self, full_length, full_height, full_depth, flip,
                        step_length, step_height, t):
     '''Create stairs by iteration.'''
     parts = []
     # Find closest match for step length and height...
     step_height = self._macro_stairs_match(full_height, step_height)
     num_steps = full_height / step_height
     step_length = full_length / num_steps
     # Create parts...
     length_iter = int(full_length / step_length)
     if flip:
         for i in range(length_iter):
             parts.append(
                 utils.Region3D(
                     utils.Point2D(step_length * i, 0),
                     utils.Point2D(step_length,
                                   step_height * (length_iter - i))))
     else:
         for i in range(length_iter):
             parts.append(
                 utils.Region3D(
                     utils.Point2D(step_length * i, 0),
                     utils.Point2D(step_length, step_height * (i + 1))))
     return parts
    def macro_stairs(self, bi, si):
        '''Make some stairs

		we see this as a 2D problem then add the missing dimension later
		(width/depth) dir tells us in which dir the steps go up length is the
		distance from start of lowest to end of heighest step height is the
		height of the highest step'''
        # FIXME cope with being able to make a hole through (under) the stairs
        origin = utils.getPoint(bi['origin'])
        size = utils.getPoint(bi['extent'])
        dir = si['dir']
        texture = ''
        if 'texture' in bi:
            texture = bi['texture']
        slength = 0
        sheight = float(si['stepheight'])
        parts = []
        parts3d = []

        # FIXME repeated code: n/e == s/w -- collapse into 2?

        # Work out which dimension is which
        if dir == dcp.NORTH:
            # use X and Y; Z rising with increasing Y
            length = size.y
            height = size.z
            width = size.x
            flip = False
            parts = self._macro_stairs_core(length, height, width, flip,
                                            slength, sheight, texture)
            for part in parts:
                part3d = utils.Region3D(
                    Point(0, part.origin.x, part.origin.y) + origin,
                    Point(width, part.extent.x, part.extent.y))
                parts3d.append(part3d)
        elif dir == dcp.SOUTH:
            # use X and Y; Z falling with increasing Y
            length = size.y
            height = size.z
            width = size.x
            flip = True
            parts = self._macro_stairs_core(length, height, width, flip,
                                            slength, sheight, texture)
            for part in parts:
                part3d = utils.Region3D(
                    Point(0, part.origin.x, part.origin.y) + origin,
                    Point(width, part.extent.x, part.extent.y))
                parts3d.append(part3d)
        elif dir == dcp.EAST:
            # use X and Y; Z rising with increasing X
            length = size.x
            height = size.z
            width = size.y
            flip = False
            parts = self._macro_stairs_core(length, height, width, flip,
                                            slength, sheight, texture)
            for part in parts:
                part3d = utils.Region3D(
                    Point(part.origin.x, 0, part.origin.y) + origin,
                    Point(part.extent.x, width, part.extent.y))
                parts3d.append(part3d)
        elif dir == dcp.WEST:
            # use X and y; Z falling with increasing X
            length = size.x
            height = size.z
            width = size.y
            flip = True
            parts = self._macro_stairs_core(length, height, width, flip,
                                            slength, sheight, texture)
            for part in parts:
                part3d = utils.Region3D(
                    Point(part.origin.x, 0, part.origin.y) + origin,
                    Point(part.extent.x, width, part.extent.y))
                parts3d.append(part3d)
        else:
            utils.error(
                'invalid direction specified for stairs (up and down are currently '
                'unsupported)')

        for part3d in parts3d:
            super().startElement(
                'solid', {
                    'origin': str(part3d.origin),
                    'extent': str(part3d.extent),
                    'texture': texture,
                    'type': 'step'
                })
            super().endElement('solid')
Esempio n. 3
0
def processSolid(doc, parent, worldtype, worldspawn, sf, offset, solid):
    style = parent.getAttribute('style')
    o = utils.getPoint(solid.getAttribute('origin')) + offset
    e = utils.getPoint(solid.getAttribute('extent'))
    type = solid.getAttribute('type')
    if not type:
        utils.error('solid with no type')
    f = solid.getAttribute('holeface')
    # Get holes info...
    # FIXME this is repeated code from the hollow one -- any way we can
    # refactor it?
    props = {}
    holes = []
    # Check if the solid has children (holes).
    # If so, split it up.
    # If not, just add it.
    if solid.hasChildNodes():
        for hole in solid.childNodes:
            ho_x, ho_y = hole.getAttribute('origin').split()
            he_x, he_y = hole.getAttribute('extent').split()
            type = hole.getAttribute('type')
            if not type:
                pass
            elif type == connector.DOOR:
                props['key'] = hole.getAttribute('key')
            else:
                utils.warning(
                    'only doors allowed as hole types; not plats or others.')
            # FIXME deal with other types
            holes.append(
                utils.Hole2D(utils.Point2D(float(ho_x), float(ho_y)),
                             utils.Point2D(float(he_x), float(he_y)), type,
                             props))
        # Built split (2D) parts into 3D brushes; mapping of coords to 3D
        # depends on which direction/face the hole was constructed in.
        if f == dcp.NORTH:
            parts = split.splitWall(
                utils.Region2D(utils.Point2D(o.x, o.z),
                               utils.Point2D(e.x, e.z)), holes)
            for part in parts:
                part3d = utils.addDim(part, dims.Y, o.y, e.y)
                utils.makeBrush(doc, worldtype, worldspawn, sf, style, part3d,
                                f)
        elif f == dcp.UP:
            parts = split.splitWall(
                utils.Region2D(utils.Point2D(o.x, o.y),
                               utils.Point2D(e.x, e.y)), holes)
            for part in parts:
                part3d = utils.addDim(part, dims.Z, o.z + prog.lip_small,
                                      e.z - prog.lip_small * 2)
                utils.makeBrush(doc, worldtype, worldspawn, sf, style, part3d,
                                f)
            else:
                utils.error('Unsupported holeface ' + f +
                            ' requested for hole in solid.')
    else:
        # Doesn't have child nodes...
        if not type or type == connector.STEP:
            pass  # no properties to set
        elif type == connector.DOOR:
            props['key'] = solid.getAttribute('key')
        elif type == connector.PLAT:
            props['position'] = solid.getAttribute('position')
        else:
            utils.warning('unknown type ' + type + ' specifed.')

        brush = utils.Region3D(Point(o.x, o.y, o.z), Point(e.x, e.y, e.z),
                               type, props)
        utils.makeBrush(doc, worldtype, worldspawn, sf, style, brush, type)
    # We can't remove the child or we screw over tree traversal (urgh)...
    utils.insertPlaceholder(doc, parent, solid)