示例#1
0
def processMap(doc, wad):
    map = doc.documentElement
    worldtype, worldspawn = processInfo(doc, map, wad)
    # Go through each successive element and process it accordingly.
    # (Yes, this is very SAX-like but we don't use SAX because by using DOM we
    # get to manipulate the tree as we go, which we do need to do.)
    for node in map.childNodes[1:]:
        processNode(doc, map, worldtype, worldspawn, s, Point(0, 0, 0), node)
def PointFromString(str):
    point_match = r_planepoints.match(str)
    return Point(float(point_match.group(1)), float(point_match.group(2)),
                 float(point_match.group(3)))
示例#3
0
 def _get_bounds(self, hollow_attrs):
     '''Work out the internal cube of the hollow.'''
     extent = utils.getPoint(hollow_attrs['extent'])
     return extent - Point(prog.lip * 2, prog.lip * 2, prog.lip * 2)
示例#4
0
def listBrushes(map):
    brush_planes = []  # stores the (6) planes that make up one brush
    plane_points = []  # stores the (3) points in the current plane
    psa = []  # store one set of non-parallel planes
    psb = []  # store another set of non-parallel planes
    textureSpec = ''

    # Process all brushes...
    for brush in map.getElementsByTagName('brush'):
        utils.uprint('Brush...')
        # Get all planes...
        for plane in brush.getElementsByTagName('plane'):
            utils.uprint('    Plane...')
            # Get texture spec...
            textureSpec = getText(
                plane.getElementsByTagName('texture')[0].childNodes)
            utils.uprint('        Texture: ' + textureSpec)
            # Get all points...
            for point in plane.getElementsByTagName('point'):
                point_match = r_planepoints.match(getText(point.childNodes))
                plane_points.append(
                    Point(float(point_match.group(1)),
                          float(point_match.group(2)),
                          float(point_match.group(3))))
                # NB: We use floats above so that later calculations are still accurate.
                utils.uprint('        ' +
                             str(plane_points[len(plane_points) - 1]))
            # Put points into a plane object...
            brush_planes.append(
                Plane3D(plane_points[0], plane_points[1], plane_points[2]))
            plane_points = []
            # Grab texture and remove this plane...
            brush.removeChild(plane)

        # Got all planes; work out brush origin and size...
        for plane in brush_planes:
            utils.uprint('   ' + str(plane))

        # Get and solve parallel planes...
        while len(brush_planes) > 0:
            t = brush_planes.pop(0)
            s = t.N.x + t.N.y + t.N.z
            if s > 0:
                psa.append(t)
            else:
                psb.append(t)
        i1 = intersect(psa[0], psa[1], psa[2])
        i2 = intersect(psb[0], psb[1], psb[2])

        # Work out size (from smallest/lowest coord) and extent...
        i1s = i1.x + i1.y + i1.z
        i2s = i2.x + i2.y + i2.z
        if i1s < i2s:
            origin = i1
            extent = i2 - i1
        else:
            origin = i2
            extent = i2 - i1

        # Update brush info...
        brush.setAttribute('origin', str(origin))
        brush.setAttribute('extent', str(extent))
        brush.setAttribute('texture', textureSpec)
        # Tidy up...
        psa = []
        psb = []
    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')
示例#6
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)