view LightTools/build.py @ 62:6d4437a24aeb

Added camera position to level definition
author koryspansel
date Mon, 03 Oct 2011 15:14:41 -0700
parents 2444937929ae
children
line wrap: on
line source

#
# build
#

import sys
import string
import struct
import os
import functools
import re

_pattern = re.compile('\(\s*(\d+)\s*,\s*(\d+)\s*\)')

class MapDefinition:
    Parse = functools.partial(string.split, sep=',')

    def __init__(self, size, position, direction, distance, yaw, pitch, grid):
        self.Size = self._ParseVector(size)
        self.Position = self._ParseVector(position)
        self.Direction = self._ParseVector(direction)
        self.Distance = self._ParseVectorF(distance)
        self.Yaw = self._ParseVectorF(yaw)
        self.Pitch = self._ParseVectorF(pitch)
        self.Grid = self._ParseList(grid)

    def Write(self, filename):
        with open(filename, 'wb') as handle:
            handle.write(struct.pack('i' * len(self.Size),      *self.Size))            # 8
            handle.write(struct.pack('i' * len(self.Position),  *self.Position))        # 8
            handle.write(struct.pack('i' * len(self.Direction), *self.Direction))       # 4
            handle.write(struct.pack('f' * len(self.Distance),  *self.Distance))        # 4
            handle.write(struct.pack('f' * len(self.Yaw),       *self.Yaw))             # 4
            handle.write(struct.pack('f' * len(self.Pitch),     *self.Pitch))           # 4

            for tower in self.Grid:
                handle.write(struct.pack('i' * len(tower), *tower))                     # 8 * Size.X * Size.Y

    def _ParseVector(self, line):
        return map(int, self.Parse(line))

    def _ParseVectorF(self, line):
        return map(float, self.Parse(line))

    def _ParseList(self, lines):
        return [map(int, item.groups()) for item in _pattern.finditer(''.join(lines))]

def ReadDefinition(filename):
    def FilterLines(lines):
        for line in map(string.strip, lines):
            if line and not line.startswith('#'):
                yield line.split('#')[0]

    with open(filename, 'rt') as handle:
        lines = handle.readlines()

    definition = tuple(FilterLines(lines))

    size = definition[0]
    position = definition[1]
    direction = definition[2]
    distance = definition[3]
    yaw = definition[4]
    pitch = definition[5]
    grid = definition[6:]

    return MapDefinition(size, position, direction, distance, yaw, pitch, grid)

def Compile(input_map, output_map):
    if os.path.isfile(input_map):
        definition = ReadDefinition(input_map)
        if not definition:
            print 'Failed to read definition "%s"' % input_map

        else:
            folder = os.path.dirname(output_map)

            if not os.path.isdir(folder):
                os.makedirs(folder)

            print 'Building %s from %s' % (os.path.basename(output_map), os.path.basename(input_map))
            definition.Write(output_map)

if __name__ == '__main__':
    path_root   = os.path.dirname(sys.argv[0])
    path_assets = os.path.abspath(os.path.join(path_root, '..', 'Assets', 'Maps'))
    path_build  = os.path.abspath(os.path.join(path_root, '..', 'Data', 'Maps'))

    if len(sys.argv) > 1:
        Compile(os.path.join(path_assets, sys.argv[1]), os.path.join(path_build, os.path.splitext(sys.argv[1])[0] + '.map'))

    else:

        if os.path.isdir(path_assets):
            for filename in os.listdir(path_assets):
                if not filename.endswith('.def'):
                    continue

                Compile(os.path.join(path_assets, filename), os.path.join(path_build, os.path.splitext(filename)[0] + '.map'))