Source

mjin / t / Qt / main

The branch '#1907 Display MJIN window in Qt' does not exist.
Full commit
#!/usr/bin/python2

import sys

if (len(sys.argv) != 2):
    print "Usage: {0} /path/to/t/mjin2".format(sys.argv[0])
    sys.exit(0)

import datetime
from pymjin2 import *
from PyQt4 import QtGui
import sip

class AddAction(Action):
    def __init__(self,
                 dactions   = None,
                 autoclone  = True,
                 parentName = None,
                 childName  = None,
                 reversed   = False):
        super(AddAction, self).__init__(dactions, autoclone)
        self.parentName = parentName
        self.childName  = childName
        self.reversed   = reversed
    def clone(self):
        return AddAction(self.dactions,
                         self.autoclone,
                         self.parentName,
                         self.childName,
                         self.reversed)
    def reverse(self):
        self.reversed = not self.reversed
    def start(self):
        parent = self.dactions.actionByName(self.parentName)
        child  = self.dactions.actionByName(self.childName)
        if (not parent and not child):
            raise Exception("You must assign parent and child actions to AddAction")
        if (not self.reversed):
            parent.addAction(child)
        else:
            parent.removeAction(child)
        print "add {0} {1} {2}".format(not self.reversed,
                                       self.childName,
                                       self.parentName)

def createOrUpdateAddAction(dactions, st, key, k):
    name = k[1]
    property = k[2]
    action = dactions.actionByName(name)
    # Create.
    if (not action):
        action = AddAction(dactions)
        dactions.addAction(name, action)
    # Update.
    sv = st.s[key]
    if (property == "template"):
        src = dactions.actionByName(sv)
        action.parentName = src.parentName
        action.childName  = src.childName
        action.reversed   = src.reversed
        action.autoclone  = src.autoclone
    elif (property == "parent"):
        action.parentName = sv
    elif (property == "child"):
        action.childName = sv
    elif (property == "reversed"):
        action.reversed = True if (sv == "1") else False
    elif (property == "autoclone"):
        action.autoclone = True if (sv == "1") else False

class SceneNodeMaterialAction(Action):
    def __init__(self, node = None, material = None, dactions = None, autoclone = True):
        super(SceneNodeMaterialAction, self).__init__(dactions, autoclone)
        self.node = node
        self.material = material
    def clone(self):
        return SceneNodeMaterialAction(self.node, self.material, self.dactions, self.autoclone)
    def reverse(self):
        pass
    def start(self):
        if (not self.node and not self.material):
            raise Exception("You must assign SceneNode and Material to Action")
        st = State()
        st.add("nodes." + self.node + ".material", self.material)
        self.dactions.dscene.setState(st)
        #print "{0} {1}".format(self.node, self.material)

def createOrUpdateSceneNodeMaterialAction(dactions, st, key, k):
    name = k[1]
    property = k[2]
    action = dactions.actionByName(name)
    # Create.
    if (not action):
        action = SceneNodeMaterialAction(None, None, dactions)
        dactions.addAction(name, action)
    # Update.
    if (property == "node"):
        action.node = st.s[key]
    elif (property == "material"):
        action.material = st.s[key]
    elif (property == "autoclone"):
        action.autoclone = True if (st.s[key] == "1") else False

class ValueSpinner(object):
    def __init__(self, delegate, resetValue):
        self.delegate = delegate
        self.resetValue = resetValue
        self.reset()
    def change(self):
        self.delta = 10
        self.spinsNb = 0
        self._alter()
    def reset(self):
        self.delta = 10
        self.value = self.resetValue
        self.increase = True
        self._alter()
    def spin(self):
        self.spinsNb += 1
        if (self.spinsNb == 5):
            self.spinsNb = 0
            if (self.delta == 10):
                self.delta = 500
            elif (self.delta == 500):
                self.delta = 1000
        self._alter()
    def _alter(self):
        if (self.increase):
            self.value += self.delta
        else:
            self.value -= self.delta
        if (self.value < self.resetValue):
            self.value = self.resetValue
        self.delegate.onValueSpinner(self.value)

class CameraTrackerInputHandler(TimerListener):
    def __init__(self, cameraTracker, timer, pini):
        self.cameraTracker = cameraTracker
        self.enabled = False
        self.replay = False
        self.valueSpinner = ValueSpinner(self, 0)
        self.spin = False
        self.timer = timer
        self.pini = pini
        TimerListener.__init__(self)
        # Select the last recorded camera track.
        names = []
        st = self.pini.load("ct.pini")
        for key in st.keys:
            k = key.split(".")
            name = k[1]
            if (name not in names):
                names.append(name)
        # Since the last name is always the last one we don't sort it.
        if (len(names)):
            lastName = names[len(names) - 1]
            print "Loading the last camera track:", lastName
            self.enabled = True
            self.valueSpinner.reset()
            self.cameraTracker.startRecording(lastName)
            keyPrefix = "cameratrack." + lastName
            cs = State()
            cs.addKeysStartingWith(st, keyPrefix)
            self.cameraTracker.setState(cs)

    def handle(self, e):
        if ((e.input == INPUT_KEY_C) and e.press):
            self.toggleEnabled()
            return True
        elif ((e.input == INPUT_KEY_P) and e.press):
            self.cameraTracker.setReplayEnabled(not self.cameraTracker.isReplayEnabled())
            return True
        elif (self.enabled and not self.cameraTracker.isReplayEnabled()):
            if ((e.input == INPUT_KEY_PLUS) or (e.input == INPUT_KEY_KP_ADD)):
                self.setSpinningEnabled(e.press, True)
                return True
            elif ((e.input == INPUT_KEY_MINUS) or (e.input == INPUT_KEY_KP_SUBTRACT)):
                self.setSpinningEnabled(e.press, False)
                return True
            elif ((e.input == INPUT_KEY_I) and e.press):
                self.cameraTracker.createOrUpdatePoint()
                return True
            elif ((e.input == INPUT_KEY_X) and e.press):
                self.cameraTracker.removePoint()
                return True
            elif ((e.input == INPUT_KEY_V) and e.press):
                self.cameraTracker.resetCamera()
                return True
            elif ((e.input == INPUT_KEY_INSERT) or (e.input == INPUT_KEY_KP_INSERT)):
                if (e.press):
                    self.cameraTracker.alterTimeInterval(100)
                return True
            elif ((e.input == INPUT_KEY_DELETE) or (e.input == INPUT_KEY_KP_DELETE)):
                if (e.press):
                    self.cameraTracker.alterTimeInterval(-100)
                return True
        return False
    def onTimerTick(self, ms):
        if (self.spin):
            self.valueSpinner.spin()
    def onValueSpinner(self, value):
        self.cameraTracker.setTimeValue(value)
    def setSpinningEnabled(self, state, increase):
        if (self.spin == state):
            return
        self.spin = state
        self.valueSpinner.increase = increase
        if (state):
            self.valueSpinner.change()
            self.timer.addListener(self, 200)
        else:
            self.timer.removeListener(self)
    def toggleEnabled(self):
        self.enabled = not self.enabled
        if (self.enabled):
            self.valueSpinner.reset()
            name = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
            self.cameraTracker.startRecording(name)
        else:
            st = self.cameraTracker.state()
            st2 = self.pini.load("ct.pini")
            st2.replace(st)
            self.pini.save(st2, "ct.pini")
            self.cameraTracker.stopRecording()

class Test(InputListener):
    def __init__(self, dataDir):
        self.dataDir = dataDir
        self.resolver = PathResolver()
        self.resolver.addSearchPath(dataDir)
        self.dscene = DScene()
        self.dsceneModelNode = DSceneModelNode()
        self.dscene.addExtension(self.dsceneModelNode)
        self.dsceneLight = DSceneLight()
        self.dscene.addExtension(self.dsceneLight)
        self.dsceneLightShadow = DSceneLightShadow()
        self.dscene.addExtension(self.dsceneLightShadow)
        self.pini = PINI(self.resolver)
        st = self.pini.load("scene.pini")
        self.dscene.setState(st)
        # Shadow compositor.
        self.shadowCompositor = Compositor()
        st = self.pini.load("shadowCompositor.pini")
        self.shadowCompositor.setState(st)
        self.shadowCompositor.setScene(self.dsceneLightShadow.shadowByName("shadow"))
        # Main compositor.
        self.mainCompositor = Compositor()
        self.mainCompositorUniform = CompositorUniform()
        self.mainCompositor.addExtension(self.mainCompositorUniform)
        self.setupCompositor(self.mainCompositor, "mainCompositor")
        self.mainCompositor.setScene(self.dscene.graph())
        self.mainCompositor.bindTexture(
            "pass2", 4, self.shadowCompositor.texture("pass1Shadows"))
        # Apply scene's light position to compositor.
        st = self.dscene.state(["lights.light.position"])
        cst = State()
        cst.add("uniforms.lightPos", st.s["lights.light.position"])
        self.mainCompositor.setState(cst)
        # Materials.
        self.dsceneNodeMaterial = DSceneNodeMaterial()
        self.dsceneNodeMaterial.regCompositor("main", self.mainCompositor)
        self.dscene.addExtension(self.dsceneNodeMaterial)
        st = self.pini.load("materials.pini")
        self.dscene.setState(st)
        # Graph.
        self.graph = Graph()
        self.graph.add(self.dsceneLightShadow.shadowByName("shadow"))
        self.graph.add(self.shadowCompositor.graph())
        self.graph.add(self.mainCompositor.graph())
        # Display textures.
        self.graph.add(
            createTextureDisplayQuad(Vec3(0, 0, 0),
                                     self.mainCompositor.texture("pass2Final"),
                                     1,
                                     1))
#        self.graph.add(
#            createTextureDisplayQuad(Vec3(0.7, 0.7, 0),
#                                     self.shadowCompositor.texture("pass1Shadows")))
        # Display everything.
        self.wnd = NewWindow()
        self.wndGeom = WindowGeometry()
        self.wnd.addExtension(self.wndGeom)
        InputListener.__init__(self)
        self.wndInput = WindowInput()
        self.wnd.addExtension(self.wndInput)
        print "01.input"
        self.wndInput.addListener(self)
        print "02.input"
        self.timer = Timer()
        self.wnd.setTimer(self.timer)
        st = State()
        st.add("frame", "100 100 640 480")
        self.wnd.setState(st)
        self.wnd.setScene(self.graph.graph())
        # Actions.
        self.dactions = DActions(self.dscene)
        self.dactions.reg("add",          createOrUpdateAddAction)
        self.dactions.reg("nodeMaterial", createOrUpdateSceneNodeMaterialAction)
        st = self.pini.load("actions.pini")
        self.dactions.setState(st)
        # Actions' runner.
        self.dactionsRunner = DActionsRunner(self.timer, self.dactions)
        #self.dactionsRunner.start("main")

        self.manipulator = CameraManipulator()
        self.manipulator.setPosition(Vec3(-3, -19.5, 8))
        self.manipulator.setRotation(degreeToQuaternion(Vec3(77, 0, -4)))
        self.wnd.setCameraManipulator(self.manipulator.manipulator())
        #self.timer.addListener(self.manipulator, 0, False)
        self.cameraTracker = CameraTracker(self.manipulator, self.timer)
        self.graph.add(self.cameraTracker.camera())
        self.cameraTrackerInputHandler = CameraTrackerInputHandler(self.cameraTracker, self.timer, self.pini)
        # Qt.
        self.wndQt = WindowQt()
        self.wnd.addExtension(self.wndQt)

    def __del__(self):
        print "__del__"
        del self.dactionsRunner
        #self.wndInput.removeListener(self)
        #self.wnd.setScene(None)
        del self.wnd
        del self.wndGeom
        del self.wndInput
        del self.timer
        del self.manipulator
        del self.dactions
        del self.graph
        del self.cameraTrackerInputHandler
        del self.cameraTracker
        del self.dscene
        del self.dsceneModelNode
        del self.dsceneNodeMaterial
        del self.dsceneLight
        del self.dsceneLightShadow
        del self.mainCompositor
        del self.mainCompositorUniform
        del self.shadowCompositor
        del self.resolver
        del self.wndQt

    def onWindowInput(self, e):
        print "onWindowInput"
#        if (e.input == INPUT_KEY_ESCAPE and e.press):
#            print "Quit"
#            self.wnd.stop()
#            return True
#        elif (e.input == INPUT_KEY_W):
#            self.manipulator.setMovingForwardEnabled(e.press)
#            return True
#        elif (e.input == INPUT_KEY_S):
#            self.manipulator.setMovingBackwardEnabled(e.press)
#            return True
#        elif (e.input == INPUT_KEY_A):
#            self.manipulator.setMovingLeftEnabled(e.press)
#            return True
#        elif (e.input == INPUT_KEY_D):
#            self.manipulator.setMovingRightEnabled(e.press)
#            return True
#        elif (e.input == INPUT_MOUSE_BUTTON_LEFT):
#            self.setManipulatorEnabled(e.press)
#        elif (self.cameraTrackerInputHandler.handle(e)):
#            return True
        return False
    def run(self):
        self.wnd.run()
    def setManipulatorEnabled(self, state):
        if (state):
            self.timer.setListenerEnabled(self.manipulator, True)
        else:
            self.timer.setListenerEnabled(self.manipulator, False)
    def setup(self, w):
        self.wndQt.setup(w)
    def setupCompositor(self, c, name):
        path = self.dataDir + "/" + name
        self.resolver.addSearchPath(path)
        c.setState(self.pini.load(name + ".pini"))
        self.resolver.removeSearchPath(path)

t = Test(sys.argv[1] + "/EffectsAndShadows")
if (False):
    t.run()
else:
    app = QtGui.QApplication(sys.argv)
    w = QtGui.QWidget()
    w.setWindowTitle("This is a title")
    addr = sip.unwrapinstance(w)
    t.setup(addressToQWidget(addr))
    w.setGeometry(100, 100, 800, 600)
    w.show()
    sys.exit(app.exec_())