Ejemplo n.º 1
0
class Container(Axon.AdaptiveCommsComponent.AdaptiveCommsComponent):
    """\
    Container(...) -> A new Container component.
    
    A container to control several OpenGLComponents.

    Keyword arguments:
    
    - position  -- Initial container position (default=(0,0,0)).
    - rotation  -- Initial container rotation (default=(0,0,0)).
    - scaling   -- Initial container scaling (default=(1,1,1)).
    - contents  -- Nested dictionary of contained components.
    """

    Inboxes = {
        "inbox": "",
        "control": "For shutdown messages",
        "position" : "receive position triple (x,y,z)",
        "rotation": "receive rotation triple (x,y,z)",
        "scaling": "receive scaling triple (x,y,z)",
        "rel_position" : "receive position triple (x,y,z)",
        "rel_rotation": "receive rotation triple (x,y,z)",
        "rel_scaling": "receive scaling triple (x,y,z)",
    }
    
    Outboxes = {
        "outbox": "",
        "signal": "For shutdown messages"
    }

    def __init__(self, **argd):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(Container, self).__init__()
        
        # get transformation data and convert to vectors
        self.position = Vector( *argd.get("position", (0,0,0)) )
        self.rotation = Vector( *argd.get("rotation", (0.0,0.0,0.0)) )
        self.scaling = Vector( *argd.get("scaling", (1,1,1) ) )
        
        # for detection of changes
        self.oldrot = Vector()
        self.oldpos = Vector()
        self.oldscaling = Vector()

        # inital apply trasformations
        self.transform = Transform()

        self.components = []

        self.rel_positions = {}
        self.rel_rotations = {}
        self.rel_scalings = {}

        self.poscomms = {}
        self.rotcomms = {}
        self.scacomms = {}
        
        
        contents = argd.get("contents", None)
        if contents is not None:
            for (comp, params) in contents.items():
                self.addElement(comp, **params)


    def main(self):
        while 1:

            while self.dataReady("control"):
                cmsg = self.recv("control")
                if isinstance(cmsg, producerFinished) or isinstance(cmsg, shutdownMicroprocess):
                    self.send(cmsg, "signal")
                    return

            self.handleMovement()
            self.applyTransforms()
            yield 1

           
    def handleMovement(self):
        """ Handle movement commands received by corresponding inboxes. """
        while self.dataReady("position"):
            pos = self.recv("position")
            self.position = Vector(*pos)
        
        while self.dataReady("rotation"):
            rot = self.recv("rotation")
            self.rotation = Vector(*rot)
            
        while self.dataReady("scaling"):
            scaling = self.recv("scaling")
            self.scaling = Vector(*scaling)
            
        while self.dataReady("rel_position"):
            self.position += Vector(*self.recv("rel_position"))
            
        while self.dataReady("rel_rotation"):
            self.rotation += Vector(*self.recv("rel_rotation"))
            
        while self.dataReady("rel_scaling"):
            self.scaling = Vector(*self.recv("rel_scaling"))


    def applyTransforms(self):
        """ Use the objects translation/rotation/scaling values to generate a new transformation Matrix if changes have happened. """
        # generate new transformation matrix if needed
        if self.oldscaling != self.scaling or self.oldrot != self.rotation or self.oldpos != self.position:
            self.transform = Transform()
            self.transform.applyScaling(self.scaling)
            self.transform.applyRotation(self.rotation)
            self.transform.applyTranslation(self.position)

            self.oldpos = self.position.copy()
            self.oldrot = self.rotation.copy()
            self.oldscaling = self.scaling.copy()
            
            self.rearangeContents()


    def rearangeContents(self):
        for comp in self.components:
            trans = self.transform.transformVector(self.rel_positions[comp])
            self.send(trans.toTuple(), self.poscomms[comp])
#                self.send(self.rotation.toTuple(), self.rotcomms[comp])
            self.send(self.scaling.toTuple(), self.scacomms[comp])

            
    def addElement(self, comp, position=(0,0,0), rotation=(0,0,0), scaling=(1,1,1) ):
        self.components.append(comp)
        self.rel_positions[comp] = Vector( *position )
        self.rel_rotations[comp] = Vector( *rotation )
        self.rel_scalings[comp] = Vector( *scaling )
        
        self.poscomms[comp] = self.addOutbox("pos")
        self.link( (self, self.poscomms[comp]), (comp, "position") )
#        self.rotcomms[comp] = self.addOutbox("rot")
#        self.link( (self, self.rotcomms[comp]), (comp, "rotation") )
        self.scacomms[comp] = self.addOutbox("sca")
        self.link( (self, self.scacomms[comp]), (comp, "scaling") )

        self.rearangeContents()
        
        
    def removeElement(self, comp):
        self.components.remove(comp)
        self.rel_positions.pop(comp)
        self.rel_rotations.pop(comp)
        self.rel_scalings.pop(comp)
        
        # todo: unlink
        
        self.poscomms.pop(comp)
        self.rotcomms.pop(comp)
        self.scacomms.pop(comp)

        self.rearangeContents()
Ejemplo n.º 2
0
class Container(Axon.AdaptiveCommsComponent.AdaptiveCommsComponent):
    """\
    Container(...) -> A new Container component.
    
    A container to control several OpenGLComponents.

    Keyword arguments:
    
    - position  -- Initial container position (default=(0,0,0)).
    - rotation  -- Initial container rotation (default=(0,0,0)).
    - scaling   -- Initial container scaling (default=(1,1,1)).
    - contents  -- Nested dictionary of contained components.
    """

    Inboxes = {
        "inbox": "",
        "control": "For shutdown messages",
        "position": "receive position triple (x,y,z)",
        "rotation": "receive rotation triple (x,y,z)",
        "scaling": "receive scaling triple (x,y,z)",
        "rel_position": "receive position triple (x,y,z)",
        "rel_rotation": "receive rotation triple (x,y,z)",
        "rel_scaling": "receive scaling triple (x,y,z)",
    }

    Outboxes = {"outbox": "", "signal": "For shutdown messages"}

    def __init__(self, **argd):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(Container, self).__init__()

        # get transformation data and convert to vectors
        self.position = Vector(*argd.get("position", (0, 0, 0)))
        self.rotation = Vector(*argd.get("rotation", (0.0, 0.0, 0.0)))
        self.scaling = Vector(*argd.get("scaling", (1, 1, 1)))

        # for detection of changes
        self.oldrot = Vector()
        self.oldpos = Vector()
        self.oldscaling = Vector()

        # inital apply trasformations
        self.transform = Transform()

        self.components = []

        self.rel_positions = {}
        self.rel_rotations = {}
        self.rel_scalings = {}

        self.poscomms = {}
        self.rotcomms = {}
        self.scacomms = {}

        contents = argd.get("contents", None)
        if contents is not None:
            for (comp, params) in contents.items():
                self.addElement(comp, **params)

    def main(self):
        while 1:

            while self.dataReady("control"):
                cmsg = self.recv("control")
                if isinstance(cmsg, producerFinished) or isinstance(
                        cmsg, shutdownMicroprocess):
                    self.send(cmsg, "signal")
                    return

            self.handleMovement()
            self.applyTransforms()
            yield 1

    def handleMovement(self):
        """ Handle movement commands received by corresponding inboxes. """
        while self.dataReady("position"):
            pos = self.recv("position")
            self.position = Vector(*pos)

        while self.dataReady("rotation"):
            rot = self.recv("rotation")
            self.rotation = Vector(*rot)

        while self.dataReady("scaling"):
            scaling = self.recv("scaling")
            self.scaling = Vector(*scaling)

        while self.dataReady("rel_position"):
            self.position += Vector(*self.recv("rel_position"))

        while self.dataReady("rel_rotation"):
            self.rotation += Vector(*self.recv("rel_rotation"))

        while self.dataReady("rel_scaling"):
            self.scaling = Vector(*self.recv("rel_scaling"))

    def applyTransforms(self):
        """ Use the objects translation/rotation/scaling values to generate a new transformation Matrix if changes have happened. """
        # generate new transformation matrix if needed
        if self.oldscaling != self.scaling or self.oldrot != self.rotation or self.oldpos != self.position:
            self.transform = Transform()
            self.transform.applyScaling(self.scaling)
            self.transform.applyRotation(self.rotation)
            self.transform.applyTranslation(self.position)

            self.oldpos = self.position.copy()
            self.oldrot = self.rotation.copy()
            self.oldscaling = self.scaling.copy()

            self.rearangeContents()

    def rearangeContents(self):
        for comp in self.components:
            trans = self.transform.transformVector(self.rel_positions[comp])
            self.send(trans.toTuple(), self.poscomms[comp])
            #                self.send(self.rotation.toTuple(), self.rotcomms[comp])
            self.send(self.scaling.toTuple(), self.scacomms[comp])

    def addElement(self,
                   comp,
                   position=(0, 0, 0),
                   rotation=(0, 0, 0),
                   scaling=(1, 1, 1)):
        self.components.append(comp)
        self.rel_positions[comp] = Vector(*position)
        self.rel_rotations[comp] = Vector(*rotation)
        self.rel_scalings[comp] = Vector(*scaling)

        self.poscomms[comp] = self.addOutbox("pos")
        self.link((self, self.poscomms[comp]), (comp, "position"))
        #        self.rotcomms[comp] = self.addOutbox("rot")
        #        self.link( (self, self.rotcomms[comp]), (comp, "rotation") )
        self.scacomms[comp] = self.addOutbox("sca")
        self.link((self, self.scacomms[comp]), (comp, "scaling"))

        self.rearangeContents()

    def removeElement(self, comp):
        self.components.remove(comp)
        self.rel_positions.pop(comp)
        self.rel_rotations.pop(comp)
        self.rel_scalings.pop(comp)

        # todo: unlink

        self.poscomms.pop(comp)
        self.rotcomms.pop(comp)
        self.scacomms.pop(comp)

        self.rearangeContents()
Ejemplo n.º 3
0
class OpenGLComponent(Axon.AdaptiveCommsComponent.AdaptiveCommsComponent):
    """\
    OpenGLComponent(...) -> create a new OpenGL component (not very useful though; it is rather designed to inherit from).

    This components implements the interaction with the OpenGLDisplay
    service that is needed to setup, draw and move an object using OpenGL.

    Keyword arguments:
    
    - size      -- three dimensional size of component (default=(0,0,0))
    - rotation  -- rotation of component around (x,y,z) axis (defaul=(0,0,0))
    - scaling   -- scaling along the (x,y,z) axis (default=(1,1,1))
    - position  -- three dimensional position (default=(0,0,0))
    - name      -- name of component (mostly for debugging, default="nameless")
    """
    
    Inboxes = {
        "inbox": "not used",
        "control": "For shutdown messages",
        "callback": "for the response after a displayrequest",
        "events": "Input events",
        "position" : "receive position triple (x,y,z)",
        "rotation": "receive rotation triple (x,y,z)",
        "scaling": "receive scaling triple (x,y,z)",
        "rel_position" : "receive position triple (x,y,z)",
        "rel_rotation": "receive rotation triple (x,y,z)",
        "rel_scaling": "receive scaling triple (x,y,z)",
    }
    
    Outboxes = {
        "outbox": "not used",
        "signal": "For shutdown messages",
        "display_signal" : "Outbox used for communicating to the display surface",
        "position" : "send position status when updated",
        "rotation": "send rotation status when updated",
        "scaling": "send scaling status when updated",
    }
    
    def __init__(self, **argd):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(OpenGLComponent, self).__init__()

        # get transformation data and convert to vectors
        self.size = Vector( *argd.get("size", (0,0,0)) )
        self.position = Vector( *argd.get("position", (0,0,0)) )
        self.rotation = Vector( *argd.get("rotation", (0.0,0.0,0.0)) )
        self.scaling = Vector( *argd.get("scaling", (1,1,1) ) )
        
        # for detection of changes
        self.oldrot = Vector()
        self.oldpos = Vector()
        self.oldscaling = Vector()

        self.transform = Transform()

        # name (mostly for debugging)
        self.name = argd.get("name", "nameless")

        # create clock
        self.clock = pygame.time.Clock()
        self.frametime = 0.0

        # get display service
        displayservice = OpenGLDisplay.getDisplayService()
        # link display_signal to displayservice
        self.link((self,"display_signal"), displayservice)
        
            
            
    def main(self):
        # create display request
        self.disprequest = { "OGL_DISPLAYREQUEST" : True,
                             "objectid" : id(self),
                             "callback" : (self,"callback"),
                             "events" : (self, "events"),
                             "size": self.size
                           }
        # send display request
        self.send(self.disprequest, "display_signal")
        # inital apply trasformations
        self.applyTransforms()
        # setup function from derived objects
        self.setup()        
        # initial draw to display list
        self.redraw()

        # wait for response on displayrequest
        while not self.dataReady("callback"):  yield 1
        self.identifier = self.recv("callback")
        
        while 1:
            yield 1
            
            while self.dataReady("control"):
                cmsg = self.recv("control")
                if isinstance(cmsg, producerFinished) or isinstance(cmsg, shutdownMicroprocess):
                    self.send(cmsg, "signal")
                    return
                   
            self.frametime = float(self.clock.tick())/1000.0
            self.handleMovement()
            self.handleEvents()
            self.applyTransforms()
            # frame function from derived objects
            self.frame()
            while not self.anyReady():
                self.pause()
                yield 1

                                          
    def applyTransforms(self):
        """ Use the objects translation/rotation/scaling values to generate a new transformation Matrix if changes have happened. """
        # generate new transformation matrix if needed
        if self.oldscaling != self.scaling or self.oldrot != self.rotation or self.oldpos != self.position:
            self.transform = Transform()
            self.transform.applyScaling(self.scaling)
            self.transform.applyRotation(self.rotation)
            self.transform.applyTranslation(self.position)

            if self.oldscaling != self.scaling:
                self.send(self.scaling.toTuple(), "scaling")
                self.oldscaling = self.scaling.copy()

            if self.oldrot != self.rotation:
                self.send(self.rotation.toTuple(), "rotation")
                self.oldrot = self.rotation.copy()

            if self.oldpos != self.position:
                self.send(self.position.toTuple(), "position")
                self.oldpos = self.position.copy()
                
            # send new transform to display service
            transform_update = { "TRANSFORM_UPDATE": True,
                                 "objectid": id(self),
                                 "transform": self.transform
                               }
            self.send(transform_update, "display_signal")


    def handleMovement(self):
        """ Handle movement commands received by corresponding inboxes. """
        while self.dataReady("position"):
            pos = self.recv("position")
            self.position = Vector(*pos)
        
        while self.dataReady("rotation"):
            rot = self.recv("rotation")
            self.rotation = Vector(*rot)
            
        while self.dataReady("scaling"):
            scaling = self.recv("scaling")
            self.scaling = Vector(*scaling)
            
        while self.dataReady("rel_position"):
            self.position += Vector(*self.recv("rel_position"))
            
        while self.dataReady("rel_rotation"):
            self.rotation += Vector(*self.recv("rel_rotation"))
            
        while self.dataReady("rel_scaling"):
            self.scaling = Vector(*self.recv("rel_scaling"))

    ##
    # Methods to be used by derived objects
    ##

    def addListenEvents(self, events):
        """\
            Sends listening request for pygame events to the display service.
            The events parameter is expected to be a list of pygame event constants.
        """
        for event in events:
            self.send({"ADDLISTENEVENT":event, "objectid":id(self)}, "display_signal")

    
    def removeListenEvents(self, events):
        """\
            Sends stop listening request for pygame events to the display service.
            The events parameter is expected to be a list of pygame event constants.
        """
        for event in events:
            self.send({"REMOVELISTENEVENT":event, "objectid":id(self)}, "display_signal")


    def redraw(self):
        """\
        Invoke draw() and save its commands to a newly generated displaylist.
        
        The displaylist name is then sent to the display service via a
        "DISPLAYLIST_UPDATE" request.
        """
        # display list id
        displaylist = glGenLists(1);
        # draw object to its displaylist
        glNewList(displaylist, GL_COMPILE)
        self.draw()
        glEndList()

        
        dl_update = { "DISPLAYLIST_UPDATE": True,
                      "objectid": id(self),
                      "displaylist": displaylist
                    }
        self.send(dl_update, "display_signal")
        


    ##
    # Method stubs to be overridden by derived objects
    ##

    def handleEvents(self):
        """
        Method stub
        
        Override this method to do event handling inside.
        Should look like this::
        
            while self.dataReady("events"):
                event = self.recv("events")
                # handle event ...
        
        """
        pass        


    def draw(self):
        """
        Method stub
        
        Override this method for drawing. Only use commands which are
        needed for drawing. Will not draw directly but be saved to a
        displaylist. Therefore, make sure not to use any commands which
        cannot be stored in displaylists (unlikely anyway).
        """
        pass

    
    def setup(self):
        """
        Method stub
        
        Override this method for component setup.
        It will be called on the first scheduling of the component.
        """
        pass

    def frame(self):
        """
        Method stub
        
        Override this method for operations you want to do every frame.
        It will be called every time the component is scheduled. Do not
        include infinite loops, the method has to return every time it
        gets called.
        """
        pass
Ejemplo n.º 4
0
class OpenGLComponent(Axon.AdaptiveCommsComponent.AdaptiveCommsComponent):
    """\
    OpenGLComponent(...) -> create a new OpenGL component (not very useful though; it is rather designed to inherit from).

    This components implements the interaction with the OpenGLDisplay
    service that is needed to setup, draw and move an object using OpenGL.

    Keyword arguments:
    
    - size      -- three dimensional size of component (default=(0,0,0))
    - rotation  -- rotation of component around (x,y,z) axis (defaul=(0,0,0))
    - scaling   -- scaling along the (x,y,z) axis (default=(1,1,1))
    - position  -- three dimensional position (default=(0,0,0))
    - name      -- name of component (mostly for debugging, default="nameless")
    """

    Inboxes = {
        "inbox": "not used",
        "control": "For shutdown messages",
        "callback": "for the response after a displayrequest",
        "events": "Input events",
        "position": "receive position triple (x,y,z)",
        "rotation": "receive rotation triple (x,y,z)",
        "scaling": "receive scaling triple (x,y,z)",
        "rel_position": "receive position triple (x,y,z)",
        "rel_rotation": "receive rotation triple (x,y,z)",
        "rel_scaling": "receive scaling triple (x,y,z)",
    }

    Outboxes = {
        "outbox": "not used",
        "signal": "For shutdown messages",
        "display_signal":
        "Outbox used for communicating to the display surface",
        "position": "send position status when updated",
        "rotation": "send rotation status when updated",
        "scaling": "send scaling status when updated",
    }

    def __init__(self, **argd):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(OpenGLComponent, self).__init__()

        # get transformation data and convert to vectors
        self.size = Vector(*argd.get("size", (0, 0, 0)))
        self.position = Vector(*argd.get("position", (0, 0, 0)))
        self.rotation = Vector(*argd.get("rotation", (0.0, 0.0, 0.0)))
        self.scaling = Vector(*argd.get("scaling", (1, 1, 1)))

        # for detection of changes
        self.oldrot = Vector()
        self.oldpos = Vector()
        self.oldscaling = Vector()

        self.transform = Transform()

        # name (mostly for debugging)
        self.name = argd.get("name", "nameless")

        # create clock
        self.clock = pygame.time.Clock()
        self.frametime = 0.0

        # get display service
        displayservice = OpenGLDisplay.getDisplayService()
        # link display_signal to displayservice
        self.link((self, "display_signal"), displayservice)

    def main(self):
        # create display request
        self.disprequest = {
            "OGL_DISPLAYREQUEST": True,
            "objectid": id(self),
            "callback": (self, "callback"),
            "events": (self, "events"),
            "size": self.size
        }
        # send display request
        self.send(self.disprequest, "display_signal")
        # inital apply trasformations
        self.applyTransforms()
        # setup function from derived objects
        self.setup()
        # initial draw to display list
        self.redraw()

        # wait for response on displayrequest
        while not self.dataReady("callback"):
            yield 1
        self.identifier = self.recv("callback")

        while 1:
            yield 1

            while self.dataReady("control"):
                cmsg = self.recv("control")
                if isinstance(cmsg, producerFinished) or isinstance(
                        cmsg, shutdownMicroprocess):
                    self.send(cmsg, "signal")
                    return

            self.frametime = float(self.clock.tick()) / 1000.0
            self.handleMovement()
            self.handleEvents()
            self.applyTransforms()
            # frame function from derived objects
            self.frame()
            while not self.anyReady():
                self.pause()
                yield 1

    def applyTransforms(self):
        """ Use the objects translation/rotation/scaling values to generate a new transformation Matrix if changes have happened. """
        # generate new transformation matrix if needed
        if self.oldscaling != self.scaling or self.oldrot != self.rotation or self.oldpos != self.position:
            self.transform = Transform()
            self.transform.applyScaling(self.scaling)
            self.transform.applyRotation(self.rotation)
            self.transform.applyTranslation(self.position)

            if self.oldscaling != self.scaling:
                self.send(self.scaling.toTuple(), "scaling")
                self.oldscaling = self.scaling.copy()

            if self.oldrot != self.rotation:
                self.send(self.rotation.toTuple(), "rotation")
                self.oldrot = self.rotation.copy()

            if self.oldpos != self.position:
                self.send(self.position.toTuple(), "position")
                self.oldpos = self.position.copy()

            # send new transform to display service
            transform_update = {
                "TRANSFORM_UPDATE": True,
                "objectid": id(self),
                "transform": self.transform
            }
            self.send(transform_update, "display_signal")

    def handleMovement(self):
        """ Handle movement commands received by corresponding inboxes. """
        while self.dataReady("position"):
            pos = self.recv("position")
            self.position = Vector(*pos)

        while self.dataReady("rotation"):
            rot = self.recv("rotation")
            self.rotation = Vector(*rot)

        while self.dataReady("scaling"):
            scaling = self.recv("scaling")
            self.scaling = Vector(*scaling)

        while self.dataReady("rel_position"):
            self.position += Vector(*self.recv("rel_position"))

        while self.dataReady("rel_rotation"):
            self.rotation += Vector(*self.recv("rel_rotation"))

        while self.dataReady("rel_scaling"):
            self.scaling = Vector(*self.recv("rel_scaling"))

    ##
    # Methods to be used by derived objects
    ##

    def addListenEvents(self, events):
        """\
            Sends listening request for pygame events to the display service.
            The events parameter is expected to be a list of pygame event constants.
        """
        for event in events:
            self.send({
                "ADDLISTENEVENT": event,
                "objectid": id(self)
            }, "display_signal")

    def removeListenEvents(self, events):
        """\
            Sends stop listening request for pygame events to the display service.
            The events parameter is expected to be a list of pygame event constants.
        """
        for event in events:
            self.send({
                "REMOVELISTENEVENT": event,
                "objectid": id(self)
            }, "display_signal")

    def redraw(self):
        """\
        Invoke draw() and save its commands to a newly generated displaylist.
        
        The displaylist name is then sent to the display service via a
        "DISPLAYLIST_UPDATE" request.
        """
        # display list id
        displaylist = glGenLists(1)
        # draw object to its displaylist
        glNewList(displaylist, GL_COMPILE)
        self.draw()
        glEndList()

        dl_update = {
            "DISPLAYLIST_UPDATE": True,
            "objectid": id(self),
            "displaylist": displaylist
        }
        self.send(dl_update, "display_signal")

    ##
    # Method stubs to be overridden by derived objects
    ##

    def handleEvents(self):
        """
        Method stub
        
        Override this method to do event handling inside.
        Should look like this::
        
            while self.dataReady("events"):
                event = self.recv("events")
                # handle event ...
        
        """
        pass

    def draw(self):
        """
        Method stub
        
        Override this method for drawing. Only use commands which are
        needed for drawing. Will not draw directly but be saved to a
        displaylist. Therefore, make sure not to use any commands which
        cannot be stored in displaylists (unlikely anyway).
        """
        pass

    def setup(self):
        """
        Method stub
        
        Override this method for component setup.
        It will be called on the first scheduling of the component.
        """
        pass

    def frame(self):
        """
        Method stub
        
        Override this method for operations you want to do every frame.
        It will be called every time the component is scheduled. Do not
        include infinite loops, the method has to return every time it
        gets called.
        """
        pass