예제 #1
0
def _saveSceneShots(sceneName, shots):
    sceneFile = os.path.join(ScenesPath(), sceneName + SCENE_EXT)
    xScene = ParseXMLWithIncludes(sceneFile)

    # save user camera position per scene
    userFile = ProjectFile() + '.user'
    if fileutil.exists(userFile):
        xUser = ParseXMLWithIncludes(userFile)
    else:
        xUser = cElementTree.Element('user')
    if sceneFile in Scene.cache:
        cameraData = Scene.cache[sceneFile].cameraData()
        if cameraData:
            for xSub in xUser:
                if xSub.tag == 'scene' and xSub.attrib['name'] == sceneName:
                    xSub.attrib['camera'] = ','.join([str(x) for x in cameraData])
                    break
            else:
                cElementTree.SubElement(xUser, 'scene', {'name': sceneName, 'camera': ','.join([str(x) for x in cameraData])})
    with fileutil.edit(userFile) as fh:
        fh.write(toPrettyXml(xUser))

    # remove old shots
    r = []
    for xShot in xScene:
        r.append(xShot)
    for s in r:
        xScene.remove(s)

    targets = []
    for shot in shots:
        if shot.sceneName == sceneName:
            targets.append(shot)

    for shot in targets:
        xShot = cElementTree.SubElement(xScene, 'Shot', {'name': shot.name, 'scene': sceneName, 'start': str(shot.start), 'end': str(shot.end), 'enabled': str(shot.enabled), 'speed': str(shot.speed),
                                                         'preroll': str(shot.preroll)})
        for curveName in shot.curves:
            xChannel = cElementTree.SubElement(xShot, 'Channel', {'name': curveName, 'mode': 'hermite'})
            data = []
            for key in shot.curves[curveName]:
                data.append(str(key.inTangent.x))
                data.append(str(key.inTangent.y))
                data.append(str(key.point().x))
                data.append(str(key.point().y))
                data.append(str(key.outTangent.x))
                data.append(str(key.outTangent.y))
                data.append(str(int(key.tangentBroken)))
                data.append(str(key.tangentMode))
            xChannel.text = ','.join(data)
        for texName in shot.textures:
            cElementTree.SubElement(xShot, 'Texture', {'name': texName, 'path': shot.textures[texName]})

    with fileutil.edit(sceneFile) as fh:
        fh.write(toPrettyXml(xScene))
예제 #2
0
파일: scene.py 프로젝트: vslotman/sqrmelon
 def readCameraData(self):
     if self.__cameraData is None:
         userFile = ProjectFile() + '.user'
         xCamera = None
         if fileutil.exists(userFile):
             xRoot = ParseXMLWithIncludes(userFile)
             for xSub in xRoot:
                 if xSub.attrib['name'] == os.path.splitext(os.path.basename(self.__filePath))[0]:
                     xCamera = xSub
                     break
         if xCamera is None:  # legacy support
             xCamera = ParseXMLWithIncludes(self.__filePath)
         self.__cameraData = CameraTransform(*[float(x) for x in xCamera.attrib['camera'].split(',')])
     return self.__cameraData
예제 #3
0
def _deserializeSceneShots(sceneName):
    sceneFile = os.path.join(ScenesPath(), sceneName + SCENE_EXT)
    xScene = ParseXMLWithIncludes(sceneFile)

    for xShot in xScene:
        name = xShot.attrib['name']
        start = float(xShot.attrib['start'])
        end = float(xShot.attrib['end'])
        speed = float(xShot.attrib.get('speed', 1.0))  # using get for legacy file support
        preroll = float(xShot.attrib.get('preroll', 0.0))

        curves = OrderedDict()
        textures = OrderedDict()
        for xEntry in xShot:
            if xEntry.tag.lower() == 'channel':
                curveName = xEntry.attrib['name']
                keys = []
                if xEntry.text:
                    keys = xEntry.text.split(',')
                curve = Curve()
                for i in range(0, len(keys), 8):
                    curve.addKeyWithTangents(tangentBroken=int(keys[i + 6]), tangentMode=int(keys[i + 7]), *[float(x) for x in keys[i:i + 6]])
                curves[curveName] = curve

            if xEntry.tag.lower() == 'texture':
                textures[xEntry.attrib['name']] = xEntry.attrib['path']

        shot = Shot(name, sceneName, start, end, curves, textures, speed, preroll)
        if 'enabled' in xShot.attrib:
            shot.enabled = xShot.attrib['enabled'] == str(True)
        yield shot
예제 #4
0
def readChannelTemplates():
    templatesDir = TemplatesPath()
    channelTemplates = os.path.join(templatesDir, 'uniforms.xml')
    result = OrderedDict()

    # legacy fallback
    if not os.path.exists(channelTemplates):
        curves = OrderedDict()
        curves['uOrigin.x'] = Curve()
        curves['uOrigin.y'] = Curve()
        curves['uOrigin.z'] = Curve()
        curves['uAngles.x'] = Curve()
        curves['uAngles.y'] = Curve()
        curves['uAngles.z'] = Curve()
        result['default'] = curves
        return result

    xRoot = ParseXMLWithIncludes(channelTemplates)
    for xTemplate in xRoot:
        name = xTemplate.attrib['name']
        curves = OrderedDict()
        result[name] = curves
        for xChannel in xTemplate:
            curve = Curve()
            curves[xChannel.attrib['name']] = curve
            Key(0.0, float(xChannel.attrib['value']), curve).reInsert()

    return result
예제 #5
0
def Template(templatePath):
    global _templates
    key = os.path.abspath(templatePath).lower()
    try:
        return _templates[key]
    except:
        xTemplate = ParseXMLWithIncludes(templatePath)
        if _templates:
            raise RuntimeError(
                'Found multiple templates in project, this is currently not supported by the player code.'
            )
        _templates[key] = xTemplate
        return xTemplate
예제 #6
0
파일: scene.py 프로젝트: vslotman/sqrmelon
def _deserializePasses(sceneFile):
    """
    :type sceneFile: str
    :rtype: list[PassData]
    """
    sceneDir = os.path.splitext(sceneFile)[0]
    templatePath = TemplateForScene(sceneFile)
    templateDir = os.path.splitext(templatePath)[0]
    xTemplate = ParseXMLWithIncludes(templatePath)
    passes = []
    frameBufferMap = {}
    for xPass in xTemplate:
        buffer = -1
        if 'buffer' in xPass.attrib:
            buffer = xPass.attrib['buffer']
            if buffer not in frameBufferMap:
                frameBufferMap[buffer] = len(frameBufferMap)

        size = None
        if 'size' in xPass.attrib:
            size = int(xPass.attrib['size']), int(xPass.attrib['size'])
        elif 'width' in xPass.attrib and 'height' in xPass.attrib:
            size = int(xPass.attrib['width']), int(xPass.attrib['height'])

        tile = size is not None
        if 'tile' in xPass.attrib:
            tile = xPass.attrib['tile'].lower() == 'true'

        factor = None
        if 'factor' in xPass.attrib:
            factor = int(xPass.attrib['factor'])

        realtime = int(xPass.attrib.get('static', 0)) == 0

        is3d = int(xPass.attrib.get('is3d', 0)) != 0
        if is3d:
            assert (size[0] ** 0.5) == size[1]
            size = size[0], size[1]

        outputs = int(xPass.attrib.get('outputs', 1))

        inputs = []
        i = 0
        key = 'input%s' % i
        while key in xPass.attrib:

            # input is filename?
            parentPath = os.path.dirname(ProjectFile())
            fullName = os.path.join(parentPath, xPass.attrib[key])
            if fileutil.exists(fullName):
                inputs.append(xPass.attrib[key])
            else:
                if '.' in xPass.attrib[key]:
                    frameBuffer, subTexture = xPass.attrib[key].split('.')
                    frameBuffer, subTexture = frameBuffer, int(subTexture)
                else:
                    frameBuffer, subTexture = xPass.attrib[key], 0

                if frameBuffer not in frameBufferMap:
                    frameBufferMap[frameBuffer] = len(frameBufferMap)
                inputs.append((frameBufferMap[frameBuffer], subTexture))

            i += 1
            key = 'input%s' % i
        vertStitches = []
        fragStitches = []
        uniforms = {}
        for xElement in xPass:
            stitches = vertStitches if xElement.attrib['path'].lower().endswith('.vert') else fragStitches
            if xElement.tag.lower() == 'section':
                stitches.append(os.path.join(sceneDir, xElement.attrib['path']))
            elif xElement.tag.lower() == 'shared':
                stitches.append(os.path.join(templateDir, xElement.attrib['path']))
            elif xElement.tag.lower() == 'global':
                stitches.append(os.path.join(templateDir, xElement.attrib['path']))
            else:
                raise ValueError('Unknown XML tag in pass: "******"' % xElement.tag)
            for xUniform in xElement:
                uniforms[xUniform.attrib['name']] = [float(x.strip()) for x in xUniform.attrib['value'].split(',')]

        passes.append(PassData(vertStitches, fragStitches, uniforms, inputs, frameBufferMap.get(buffer, -1), realtime, size, tile, factor, outputs, xPass.attrib.get('drawcommand', None), is3d, xPass.attrib.get('name', None)))
    return passes
예제 #7
0
def run():
    shots = []
    scenes = []
    scenesDir = ScenesPath()

    for scene in os.listdir(scenesDir):
        if not scene.endswith(SCENE_EXT):
            continue
        scenePath = os.path.join(scenesDir, scene)
        sceneDir = os.path.splitext(scenePath)[0]
        xScene = ParseXMLWithIncludes(scenePath)

        templatePath = os.path.join(scenesDir, xScene.attrib['template'])
        templateDir = os.path.splitext(templatePath)[0]
        xTemplate = Template(templatePath)

        scene = []

        for xPass in xTemplate:
            stitchIds = []
            uniforms = {}
            for xSection in xPass:
                baseDir = sceneDir
                if xSection.tag in ('global', 'shared'):
                    baseDir = templateDir
                shaderFile = os.path.join(baseDir, xSection.attrib['path'])
                stitchIds.append(text.addFile(shaderFile))
                for xUniform in xSection:
                    name = xUniform.attrib['name']
                    values = [
                        float(x.strip())
                        for x in xUniform.attrib['value'].split(',')
                    ]
                    uniforms[text.addString(name)] = len(
                        values), floats.addFloats(values, name)

            programId = shaders.fromStitches(stitchIds)

            buffer = int(xPass.attrib.get('buffer', -1))
            outputs = int(xPass.attrib.get('outputs', 1))
            size = int(xPass.attrib.get('size', 0))
            width = int(xPass.attrib.get('width', size))
            height = int(xPass.attrib.get('height', size))
            factor = int(xPass.attrib.get('factor', 1))
            static = int(xPass.attrib.get('static', 0))
            is3d = int(xPass.attrib.get('is3d', 0))
            if buffer != -1:
                buffer = framebuffers.add(buffer, outputs, width, height,
                                          factor, static, is3d)

            i = 0
            key = 'input%s' % i
            inputs = []
            while key in xPass.attrib:
                v = xPass.attrib[key]
                if '.' in v:
                    a, b = v.split('.')
                else:
                    a, b = v, 0
                inputs.append((int(a), int(b)))
                i += 1
                key = 'input%s' % i

            scene.append(passes.add(programId, buffer, inputs, uniforms))

        sceneIndex = len(scenes)
        scenes.append(len(scene))
        scenes += scene

        for xShot in xScene:
            if xShot.attrib.get('enabled', 'True') == 'False':
                continue
            animations = {}
            for xChannel in xShot:
                uname = xChannel.attrib['name']
                n = uname
                x = 0
                if '.' in uname:
                    n, x = uname.rsplit('.', 1)
                    x = 'xyzw'.index(x)
                n = text.addString(n)
                if n not in animations:
                    animations[n] = []
                if not xChannel.text:
                    keyframes = []
                else:
                    keyframes = []
                    for i, v in enumerate(
                            float(v.strip())
                            for v in xChannel.text.split(',')):
                        j = i % 8
                        if j == 0 or j == 4 or j > 5:
                            continue
                        if j == 5:  # out tangent y
                            if v == float(
                                    'inf'
                            ):  # stepped tangents are implemented as out tangentY = positive infinity
                                v = 'FLT_MAX'
                        keyframes.append(v)
                    assert len(keyframes) / 4.0 == int(len(keyframes) /
                                                       4), len(keyframes)
                while len(animations[n]) <= x:
                    animations[n].append(None)
                assert animations[n][x] is None
                animations[n][x] = floats.addFloats(keyframes), len(keyframes)

            for channelStack in animations.values():
                # TODO we can not / do not check if the channelStack length matches the uniform dimensions inside the shader (e.g. are we sure we're not gonna call glUniform2f for a vec3?)
                assert None not in channelStack, 'Animation provided for multiple channels but there is one missing (Y if a vec3 or also Z if a vec4).'

            shots.append((float(xShot.attrib['start']),
                          float(xShot.attrib['end']), sceneIndex, animations))

    # sort shots by start time
    def _serializeShots(shots):
        shots.sort(key=lambda x: x[0])
        shotTimesStart = floats.addFloats(
            [x for shot in shots for x in (shot[0], shot[1])])
        yield '\n\n__forceinline int shotAtBeats(float beats, float& localBeats)\n{\n'
        if len(shots) == 1:
            yield '\tlocalBeats = beats - gFloatData[%s];\n' % shotTimesStart
            yield '\treturn 0;\n'
        else:
            yield '\tint shotTimeCursor = 0;\n'
            yield '\tdo\n\t{\n'
            yield '\t\tif(beats < gFloatData[shotTimeCursor * 2 + %s])\n\t\t{\n' % (
                shotTimesStart + 1)
            yield '\t\t\tlocalBeats = beats - gFloatData[shotTimeCursor * 2 + %s];\n' % shotTimesStart
            yield '\t\t\treturn shotTimeCursor;\n'
            yield '\t\t}\n'
            yield '\t}\n\twhile(++shotTimeCursor < %s);\n' % len(shots)
            yield '\treturn -1;\n'
        yield '}\n'

        global gShotScene
        gShotScene = ints.addInts([shot[2] for shot in shots])
        flatAnimationData = []
        animationDataPtrs = []
        for shot in shots:
            animationDataPtrs += [len(flatAnimationData), len(shot[3].keys())]
            global gAnimEntriesMax
            gAnimEntriesMax = max(gAnimEntriesMax, len(shot[3].keys()))
            for uniformStringId in shot[3]:
                animationData = shot[3][uniformStringId]
                flatAnimationData += [uniformStringId, len(animationData)]
                for pair in animationData:
                    flatAnimationData += pair
                flatAnimationData += [0] * (2 * (4 - len(animationData)))

        global gShotAnimationDataIds
        gShotAnimationDataIds = ints.addInts(animationDataPtrs)
        global gShotUniformData
        gShotUniformData = ints.addInts(flatAnimationData)

    def _serializeAll(scenes, shots):
        buffer = list(_serializeShots(shots))
        for serializable in (text, floats):
            for ln in serializable.serialize():
                yield ln
        buffer2 = []
        for serializable in (shaders, framebuffers, passes):
            buffer2 += list(serializable.serialize())
        global gScenePassIds
        gScenePassIds = ints.addInts(scenes)
        for ln in ints.serialize():
            yield ln
        for ln in buffer2:
            yield ln
        for ln in buffer:
            yield ln

    data = [''.join(_serializeAll(scenes, shots))]
    data.append(
        """\n\n__forceinline float evalCurve(const float* data, int numFloats, float beats)
{
\tif(numFloats == 4 || beats <= data[1]) // 1 key or evaluating before first frame
\t\treturn data[2];

\t// Find index of first key that has a bigger time than our current time
\t// if none, this will be the index of the last key.
\tint keyValueCount = numFloats;
\tint rightKeyIndex = 4;
\twhile (rightKeyIndex < keyValueCount - 4 && data[rightKeyIndex + 1] < beats)
\t\trightKeyIndex += 4;

\t// Clamp our sampling time to our range
\tfloat sampleTime = (beats > data[rightKeyIndex + 1]) ? data[rightKeyIndex + 1] : beats;

\t// Retrieve our spline points
\tfloat y0 = data[rightKeyIndex - 2];
\tfloat y1 = data[rightKeyIndex - 1]; 
\t// handle stepped tangents
\tif(y1 == FLT_MAX) return y0;
\tfloat y2 = data[rightKeyIndex];
\tfloat y3 = data[rightKeyIndex + 2];

\tfloat dy = y3 - y0;
\tfloat c0 = y1 + y2 - dy - dy;
\tfloat c1 = dy + dy + dy - y1 - y1 - y2;
\tfloat c2 = y1;
\tfloat c3 = y0;

\t// Determine factor
\tfloat dt = data[rightKeyIndex + 1] - data[rightKeyIndex - 3];
\tfloat t = (sampleTime - data[rightKeyIndex - 3]) / dt;

\treturn t * (t * (t * c0 + c1) + c2) + c3;
}

#define gAnimEntriesMax %s
#define gShotAnimationDataIds %s
#define gShotScene %s
#define gScenePassIds %s
#define gPassProgramsAndTargets %s
#define gShotUniformData %s
#define gFrameBufferData %s
#define gFrameBufferBlockSize %s
#define gProgramCount %s
""" % (gAnimEntriesMax, gShotAnimationDataIds, gShotScene, gScenePassIds,
       gPassProgramsAndTargets, gShotUniformData, gFrameBufferData,
       FrameBufferPool.BLOCK_SIZE, len(shaders.offsets)))

    dst = os.path.join(
        os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'Player',
        'generated.hpp')
    with fileutil.edit(dst, 'w') as fh:
        fh.write(''.join(data))