Пример #1
0
 def set_label(self, new_name):
     if self.initSize == Vector():
         self.size = Vector()
     self.name = new_name
     self.buildCaption()        
     #  It's after buildCaption() because self.size is decided only after buildCaption() if size=(0,0,0)
     self.radius = self.size.length()/2
Пример #2
0
    def draw(self):
        """Draw sphere particle."""
        hs = self.radius
        glColor4f(self.sidecurcolour[0] / 256.0, self.sidecurcolour[1] / 256.0,
                  self.sidecurcolour[2] / 256.0, 0.5)

        # Create a quadratic object for sphere rendering
        quadratic = gluNewQuadric()
        gluQuadricNormals(quadratic, GLU_SMOOTH)
        gluQuadricTexture(quadratic, GL_TRUE)

        # Add texture
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)

        # Draw sphere
        gluSphere(quadratic, hs, 32, 32)
        #glutSolidSphere(hs,32,32)

        glDisable(GL_TEXTURE_2D)

        # Draw links
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadMatrixf(self.linkTransform.getMatrix())
        for p in self.bondedTo:
            glBegin(GL_LINES)
            glVertex3f(*self.initialpos.toTuple())
            glVertex3f(*(Vector(*p.pos) - Vector(*self.pos)).toTuple())
            glEnd()
        glPopMatrix()
Пример #3
0
    def buildCaption(self):
        """Pre-render the text to go on the label."""
        # Text is rendered to self.image
        if self.pic is not None:
            if self.pic.find('://') != -1 and not os.path.exists(self.pic):
                """ FIXME: either use thread to wrap urlopen or kamaelia HTTP components 
                in case urlopen is blocked """
                fObject = urlopen(self.pic)
                picData = fObject.read()
                pic = StringIO(picData)
            else:
                pic = self.pic
            self.image = pygame.image.load(pic).convert()
        else:
            pygame.font.init()
            font = pygame.font.Font(None, self.fontsize)
            self.image = font.render(self.name,True, self.foregroundColour, )
        
        if self.size != Vector(0,0,0):
            texsize = (self.size.x*self.pixelscaling, self.size.y*self.pixelscaling)
        else:
            texsize = ( self.image.get_width()+2*self.margin, self.image.get_height()+2*self.margin )
            self.size=Vector(texsize[0]/float(self.pixelscaling), texsize[1]/float(self.pixelscaling), self.thickness)

        # create power of 2 dimensioned surface
        pow2size = (int(2**(math.ceil(math.log(texsize[0]+2*self.margin, 2)))), int(2**(math.ceil(math.log(texsize[1]+2*self.margin, 2)))))
        textureSurface = pygame.Surface(pow2size)
        textureSurface.fill( self.backgroundColour )
        # determine texture coordinates
        self.tex_w = float(texsize[0])/pow2size[0]
        self.tex_h = float(texsize[1])/pow2size[1]
        # copy image data to pow2surface
        dest = ( max((texsize[0]-self.image.get_width())/2, 0), max((texsize[1]-self.image.get_height())/2, 0) )
        textureSurface.blit(self.image, dest)
#        textureSurface.set_alpha(128)
        textureSurface = textureSurface.convert_alpha()

        # read pixel data
        textureData = pygame.image.tostring(textureSurface, "RGBX", 1)
        #print self.image.get_width(), self.image.get_height()
        #print textureSurface.get_width(), textureSurface.get_height()
        #print textureData

        self.texID = glGenTextures(1)
        # create texture
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, textureSurface.get_width(), textureSurface.get_height(), 0,
                        GL_RGBA, GL_UNSIGNED_BYTE, textureData );
        glDisable(GL_TEXTURE_2D)
Пример #4
0
    def frame(self):
        while self.dataReady("position"):
            self.position = Vector(*self.recv("position"))
            if self.lastValidPos is None:
                self.lastValidPos = self.position.copy()

        while self.dataReady("inbox"):

            msg = self.recv("inbox")
            if msg == "ACK":
                self.lastValidPos = self.position.copy()
            elif msg == "INVALID":
                diff = self.lastValidPos - self.position
                diff.z = 0
                self.send(diff.toTuple(), "movement")
Пример #5
0
 def rotateParticles(self, particles, dAngle):
     """\
     Rotate the particles around their common centre dAngle degree.
     Particles is a list; dAngle is a triple tuple of degree.
     If particles are given an empty list, rotate all particles instead.
     """
     if particles == []:
         particles = self.currentDisplayedPhysics.particles
     centrePoint = Vector()
     for particle in particles:
         posVector = Vector(*particle.pos)
         centrePoint += posVector
     centrePoint /= len(particles)
     if dAngle[0] != 0:  # Rotate around x axis
         for particle in particles:
             posVector = Vector(*particle.pos)
             relativePosVector = posVector - centrePoint
             radius = (relativePosVector.z * relativePosVector.z +
                       relativePosVector.y * relativePosVector.y)**0.5
             newAngle = (
                 math.atan2(relativePosVector.z, relativePosVector.y) +
                 dAngle[0] * math.pi / 180)
             particle.pos = (posVector.x,
                             radius * math.cos(newAngle) + centrePoint.y,
                             radius * math.sin(newAngle) + centrePoint.z)
             particle.drotation += Vector(dAngle[0], 0, 0)
     if dAngle[1] != 0:  # Rotate around y axis
         for particle in particles:
             posVector = Vector(*particle.pos)
             relativePosVector = posVector - centrePoint
             radius = (relativePosVector.z * relativePosVector.z +
                       relativePosVector.x * relativePosVector.x)**0.5
             newAngle = (
                 math.atan2(relativePosVector.z, relativePosVector.x) +
                 dAngle[1] * math.pi / 180)
             particle.pos = (radius * math.cos(newAngle) + centrePoint.x,
                             posVector.y,
                             radius * math.sin(newAngle) + centrePoint.z)
             particle.drotation += Vector(0, -dAngle[1], 0)
     if dAngle[2] != 0:  # Rotate around z axis
         for particle in particles:
             posVector = Vector(*particle.pos)
             relativePosVector = posVector - centrePoint
             radius = (relativePosVector.x * relativePosVector.x +
                       relativePosVector.y * relativePosVector.y)**0.5
             newAngle = (
                 math.atan2(relativePosVector.y, relativePosVector.x) +
                 dAngle[2] * math.pi / 180)
             particle.pos = (radius * math.cos(newAngle) + centrePoint.x,
                             radius * math.sin(newAngle) + centrePoint.y,
                             posVector.z)
             particle.drotation += Vector(0, 0, dAngle[2])
     # An angle keeps the same with when it minus muptiple 360
     particle.drotation %= 360
Пример #6
0
    def buildCaption(self):
        """Pre-render the text to go on the label."""
        # Text is rendered to self.image
        if self.image is not None:
            if self.imageIO is not None:
                self.imageSurface = pygame.image.load(self.imageIO).convert()
                self.imageIO = None
            elif os.path.exists(self.image):
                self.imageSurface = pygame.image.load(self.image).convert()
            # Image texture is used instead of label texture if 'image' argument is specified
            elif self.image.find('://') != -1:
                # Use text label for notification of waiting before the picture is available
                pygame.font.init()
                font = pygame.font.Font(None, self.fontsize)
                self.imageSurface = font.render("Loading image...",True, self.fgcurcolour, )
                # Use thread to wrap urlopen in case urlopen is blocked
                import thread
                thread.start_new(self.readURLFile, ())
        else:
            # Label texture is used if 'image' argument is not specified
            pygame.font.init()
            font = pygame.font.Font(None, self.fontsize)
            self.imageSurface = font.render(self.name,True, self.fgcurcolour, )
        
        if self.size != Vector(0,0,0):
            texsize = (self.size.x*self.pixelscaling, self.size.y*self.pixelscaling)
        else:
            texsize = ( self.imageSurface.get_width()+2*self.margin, self.imageSurface.get_height()+2*self.margin )
            self.size=Vector(texsize[0]/float(self.pixelscaling), texsize[1]/float(self.pixelscaling), self.thickness)

        # create power of 2 dimensioned surface
        pow2size = (int(2**(math.ceil(math.log(texsize[0]+2*self.margin, 2)))), int(2**(math.ceil(math.log(texsize[1]+2*self.margin, 2)))))
        textureSurface = pygame.Surface(pow2size)
        textureSurface.fill( self.bgcurcolour )
        # determine texture coordinates
        self.tex_w = float(texsize[0])/pow2size[0]
        self.tex_h = float(texsize[1])/pow2size[1]
        # copy image data to pow2surface
        dest = ( max((texsize[0]-self.imageSurface.get_width())/2, 0), max((texsize[1]-self.imageSurface.get_height())/2, 0) )
        textureSurface.blit(self.imageSurface, dest)
        textureSurface = textureSurface.convert_alpha()

        # read pixel data
        textureData = pygame.image.tostring(textureSurface, "RGBX", 1)

        self.texID = glGenTextures(1)
        # create texture
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, textureSurface.get_width(), textureSurface.get_height(), 0,
                        GL_RGBA, GL_UNSIGNED_BYTE, textureData );
        glDisable(GL_TEXTURE_2D)
Пример #7
0
    def draw(self):
        """Draw teapot particle."""
        hs = self.radius
        glColor4f(self.sidecurcolour[0] / 256.0, self.sidecurcolour[1] / 256.0,
                  self.sidecurcolour[2] / 256.0, 0.5)

        # Add texture
        glMatrixMode(GL_TEXTURE)
        glPushMatrix()
        glLoadIdentity()
        glRotatef(180.0, 0.0, 0.0, 1.0)
        glMatrixMode(GL_MODELVIEW)

        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)

        # Draw teapot
        glFrontFace(GL_CW)
        glutSolidTeapot(hs)
        glFrontFace(GL_CCW)

        glDisable(GL_TEXTURE_2D)

        glMatrixMode(GL_TEXTURE)
        glPopMatrix()
        glMatrixMode(GL_MODELVIEW)

        # Draw links
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadMatrixf(self.linkTransform.getMatrix())
        for p in self.bondedTo:
            glBegin(GL_LINES)
            glVertex3f(*self.initialpos.toTuple())
            glVertex3f(*(Vector(*p.pos) - Vector(*self.pos)).toTuple())
            glEnd()
        glPopMatrix()


# Licensed to the BBC under a Contributor Agreement: CL
Пример #8
0
    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.drotation != Vector() or self.oldpos != Vector(*self.pos):
            self.transform = Transform()
            self.linkTransform = Transform()
            drotationTransform = Transform()
            drotationTransform.applyRotation(self.drotation)
            
            self.transform.applyScaling(self.scaling)
            self.linkTransform.applyScaling(self.scaling)
            
            self.transform = self.transform*self.oldrotTransform*drotationTransform
            self.oldrotTransform = self.oldrotTransform*drotationTransform
            
            self.transform.applyTranslation(Vector(*self.pos))
            self.linkTransform.applyTranslation(Vector(*self.pos))

            if self.oldscaling != self.scaling:
                self.oldscaling = self.scaling.copy()
            
            self.drotation = Vector()    
            
            if self.oldpos != Vector(*self.pos):
                self.oldpos = Vector(*self.pos)
            
            # send new transform to display service
            transform_update = { "TRANSFORM_UPDATE": True,
                                 "objectid": id(self),
                                 "transform": self.transform
                               }
            return transform_update
        else:
            return None
Пример #9
0
    def handleEvents(self):
        while self.dataReady("events"):
            setPullPoint = False
            event = self.recv("events")
            if (event.type == pygame.MOUSEBUTTONDOWN and event.button == 1
                    and self.identifier in event.hitobjects):
                self.pulling = True
                setPullPoint = True

            if (event.type == pygame.MOUSEBUTTONUP and self.pulling):
                self.pulling = False
                self.foldpoint, self.folddelta = calcFoldLine(
                    (0.0, 0.0), (0.0, 0.0), self.radius)

            if self.pulling:

                # transform vertices for intersection test
                transformedPoly = [
                    self.transform.transformVector(Vector(x, y, 0.0))
                    for ((x, y), _) in self.polys[0]
                ]
                # calculate distance of intersection
                t = Intersect.ray_Plane(Vector(0, 0, 0), event.direction,
                                        transformedPoly[0:3])
                # point of intersection
                p = event.direction * t

                point = mapPlaneToPoly(
                    transformedPoly[0].toTuple(),
                    transformedPoly[1].toTuple(),
                    transformedPoly[2].toTuple(),
                    self.polys[0][0][0],
                    self.polys[0][1][0],
                    self.polys[0][2][0],
                    p.toTuple(),
                )
                if setPullPoint:
                    self.pullpoint = point[0], point[1]
                self.foldpoint, self.folddelta = calcFoldLine(
                    self.pullpoint, point, self.radius)
Пример #10
0
    def __init__(self, position=(-1, 0, -10), ID="", **argd):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(Particle3D, self).__init__(position=position, ID=ID)

        self.pos = position
        self.initSize = Vector(*argd.get("size", (0, 0, 0)))

        self.selected = False

        self.bgcolour = argd.get("bgcolour", (230, 230, 230))
        self.fgcolour = argd.get("fgcolour", (0, 0, 0))
        self.sidecolour = argd.get("sidecolour", (200, 200, 244))

        self.bgcolourselected = argd.get("bgcolourselected", (0, 0, 0))
        self.fgcolourselected = argd.get("fgcolourselected", (244, 244, 244))
        self.sidecolourselected = argd.get("sidecolourselected", (0, 0, 100))

        self.margin = argd.get("margin", 8)
        self.fontsize = argd.get("fontsize", 50)
        self.pixelscaling = argd.get("pixelscaling", 100)
        self.thickness = argd.get("thickness", 0.3)

        # For picture texture
        self.image = argd.get("image", None)
        # For remote picture
        self.imageIO = None

        name = argd.get("name", "NoName")
        self.set_label(name)

        # For rotation and scaling
        self.drotation = Vector()
        self.scaling = Vector(*argd.get("scaling", (1, 1, 1)))

        # For detection of changes
        self.oldpos = self.initialpos = Vector()
        self.oldscaling = Vector()

        # For transformation matrix multiplication
        # Store all transformations
        self.transform = Transform()
        # Specially store link transformations because link doesn't do rotation and scaling
        self.linkTransform = Transform()
        # Store all previous transformations to be multiplied with the current one
        self.oldrotTransform = Transform()

        # For redraw detection
        self.needRedraw = True

        # For drag handling
        self.oldpoint = None
Пример #11
0
 def draw(self):
     """ DRAW teapot particle."""
     hs = self.radius
     
     # Add texture
     glMatrixMode(GL_TEXTURE)
     glPushMatrix()
     glLoadIdentity()
     glRotatef(180.0,0.0,0.0,1.0)
     glMatrixMode(GL_MODELVIEW)
     
     glEnable(GL_TEXTURE_2D)
     glBindTexture(GL_TEXTURE_2D, self.texID)
     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
     
     
     
     # Draw teapot
     glFrontFace(GL_CW)
     glutSolidTeapot(hs)
     glFrontFace(GL_CCW)
     
     glDisable(GL_TEXTURE_2D)
     
     glMatrixMode(GL_TEXTURE)
     glPopMatrix()
     glMatrixMode(GL_MODELVIEW)
     
     # Draw links        
     glMatrixMode(GL_MODELVIEW)
     glPushMatrix()
     glLoadMatrixf(self.linkTransform.getMatrix())
     for p in self.bondedTo:
         glBegin(GL_LINES)
         glVertex3f(*self.initialpos.toTuple())
         glVertex3f(*(Vector(*p.pos)-Vector(*self.pos)).toTuple())
         glEnd()
     glPopMatrix()
Пример #12
0
 def frame(self):
     while self.dataReady("position"):
         self.position = Vector(*self.recv("position"))
         if self.lastValidPos is None:
             self.lastValidPos = self.position.copy()
         
     while self.dataReady("inbox"):
     
         msg = self.recv("inbox")
         if msg == "ACK":
             self.lastValidPos = self.position.copy()
         elif msg == "INVALID":
             diff = self.lastValidPos - self.position
             diff.z = 0
             self.send(diff.toTuple(), "movement")
Пример #13
0
    def __init__(self, position=(-1, 0, -10), ID='', **argd):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(Particle3D, self).__init__(position=position, ID=ID)

        self.pos = position
        self.initSize = Vector(*argd.get("size", (0, 0, 0)))

        self.selected = False

        self.bgcolour = argd.get("bgcolour", (230, 230, 230))
        self.fgcolour = argd.get("fgcolour", (0, 0, 0))
        self.sidecolour = argd.get("sidecolour", (200, 200, 244))

        self.bgcolourselected = argd.get("bgcolourselected", (0, 0, 0))
        self.fgcolourselected = argd.get("fgcolourselected", (244, 244, 244))
        self.sidecolourselected = argd.get("sidecolourselected", (0, 0, 100))

        self.margin = argd.get("margin", 8)
        self.fontsize = argd.get("fontsize", 50)
        self.pixelscaling = argd.get("pixelscaling", 100)
        self.thickness = argd.get("thickness", 0.3)

        # For picture texture
        self.image = argd.get("image", None)
        # For remote picture
        self.imageIO = None

        name = argd.get("name", "NoName")
        self.set_label(name)

        # For rotation and scaling
        self.drotation = Vector()
        self.scaling = Vector(*argd.get("scaling", (1, 1, 1)))

        # For detection of changes
        self.oldpos = self.initialpos = Vector()
        self.oldscaling = Vector()

        # For transformation matrix multiplication
        # Store all transformations
        self.transform = Transform()
        # Specially store link transformations because link doesn't do rotation and scaling
        self.linkTransform = Transform()
        # Store all previous transformations to be multiplied with the current one
        self.oldrotTransform = Transform()

        # For redraw detection
        self.needRedraw = True

        # For drag handling
        self.oldpoint = None
Пример #14
0
 def gotoDisplayLevel(self, dlevel):
     # Save current level's viewer position
     self.levelViewerPos[
         self.currentLevel] = self.display.viewerposition.copy()
     # Display next level
     self.currentLevel += dlevel
     # Reset viewer position to previous
     try:
         self.display.viewerposition = self.levelViewerPos[
             self.currentLevel].copy()
     except KeyError:
         self.display.viewerposition = self.levelViewerPos[
             self.currentLevel] = Vector()
     # Remove current displayed particles
     for particle in self.currentDisplayedPhysics.particles:
         self.display.ogl_displaylists.pop(id(particle))
         self.display.ogl_transforms.pop(id(particle))
     self.currentDisplayedPhysics.removeByID(
         *self.currentDisplayedPhysics.particleDict.keys())
Пример #15
0
    def __init__(self, position = (-1,0,-10), ID='', **argd):
        super(Particle3D, self).__init__(position=position, ID = ID)
        
        self.pos = position
        self.initSize = Vector(*argd.get("size", (0,0,0)))

        self.backgroundColourWhenUnselected = self.backgroundColour = argd.get("bgcolour", (230,230,230))
        self.foregroundColourWhenUnselected = self.foregroundColour = argd.get("fgcolour", (0,0,0))
        self.sideColourWhenUnselected = self.sideColour = argd.get("sidecolour", (200,200,244))
        
        self.backgroundColourWhenSelected = argd.get("bgcolourselected", (0,0,0))
        self.foregroundColourWhenSelected = argd.get("fgcolourselected", (244,244,244))
        self.sideColourWhenSelected = argd.get("sidecolourselected", (200,200,244))
        
        self.margin = argd.get("margin", 8)
        self.fontsize = argd.get("fontsize", 50)
        self.pixelscaling = argd.get("pixelscaling", 100)
        self.thickness = argd.get("thickness", 0.3)
        
        # For picture texture
        self.pic = argd.get("image", None)
        
        name = argd.get("name","NoName")
        self.set_label(name)
        
        # For rotation and scaling
        self.drotation = Vector()
        self.scaling = Vector( *argd.get("scaling", (1,1,1) ) )
        
        # For detection of changes
        self.oldpos = self.initialpos = Vector()
        self.oldscaling = Vector()
        
        # For transformation matrix multiplication
        self.transform = Transform()
        self.linkTransform = Transform()
        self.oldrotTransform = Transform()
        
        # For redraw detection
        self.needRedraw = True
        
        # For drag handling
        self.oldpoint = None
Пример #16
0
    def buildCaption(self):
        """Pre-render the text to go on the label."""
        # Text is rendered to self.image
        if self.image is not None:
            if self.imageIO is not None:
                self.imageSurface = pygame.image.load(self.imageIO).convert()
                self.imageIO = None
            elif os.path.exists(self.image):
                self.imageSurface = pygame.image.load(self.image).convert()
            # Image texture is used instead of label texture if 'image' argument is specified
            elif self.image.find('://') != -1:
                # Use text label for notification of waiting before the picture is available
                pygame.font.init()
                font = pygame.font.Font(None, self.fontsize)
                self.imageSurface = font.render(
                    "Loading image...",
                    True,
                    self.fgcurcolour,
                )
                # Use thread to wrap urlopen in case urlopen is blocked
                import thread
                thread.start_new(self.readURLFile, ())
        else:
            # Label texture is used if 'image' argument is not specified
            pygame.font.init()
            font = pygame.font.Font(None, self.fontsize)
            self.imageSurface = font.render(
                self.name,
                True,
                self.fgcurcolour,
            )

        if self.size != Vector(0, 0, 0):
            texsize = (self.size.x * self.pixelscaling,
                       self.size.y * self.pixelscaling)
        else:
            texsize = (self.imageSurface.get_width() + 2 * self.margin,
                       self.imageSurface.get_height() + 2 * self.margin)
            self.size = Vector(texsize[0] / float(self.pixelscaling),
                               texsize[1] / float(self.pixelscaling),
                               self.thickness)

        # create power of 2 dimensioned surface
        pow2size = (int(2**(math.ceil(math.log(texsize[0] + 2 * self.margin,
                                               2)))),
                    int(2**(math.ceil(math.log(texsize[1] + 2 * self.margin,
                                               2)))))
        textureSurface = pygame.Surface(pow2size)
        textureSurface.fill(self.bgcurcolour)
        # determine texture coordinates
        self.tex_w = float(texsize[0]) / pow2size[0]
        self.tex_h = float(texsize[1]) / pow2size[1]
        # copy image data to pow2surface
        dest = (max((texsize[0] - self.imageSurface.get_width()) / 2, 0),
                max((texsize[1] - self.imageSurface.get_height()) / 2, 0))
        textureSurface.blit(self.imageSurface, dest)
        textureSurface = textureSurface.convert_alpha()

        # read pixel data
        textureData = pygame.image.tostring(textureSurface, "RGBX", 1)

        self.texID = glGenTextures(1)
        # create texture
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureSurface.get_width(),
                     textureSurface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     textureData)
        glDisable(GL_TEXTURE_2D)
Пример #17
0
 def __init__(self, **argd):
     super(SphereParticle3D, self).__init__(**argd)
     self.drotation = Vector(0,0,90)
Пример #18
0
class Particle3D(BaseParticle):
    """\
    A super class for 3D particles
    super(RenderingParticle3D, self).__init__(**argd)
    
    Simple 3D generic superclass particle for topology visualisation.
    
    Keyword arguments:
    
    - ID        -- a unique ID for this particle
    - position  -- (x,y,z) tuple of particle coordinates
    - name      -- A name this particle will be labelled with
    - bgcolour  -- Colour of surfaces behind text label (default=(230,230,230)), only apply to label texture 
    - fgcolour  -- Colour of the text label (default=(0,0,0), only apply to label texture 
    - sidecolour -- Colour of side planes (default=(200,200,244)), only apply to CuboidParticle3D
    - bgcolourselected  -- Background colour when the particle is selected (default=(0,0,0)
    - bgcolourselected  -- Frontground colour when the particle is selected (default=(244,244,244))
    - sidecolourselected -- Side colour when the particle is selected (default=(0,0,100))
    - size         -- Size of particle (length, width, depth), it depends on texture size if unspecified
    - margin       -- Margin size in pixels (default=8)
    - fontsize     -- Font size for label text (default=50)
    - pixelscaling -- Factor to convert pixels to units in 3d, ignored if size is specified (default=100)
    - thickness    -- Thickness of button widget, ignored if size is specified (default=0.3)
    - image        -- The uri of image, image texture instead of label texture is used if specified
    """
    def __init__(self, position=(-1, 0, -10), ID='', **argd):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(Particle3D, self).__init__(position=position, ID=ID)

        self.pos = position
        self.initSize = Vector(*argd.get("size", (0, 0, 0)))

        self.selected = False

        self.bgcolour = argd.get("bgcolour", (230, 230, 230))
        self.fgcolour = argd.get("fgcolour", (0, 0, 0))
        self.sidecolour = argd.get("sidecolour", (200, 200, 244))

        self.bgcolourselected = argd.get("bgcolourselected", (0, 0, 0))
        self.fgcolourselected = argd.get("fgcolourselected", (244, 244, 244))
        self.sidecolourselected = argd.get("sidecolourselected", (0, 0, 100))

        self.margin = argd.get("margin", 8)
        self.fontsize = argd.get("fontsize", 50)
        self.pixelscaling = argd.get("pixelscaling", 100)
        self.thickness = argd.get("thickness", 0.3)

        # For picture texture
        self.image = argd.get("image", None)
        # For remote picture
        self.imageIO = None

        name = argd.get("name", "NoName")
        self.set_label(name)

        # For rotation and scaling
        self.drotation = Vector()
        self.scaling = Vector(*argd.get("scaling", (1, 1, 1)))

        # For detection of changes
        self.oldpos = self.initialpos = Vector()
        self.oldscaling = Vector()

        # For transformation matrix multiplication
        # Store all transformations
        self.transform = Transform()
        # Specially store link transformations because link doesn't do rotation and scaling
        self.linkTransform = Transform()
        # Store all previous transformations to be multiplied with the current one
        self.oldrotTransform = Transform()

        # For redraw detection
        self.needRedraw = True

        # For drag handling
        self.oldpoint = None

    def get_bgcolour(self):
        """Get bgcolour."""
        return self._bgcolour

    def set_bgcolour(self, value):
        """Set bgcolour and bgcurcolour as well if it is not selected."""
        self._bgcolour = value
        if not self.selected:
            self.bgcurcolour = value

    bgcolour = property(get_bgcolour, set_bgcolour, None, None)

    def get_fgcolour(self):
        """Get fgcolour."""
        return self._fgcolour

    def set_fgcolour(self, value):
        """Set fgcolour and fgcurcolour as well if it is not selected."""
        self._fgcolour = value
        if not self.selected:
            self.fgcurcolour = value

    fgcolour = property(get_fgcolour, set_fgcolour, None, None)

    def get_sidecolour(self):
        """Get sidecolour."""
        return self._sidecolour

    def set_sidecolour(self, value):
        """Set sidecolour and sidecurcolour as well if it is not selected."""
        self._sidecolour = value
        if not self.selected:
            self.sidecurcolour = value

    sidecolour = property(get_sidecolour, set_sidecolour, None, None)

    def get_bgcolourselected(self):
        """Get bgcolourselected."""
        return self._bgcolourselected

    def set_bgcolourselected(self, value):
        """Set bgcolourselected and bgcurcolour as well if it is selected."""
        self._bgcolourselected = value
        if self.selected:
            self.bgcurcolour = value

    bgcolourselected = property(get_bgcolourselected, set_bgcolourselected,
                                None, None)

    def get_fgcolourselected(self):
        """Get fgcolourselected."""
        return self._fgcolourselected

    def set_fgcolourselected(self, value):
        """Set fgcolourselected and fgcurcolour as well if it is selected."""
        self._fgcolourselected = value
        if self.selected:
            self.fgcurcolour = value

    fgcolourselected = property(get_fgcolourselected, set_fgcolourselected,
                                None, None)

    def get_sidecolourselected(self):
        """Get sidecolourselected."""
        return self._sidecolourselected

    def set_sidecolourselected(self, value):
        """Set sidecolourselected and sidecurcolour as well if it is selected."""
        self._sidecolourselected = value
        if self.selected:
            self.sidecurcolour = value

    sidecolourselected = property(get_sidecolourselected,
                                  set_sidecolourselected, None, None)

    def set_label(self, new_name):
        """Set text label."""
        if self.initSize == Vector():
            self.size = Vector()
        self.name = new_name
        self.buildCaption()
        #  It's after buildCaption() because self.size is decided only after buildCaption() if size=(0,0,0)
        self.radius = self.size.length() / 2

    def updateAttrs(self, **params):
        """Update attributes."""
        for key, value in params.iteritems():
            setattr(self, key, value)
        self.buildCaption()

    def draw(self):
        """\Stub method
        Override this method to draw concrete particles and links.
        """
        pass

    def readURLFile(self):
        """Read a string buffer of an object denoted by a URL."""
        fObject = urlopen(self.image)
        imageData = fObject.read()
        self.imageIO = StringIO(imageData)
        # Text label is not needed for picture texture
        self.set_label("Dummy")

    def buildCaption(self):
        """Pre-render the text to go on the label."""
        # Text is rendered to self.image
        if self.image is not None:
            if self.imageIO is not None:
                self.imageSurface = pygame.image.load(self.imageIO).convert()
                self.imageIO = None
            elif os.path.exists(self.image):
                self.imageSurface = pygame.image.load(self.image).convert()
            # Image texture is used instead of label texture if 'image' argument is specified
            elif self.image.find('://') != -1:
                # Use text label for notification of waiting before the picture is available
                pygame.font.init()
                font = pygame.font.Font(None, self.fontsize)
                self.imageSurface = font.render(
                    "Loading image...",
                    True,
                    self.fgcurcolour,
                )
                # Use thread to wrap urlopen in case urlopen is blocked
                import thread
                thread.start_new(self.readURLFile, ())
        else:
            # Label texture is used if 'image' argument is not specified
            pygame.font.init()
            font = pygame.font.Font(None, self.fontsize)
            self.imageSurface = font.render(
                self.name,
                True,
                self.fgcurcolour,
            )

        if self.size != Vector(0, 0, 0):
            texsize = (self.size.x * self.pixelscaling,
                       self.size.y * self.pixelscaling)
        else:
            texsize = (self.imageSurface.get_width() + 2 * self.margin,
                       self.imageSurface.get_height() + 2 * self.margin)
            self.size = Vector(texsize[0] / float(self.pixelscaling),
                               texsize[1] / float(self.pixelscaling),
                               self.thickness)

        # create power of 2 dimensioned surface
        pow2size = (int(2**(math.ceil(math.log(texsize[0] + 2 * self.margin,
                                               2)))),
                    int(2**(math.ceil(math.log(texsize[1] + 2 * self.margin,
                                               2)))))
        textureSurface = pygame.Surface(pow2size)
        textureSurface.fill(self.bgcurcolour)
        # determine texture coordinates
        self.tex_w = float(texsize[0]) / pow2size[0]
        self.tex_h = float(texsize[1]) / pow2size[1]
        # copy image data to pow2surface
        dest = (max((texsize[0] - self.imageSurface.get_width()) / 2, 0),
                max((texsize[1] - self.imageSurface.get_height()) / 2, 0))
        textureSurface.blit(self.imageSurface, dest)
        textureSurface = textureSurface.convert_alpha()

        # read pixel data
        textureData = pygame.image.tostring(textureSurface, "RGBX", 1)

        self.texID = glGenTextures(1)
        # create texture
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureSurface.get_width(),
                     textureSurface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     textureData)
        glDisable(GL_TEXTURE_2D)

    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.drotation != Vector(
        ) or self.oldpos != Vector(*self.pos):
            self.transform = Transform()
            self.linkTransform = Transform()
            drotationTransform = Transform()
            drotationTransform.applyRotation(self.drotation)

            self.transform.applyScaling(self.scaling)
            self.linkTransform.applyScaling(self.scaling)

            self.transform = self.transform * self.oldrotTransform * drotationTransform
            self.oldrotTransform = self.oldrotTransform * drotationTransform

            self.transform.applyTranslation(Vector(*self.pos))
            self.linkTransform.applyTranslation(Vector(*self.pos))

            if self.oldscaling != self.scaling:
                self.oldscaling = self.scaling.copy()

            self.drotation = Vector()

            if self.oldpos != Vector(*self.pos):
                self.oldpos = Vector(*self.pos)

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

    def select(self):
        """Tell this particle it is selected"""
        self.selected = True
        self.sidecurcolour = self.sidecolourselected
        self.bgcurcolour = self.bgcolourselected
        self.fgcurcolour = self.fgcolourselected
        self.buildCaption()

    def deselect(self):
        """Tell this particle it is deselected"""
        self.selected = False
        self.sidecurcolour = self.sidecolour
        self.bgcurcolour = self.bgcolour
        self.fgcurcolour = self.fgcolour
        self.buildCaption()
Пример #19
0
    def gotoDisplayLevel(self, dlevel):
        """Switch to another display level."""
        isValid = False
        if self.currentLevel + dlevel > self.maxLevel:
            print("Warning: max hierarchy level has reached!")
        elif self.currentLevel + dlevel < 0:
            print("Warning: The first hierarchy level has reached!")
        else:
            if dlevel < 0:  # Go to the last dlevel level
                self.previousParentParticleID = self.currentParentParticleID
                items = self.currentParentParticleID.split(':')
                for _ in xrange(-dlevel):
                    items.pop()
                self.currentParentParticleID = ':'.join(items)
                isValid = True
            if dlevel == 1:  # It only makes sense if dlevel == 1 when go to next dlevel level
                if len(self.selectedParticles) == 1:
                    hasChildParticles = False
                    for particle in self.physics.particles:
                        if particle.ID.find(
                                self.selectedParticles[0].ID
                        ) == 0 and particle.ID != self.selectedParticles[0].ID:
                            hasChildParticles = True
                            break
                    if hasChildParticles:
                        self.previousParentParticleID = self.currentParentParticleID
                        self.currentParentParticleID = self.selectedParticles[
                            0].ID
                        isValid = True
                    else:
                        print(
                            'Warning: The particle you double-clicked has no children!'
                        )
                else:
                    print(
                        "Tips: To extend a node, please double-click the node you want to extend"
                    )
        # Show the specified display level if valid
        if isValid:
            # Save current level's viewer position
            self.levelViewerPos[
                self.currentLevel, self.
                previousParentParticleID] = self.display.viewerposition.copy()
            # Deselect all
            self.deselectAll()
            # Display next level
            self.currentLevel += dlevel
            # Reset viewer position to previous
            try:
                self.display.viewerposition = self.levelViewerPos[
                    self.currentLevel, self.currentParentParticleID].copy()
            except KeyError:
                self.display.viewerposition = self.levelViewerPos[
                    self.currentLevel,
                    self.currentParentParticleID] = Vector()
            # Remove current displayed particles
            for particle in self.currentDisplayedPhysics.particles:
                self.display.ogl_displaylists.pop(id(particle))
                self.display.ogl_transforms.pop(id(particle))
            self.currentDisplayedPhysics.removeByID(
                *self.currentDisplayedPhysics.particleDict.keys())

            # Add current level's particles to self.currentDisplayedPhysics.particles for display
            self.currentDisplayedPhysics.particles = []
            if self.physics.particles != []:
                for particle in self.physics.particles:
                    if self.currentParentParticleID == '':  # If no parent, it's the top level
                        if ':' not in particle.ID:
                            self.currentDisplayedPhysics.add(particle)
                            particle.oldpos = particle.initialpos
                    # The child particles of self.currentParentParticleID
                    elif particle.ID.find(
                            self.currentParentParticleID
                    ) == 0 and particle.ID.count(':') == self.currentLevel:
                        self.currentDisplayedPhysics.add(particle)
                        particle.oldpos = particle.initialpos
Пример #20
0
class Particle3D(BaseParticle):
    """\
    A super class for 3D particles
    super(RenderingParticle3D, self).__init__(**argd)
    
    Simple 3D generic superclass particle for topology visualisation.
    
    Keyword arguments:
    
    - ID        -- a unique ID for this particle
    - position  -- (x,y,z) tuple of particle coordinates
    - name      -- A name this particle will be labelled with
    - bgcolour  -- Colour of surfaces behind text label (default=(230,230,230)), only apply to label texture 
    - fgcolour  -- Colour of the text label (default=(0,0,0), only apply to label texture 
    - sidecolour -- Colour of side planes (default=(200,200,244)), only apply to CuboidParticle3D
    - bgcolourselected  -- Background colour when the particle is selected (default=(0,0,0)
    - bgcolourselected  -- Frontground colour when the particle is selected (default=(244,244,244))
    - sidecolourselected -- Side colour when the particle is selected (default=(0,0,100))
    - size         -- Size of particle (length, width, depth), it depends on texture size if unspecified
    - margin       -- Margin size in pixels (default=8)
    - fontsize     -- Font size for label text (default=50)
    - pixelscaling -- Factor to convert pixels to units in 3d, ignored if size is specified (default=100)
    - thickness    -- Thickness of button widget, ignored if size is specified (default=0.3)
    - image        -- The uri of image, image texture instead of label texture is used if specified
    """

    def __init__(self, position=(-1, 0, -10), ID="", **argd):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(Particle3D, self).__init__(position=position, ID=ID)

        self.pos = position
        self.initSize = Vector(*argd.get("size", (0, 0, 0)))

        self.selected = False

        self.bgcolour = argd.get("bgcolour", (230, 230, 230))
        self.fgcolour = argd.get("fgcolour", (0, 0, 0))
        self.sidecolour = argd.get("sidecolour", (200, 200, 244))

        self.bgcolourselected = argd.get("bgcolourselected", (0, 0, 0))
        self.fgcolourselected = argd.get("fgcolourselected", (244, 244, 244))
        self.sidecolourselected = argd.get("sidecolourselected", (0, 0, 100))

        self.margin = argd.get("margin", 8)
        self.fontsize = argd.get("fontsize", 50)
        self.pixelscaling = argd.get("pixelscaling", 100)
        self.thickness = argd.get("thickness", 0.3)

        # For picture texture
        self.image = argd.get("image", None)
        # For remote picture
        self.imageIO = None

        name = argd.get("name", "NoName")
        self.set_label(name)

        # For rotation and scaling
        self.drotation = Vector()
        self.scaling = Vector(*argd.get("scaling", (1, 1, 1)))

        # For detection of changes
        self.oldpos = self.initialpos = Vector()
        self.oldscaling = Vector()

        # For transformation matrix multiplication
        # Store all transformations
        self.transform = Transform()
        # Specially store link transformations because link doesn't do rotation and scaling
        self.linkTransform = Transform()
        # Store all previous transformations to be multiplied with the current one
        self.oldrotTransform = Transform()

        # For redraw detection
        self.needRedraw = True

        # For drag handling
        self.oldpoint = None

    def get_bgcolour(self):
        """Get bgcolour."""
        return self._bgcolour

    def set_bgcolour(self, value):
        """Set bgcolour and bgcurcolour as well if it is not selected."""
        self._bgcolour = value
        if not self.selected:
            self.bgcurcolour = value

    bgcolour = property(get_bgcolour, set_bgcolour, None, None)

    def get_fgcolour(self):
        """Get fgcolour."""
        return self._fgcolour

    def set_fgcolour(self, value):
        """Set fgcolour and fgcurcolour as well if it is not selected."""
        self._fgcolour = value
        if not self.selected:
            self.fgcurcolour = value

    fgcolour = property(get_fgcolour, set_fgcolour, None, None)

    def get_sidecolour(self):
        """Get sidecolour."""
        return self._sidecolour

    def set_sidecolour(self, value):
        """Set sidecolour and sidecurcolour as well if it is not selected."""
        self._sidecolour = value
        if not self.selected:
            self.sidecurcolour = value

    sidecolour = property(get_sidecolour, set_sidecolour, None, None)

    def get_bgcolourselected(self):
        """Get bgcolourselected."""
        return self._bgcolourselected

    def set_bgcolourselected(self, value):
        """Set bgcolourselected and bgcurcolour as well if it is selected."""
        self._bgcolourselected = value
        if self.selected:
            self.bgcurcolour = value

    bgcolourselected = property(get_bgcolourselected, set_bgcolourselected, None, None)

    def get_fgcolourselected(self):
        """Get fgcolourselected."""
        return self._fgcolourselected

    def set_fgcolourselected(self, value):
        """Set fgcolourselected and fgcurcolour as well if it is selected."""
        self._fgcolourselected = value
        if self.selected:
            self.fgcurcolour = value

    fgcolourselected = property(get_fgcolourselected, set_fgcolourselected, None, None)

    def get_sidecolourselected(self):
        """Get sidecolourselected."""
        return self._sidecolourselected

    def set_sidecolourselected(self, value):
        """Set sidecolourselected and sidecurcolour as well if it is selected."""
        self._sidecolourselected = value
        if self.selected:
            self.sidecurcolour = value

    sidecolourselected = property(get_sidecolourselected, set_sidecolourselected, None, None)

    def set_label(self, new_name):
        """Set text label."""
        if self.initSize == Vector():
            self.size = Vector()
        self.name = new_name
        self.buildCaption()
        #  It's after buildCaption() because self.size is decided only after buildCaption() if size=(0,0,0)
        self.radius = self.size.length() / 2

    def updateAttrs(self, **params):
        """Update attributes."""
        for key, value in params.iteritems():
            setattr(self, key, value)
        self.buildCaption()

    def draw(self):
        """\Stub method
        Override this method to draw concrete particles and links.
        """
        pass

    def readURLFile(self):
        """Read a string buffer of an object denoted by a URL."""
        fObject = urlopen(self.image)
        imageData = fObject.read()
        self.imageIO = StringIO(imageData)
        # Text label is not needed for picture texture
        self.set_label("Dummy")

    def buildCaption(self):
        """Pre-render the text to go on the label."""
        # Text is rendered to self.image
        if self.image is not None:
            if self.imageIO is not None:
                self.imageSurface = pygame.image.load(self.imageIO).convert()
                self.imageIO = None
            elif os.path.exists(self.image):
                self.imageSurface = pygame.image.load(self.image).convert()
            # Image texture is used instead of label texture if 'image' argument is specified
            elif self.image.find("://") != -1:
                # Use text label for notification of waiting before the picture is available
                pygame.font.init()
                font = pygame.font.Font(None, self.fontsize)
                self.imageSurface = font.render("Loading image...", True, self.fgcurcolour)
                # Use thread to wrap urlopen in case urlopen is blocked
                import thread

                thread.start_new(self.readURLFile, ())
        else:
            # Label texture is used if 'image' argument is not specified
            pygame.font.init()
            font = pygame.font.Font(None, self.fontsize)
            self.imageSurface = font.render(self.name, True, self.fgcurcolour)

        if self.size != Vector(0, 0, 0):
            texsize = (self.size.x * self.pixelscaling, self.size.y * self.pixelscaling)
        else:
            texsize = (
                self.imageSurface.get_width() + 2 * self.margin,
                self.imageSurface.get_height() + 2 * self.margin,
            )
            self.size = Vector(
                texsize[0] / float(self.pixelscaling), texsize[1] / float(self.pixelscaling), self.thickness
            )

        # create power of 2 dimensioned surface
        pow2size = (
            int(2 ** (math.ceil(math.log(texsize[0] + 2 * self.margin, 2)))),
            int(2 ** (math.ceil(math.log(texsize[1] + 2 * self.margin, 2)))),
        )
        textureSurface = pygame.Surface(pow2size)
        textureSurface.fill(self.bgcurcolour)
        # determine texture coordinates
        self.tex_w = float(texsize[0]) / pow2size[0]
        self.tex_h = float(texsize[1]) / pow2size[1]
        # copy image data to pow2surface
        dest = (
            max((texsize[0] - self.imageSurface.get_width()) / 2, 0),
            max((texsize[1] - self.imageSurface.get_height()) / 2, 0),
        )
        textureSurface.blit(self.imageSurface, dest)
        textureSurface = textureSurface.convert_alpha()

        # read pixel data
        textureData = pygame.image.tostring(textureSurface, "RGBX", 1)

        self.texID = glGenTextures(1)
        # create texture
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexImage2D(
            GL_TEXTURE_2D,
            0,
            GL_RGBA,
            textureSurface.get_width(),
            textureSurface.get_height(),
            0,
            GL_RGBA,
            GL_UNSIGNED_BYTE,
            textureData,
        )
        glDisable(GL_TEXTURE_2D)

    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.drotation != Vector() or self.oldpos != Vector(*self.pos):
            self.transform = Transform()
            self.linkTransform = Transform()
            drotationTransform = Transform()
            drotationTransform.applyRotation(self.drotation)

            self.transform.applyScaling(self.scaling)
            self.linkTransform.applyScaling(self.scaling)

            self.transform = self.transform * self.oldrotTransform * drotationTransform
            self.oldrotTransform = self.oldrotTransform * drotationTransform

            self.transform.applyTranslation(Vector(*self.pos))
            self.linkTransform.applyTranslation(Vector(*self.pos))

            if self.oldscaling != self.scaling:
                self.oldscaling = self.scaling.copy()

            self.drotation = Vector()

            if self.oldpos != Vector(*self.pos):
                self.oldpos = Vector(*self.pos)

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

    def select(self):
        """Tell this particle it is selected"""
        self.selected = True
        self.sidecurcolour = self.sidecolourselected
        self.bgcurcolour = self.bgcolourselected
        self.fgcurcolour = self.fgcolourselected
        self.buildCaption()

    def deselect(self):
        """Tell this particle it is deselected"""
        self.selected = False
        self.sidecurcolour = self.sidecolour
        self.bgcurcolour = self.bgcolour
        self.fgcurcolour = self.fgcolour
        self.buildCaption()
Пример #21
0
    def handleMouseEvents(self, event):
        """Handle mouse events."""
        if event.type == pygame.MOUSEBUTTONDOWN or pygame.MOUSEMOTION and self.grabbed:
            if not self.rotationMode:
                for particle in self.hitParticles:
                    p1 = Vector(*particle.pos).copy()
                    p1.x += 10
                    p2 = Vector(*particle.pos).copy()
                    p2.y += 10
                    # Get the position of mouse
                    z = Intersect.ray_Plane(Vector(0, 0, 0), event.direction, [
                        Vector(*particle.pos) -
                        Vector(0, 0, self.display.viewerposition.z),
                        p1 - Vector(0, 0, self.display.viewerposition.z),
                        p2 - Vector(0, 0, self.display.viewerposition.z)
                    ])
                    newpoint = event.direction * z
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                # Handle double click
                clickPos = event.pos
                currentTime = time.time()
                elapsedTime = currentTime - self.lastClickTime
                # If it's a double-click
                if clickPos == self.lastClickPos and elapsedTime < self.dClickRes:
                    self.gotoDisplayLevel(1)
                else:  # Single click
                    if not self.rotationMode:  # Select particle
                        for particle in self.currentDisplayedPhysics.particles:
                            if particle.identifier in event.hitobjects:
                                self.grabbed = True
                                self.hitParticles.append(particle)
                                self.selectParticle(particle)
                        # If click places other than particles in non multiSelectMode, deselect all
                        if not self.hitParticles and not self.multiSelectMode:
                            self.deselectAll()
                self.lastClickPos = clickPos
                self.lastClickTime = currentTime
            elif event.button == 3:  # Right-clicked
                self.gotoDisplayLevel(-1)
            elif event.button == 4:  # Scrolled-up: zoom out
                if self.selectedParticles:
                    particles = self.selectedParticles
                else:
                    particles = self.currentDisplayedPhysics.particles
                for particle in particles:
                    posVector = Vector(*particle.pos)
                    posVector.z -= 1
                    particle.pos = posVector.toTuple()
            elif event.button == 5:  # Scrolled-down: zoom in
                if self.selectedParticles:
                    particles = self.selectedParticles
                else:
                    particles = self.currentDisplayedPhysics.particles
                for particle in particles:
                    posVector = Vector(*particle.pos)
                    posVector.z += 1
                    particle.pos = posVector.toTuple()
        if event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                for particle in self.hitParticles:
                    self.grabbed = False
                    particle.oldpoint = None
                    self.hitParticles.pop(self.hitParticles.index(particle))
        if event.type == pygame.MOUSEMOTION:
            if not self.rotationMode and self.grabbed:  # Drag particles
                for particle in self.hitParticles:
                    try:
                        if particle.oldpoint is not None:
                            diff = newpoint - particle.oldpoint
                            amount = (diff.x, diff.y)
                            particle.pos = (Vector(*particle.pos) +
                                            Vector(*amount)).toTuple()
                    except NameError:
                        pass

                    # Redraw the link so that the link can move with the particle
                    for p in particle.bondedFrom:
                        p.needRedraw = True
            elif self.rotationMode:  # Rotate particles
                dAnglex = float(event.rel[1])
                dAngley = -float(event.rel[0])
                self.rotateParticles(self.selectedParticles,
                                     (dAnglex, dAngley, 0))

        try:
            for particle in self.hitParticles:
                particle.oldpoint = newpoint
        except NameError:
            pass
Пример #22
0
class CheckersInteractor(Interactor):
    
    def __init__(self, **argd):
        super(CheckersInteractor, self).__init__(**argd)

        self.addInbox("position")
        self.addOutbox("movement")

        self.liftheight = argd.get("liftheight", 0.2)
        self.colour = argd.get("colour")
                                         
        self.grabbed = False
        self.position = None
        self.oldpoint = None
        self.lastValidPos = None
            
        if self.nolink == False:
            self.link( (self, "movement"), (self.target, "rel_position") )
            self.link( (self.target, "position"), (self, "position") )


    def setup(self):
        self.addListenEvents( [pygame.MOUSEMOTION, pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP ])


    def handleEvents(self):
        while self.dataReady("events"):
            event = self.recv("events")
            
            if self.position is not None:
                if event.type == pygame.MOUSEBUTTONDOWN or pygame.MOUSEMOTION and self.grabbed:
                    p1 = self.position.copy()
                    p1.x += 10
                    p2 = self.position.copy()
                    p2.y += 10
                    z = Intersect.ray_Plane(event.viewerposition, event.direction, [self.position, p1, p2])
                    newpoint = event.direction * z
                    
                if event.type == pygame.MOUSEBUTTONDOWN and self.identifier in event.hitobjects:
                    if event.button == 1:
                        self.grabbed = True
                        self.send((0,0,self.liftheight), "movement")
                        
                if event.type == pygame.MOUSEBUTTONUP:
                    if event.button == 1 and self.grabbed:
                        self.grabbed = False
                        # place piece in the middle of a black field
                        alignedpos = self.position.copy()
                        alignedpos.x = floor(alignedpos.x)+0.5
                        alignedpos.y = floor(alignedpos.y)+0.5

                        diff = alignedpos - self.position
                        self.send((diff.x,diff.y,-self.liftheight), "movement")
                        
                        self.position = alignedpos

                        fr = (floor(self.lastValidPos.x)+4, floor(self.lastValidPos.y)+4)
                        to = (floor(alignedpos.x)+4, floor(alignedpos.y)+4 )
                        self.send( {"PLACEMENT":True, "from":fr, "to":to, "colour":self.colour, "objectid": id(self)}, "outbox")

                if event.type == pygame.MOUSEMOTION:
                    if self.grabbed == True:
                        if self.oldpoint is not None:
                            diff = newpoint-self.oldpoint
                            diff.z = 0
                            self.send(diff.toTuple(), "movement")

                try:
                    self.oldpoint = newpoint
                except NameError: pass            


    def frame(self):
        while self.dataReady("position"):
            self.position = Vector(*self.recv("position"))
            if self.lastValidPos is None:
                self.lastValidPos = self.position.copy()
            
        while self.dataReady("inbox"):
        
            msg = self.recv("inbox")
            if msg == "ACK":
                self.lastValidPos = self.position.copy()
            elif msg == "INVALID":
                diff = self.lastValidPos - self.position
                diff.z = 0
                self.send(diff.toTuple(), "movement")
Пример #23
0
    def __init__(self,
                 screensize=(800, 600),
                 fullscreen=False,
                 caption="3D Topology Viewer",
                 particleTypes=None,
                 initialTopology=None,
                 laws=None,
                 simCyclesPerRedraw=1,
                 border=0):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""

        super(TopologyViewer3D, self).__init__()

        glutInit(sys.argv)

        tracker = _cat.coordinatingassistanttracker.getcat()
        try:
            self.display = tracker.retrieveService("ogl_display")[0]
        except KeyError:
            self.display = OpenGLDisplay(width=screensize[0],
                                         height=screensize[1],
                                         fullscreen=fullscreen,
                                         title=caption)
            self.display.activate()
            OpenGLDisplay.setDisplayService(self.display, tracker)
        self.display = OpenGLDisplay.getDisplayService()[0]
        self.link((self, "display_signal"), (self.display, "notify"))
        self.link((self.display, "signal"), (self, "control"))

        self.border = border

        if particleTypes == None:
            self.particleTypes = {
                "-": CuboidParticle3D,
                "cuboid": CuboidParticle3D,
                "sphere": SphereParticle3D,
                "teapot": TeapotParticle3D
            }
        else:
            self.particleTypes = particleTypes

        if initialTopology == None:
            initialTopology = ([], [])
        self.initialNodes = list(initialTopology[0])
        self.initialBonds = list(initialTopology[1])

        self.hitParticles = []
        self.multiSelectMode = False
        self.selectedParticles = []
        self.grabbed = False
        self.rotationMode = False

        if laws == None:
            self.laws = Kamaelia.Support.Particles.SimpleLaws(bondLength=2)
        else:
            self.laws = laws

        self.physics = ParticleSystem(self.laws, [], 0)
        self.biggestRadius = 0

        # Do interaction
        self.simCyclesPerRedraw = simCyclesPerRedraw
        self.lastIdleTime = time.time()

        # Tell if new node is added; if true, new id needs adding to OpenGLDisplay list
        self.isNewNode = False

        # For hierarchy structure
        self.maxLevel = 0
        self.currentLevel = 0
        self.previousParentParticleID = self.currentParentParticleID = ''
        self.viewerOldPos = Vector()
        self.levelViewerPos = {}
        # The Physics particle system of current display level for display
        self.currentDisplayedPhysics = ParticleSystem(self.laws, [], 0)

        # For double click
        self.lastClickPos = (0, 0)
        self.lastClickTime = time.time()
        self.dClickRes = 0.3
Пример #24
0
class Particle3D(BaseParticle):
    """\
    A super class for 3D particles
    """
    
    def __init__(self, position = (-1,0,-10), ID='', **argd):
        super(Particle3D, self).__init__(position=position, ID = ID)
        
        self.pos = position
        self.initSize = Vector(*argd.get("size", (0,0,0)))

        self.backgroundColourWhenUnselected = self.backgroundColour = argd.get("bgcolour", (230,230,230))
        self.foregroundColourWhenUnselected = self.foregroundColour = argd.get("fgcolour", (0,0,0))
        self.sideColourWhenUnselected = self.sideColour = argd.get("sidecolour", (200,200,244))
        
        self.backgroundColourWhenSelected = argd.get("bgcolourselected", (0,0,0))
        self.foregroundColourWhenSelected = argd.get("fgcolourselected", (244,244,244))
        self.sideColourWhenSelected = argd.get("sidecolourselected", (200,200,244))
        
        self.margin = argd.get("margin", 8)
        self.fontsize = argd.get("fontsize", 50)
        self.pixelscaling = argd.get("pixelscaling", 100)
        self.thickness = argd.get("thickness", 0.3)
        
        # For picture texture
        self.pic = argd.get("image", None)
        
        name = argd.get("name","NoName")
        self.set_label(name)
        
        # For rotation and scaling
        self.drotation = Vector()
        self.scaling = Vector( *argd.get("scaling", (1,1,1) ) )
        
        # For detection of changes
        self.oldpos = self.initialpos = Vector()
        self.oldscaling = Vector()
        
        # For transformation matrix multiplication
        self.transform = Transform()
        self.linkTransform = Transform()
        self.oldrotTransform = Transform()
        
        # For redraw detection
        self.needRedraw = True
        
        # For drag handling
        self.oldpoint = None
        
        
    
    def set_label(self, new_name):
        if self.initSize == Vector():
            self.size = Vector()
        self.name = new_name
        self.buildCaption()        
        #  It's after buildCaption() because self.size is decided only after buildCaption() if size=(0,0,0)
        self.radius = self.size.length()/2
    
    def draw(self):
        """\Stub method
        
        Override this method to draw particles and links.
        """
        pass
        
    def buildCaption(self):
        """Pre-render the text to go on the label."""
        # Text is rendered to self.image
        if self.pic is not None:
            if self.pic.find('://') != -1 and not os.path.exists(self.pic):
                """ FIXME: either use thread to wrap urlopen or kamaelia HTTP components 
                in case urlopen is blocked """
                fObject = urlopen(self.pic)
                picData = fObject.read()
                pic = StringIO(picData)
            else:
                pic = self.pic
            self.image = pygame.image.load(pic).convert()
        else:
            pygame.font.init()
            font = pygame.font.Font(None, self.fontsize)
            self.image = font.render(self.name,True, self.foregroundColour, )
        
        if self.size != Vector(0,0,0):
            texsize = (self.size.x*self.pixelscaling, self.size.y*self.pixelscaling)
        else:
            texsize = ( self.image.get_width()+2*self.margin, self.image.get_height()+2*self.margin )
            self.size=Vector(texsize[0]/float(self.pixelscaling), texsize[1]/float(self.pixelscaling), self.thickness)

        # create power of 2 dimensioned surface
        pow2size = (int(2**(math.ceil(math.log(texsize[0]+2*self.margin, 2)))), int(2**(math.ceil(math.log(texsize[1]+2*self.margin, 2)))))
        textureSurface = pygame.Surface(pow2size)
        textureSurface.fill( self.backgroundColour )
        # determine texture coordinates
        self.tex_w = float(texsize[0])/pow2size[0]
        self.tex_h = float(texsize[1])/pow2size[1]
        # copy image data to pow2surface
        dest = ( max((texsize[0]-self.image.get_width())/2, 0), max((texsize[1]-self.image.get_height())/2, 0) )
        textureSurface.blit(self.image, dest)
#        textureSurface.set_alpha(128)
        textureSurface = textureSurface.convert_alpha()

        # read pixel data
        textureData = pygame.image.tostring(textureSurface, "RGBX", 1)
        #print self.image.get_width(), self.image.get_height()
        #print textureSurface.get_width(), textureSurface.get_height()
        #print textureData

        self.texID = glGenTextures(1)
        # create texture
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, textureSurface.get_width(), textureSurface.get_height(), 0,
                        GL_RGBA, GL_UNSIGNED_BYTE, textureData );
        glDisable(GL_TEXTURE_2D)
        
        
        
    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.drotation != Vector() or self.oldpos != Vector(*self.pos):
            self.transform = Transform()
            self.linkTransform = Transform()
            drotationTransform = Transform()
            drotationTransform.applyRotation(self.drotation)
            
            self.transform.applyScaling(self.scaling)
            self.linkTransform.applyScaling(self.scaling)
            
            self.transform = self.transform*self.oldrotTransform*drotationTransform
            self.oldrotTransform = self.oldrotTransform*drotationTransform
            
            self.transform.applyTranslation(Vector(*self.pos))
            self.linkTransform.applyTranslation(Vector(*self.pos))

            if self.oldscaling != self.scaling:
                self.oldscaling = self.scaling.copy()
            
            self.drotation = Vector()    
            
            if self.oldpos != Vector(*self.pos):
                self.oldpos = Vector(*self.pos)
            
            # send new transform to display service
            transform_update = { "TRANSFORM_UPDATE": True,
                                 "objectid": id(self),
                                 "transform": self.transform
                               }
            return transform_update
        else:
            return None

    
    def select( self ):
        """Tell this particle it is selected"""
        #self.selected = True
        self.sideColour = self.sideColourWhenSelected
        self.backgroundColour = self.backgroundColourWhenSelected
        self.foregroundColour = self.foregroundColourWhenSelected
        self.buildCaption()

    def deselect( self ):
        """Tell this particle it is deselected"""
        #self.selected = False
        self.sideColour = self.sideColourWhenUnselected
        self.backgroundColour = self.backgroundColourWhenUnselected
        self.foregroundColour = self.foregroundColourWhenUnselected
        self.buildCaption()
Пример #25
0
    def handleEvents(self):
        """ Handle events. """
        while self.dataReady("events"):
            event = self.recv("events")
            if event.type == pygame.MOUSEBUTTONDOWN or pygame.MOUSEMOTION and self.grabbed:
                if not self.rotationMode:
                    for particle in self.hitParticles:
                        p1 = Vector(*particle.pos).copy()
                        p1.x += 10
                        p2 = Vector(*particle.pos).copy()
                        p2.y += 10
                        #z = Intersect.ray_Plane(Vector(0,0,0), event.direction, [Vector(*particle.pos)-self.display.viewerposition, p1, p2])
                        z = Intersect.ray_Plane(Vector(0,0,0), event.direction, [Vector(*particle.pos)-Vector(0,0,self.display.viewerposition.z), p1-Vector(0,0,self.display.viewerposition.z), p2-Vector(0,0,self.display.viewerposition.z)])
                        newpoint = event.direction * z
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    # Handle double click
                    clickPos = event.pos
                    currentTime = time.time()
                    elapsedTime = currentTime - self.lastClickTime
                    if clickPos == self.lastClickPos and elapsedTime<self.dClickRes:
                        if self.currentLevel < self.maxLevel and len(self.selectedParticles) == 1:
                            hasChildParticles = False
                            for particle in self.physics.particles:
                                if particle.ID.find(self.selectedParticles[0].ID) == 0 and particle.ID != self.selectedParticles[0].ID:
                                    hasChildParticles = True
                                    break
                            if hasChildParticles:
                                self.currentParentParticleID = self.selectedParticles[0].ID
                                self.gotoDisplayLevel(1)
                            else:
                                print 'Warning: The particle you double-clicked has no children!'
                            
                        else:
                            if self.currentLevel == self.maxLevel:
                                print "Warning: max hierarchy level has reached!"
                            if len(self.selectedParticles) != 1:
                                print "Tips: To extend a node, please double-click the node you want to extend"
                    else:
                        if not self.rotationMode:
                            for particle in self.currentDisplayedPhysics.particles:
                                if particle.identifier in event.hitobjects:
                                    #particle.oldpos = particle.oldpos - self.display.viewerposition
                                    self.grabbed = True
                                    #particle.scaling = Vector(0.9,0.9,0.9)
                                    self.hitParticles.append(particle)
                                    self.selectParticle(particle)
                                    #print str(id(particle))+'hit'
                                    #print self.hitParticles
                            # If click places other than particles in non multiSelectMode, deselect all
                            if not self.hitParticles and not self.multiSelectMode:
                                self.deselectAll()
                    self.lastClickPos = clickPos
                    self.lastClickTime = currentTime
                if event.button == 3:
                    if self.currentLevel > 0:
                        items = self.currentParentParticleID.split(':')
                        items.pop()
                        self.currentParentParticleID = ':'.join(items)
                        self.gotoDisplayLevel(-1)
                    else:
                        print "Warning: The first hierarchy level has reached!"
                if event.button == 4:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        posVector.z -= 1
                        particle.pos = posVector.toTuple()
                if event.button == 5:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        posVector.z += 1
                        particle.pos = posVector.toTuple()
            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:  
                    for particle in self.hitParticles:
                        self.grabbed = False
                        particle.oldpoint = None
                        #particle.scaling = Vector(1,1,1)
                        self.hitParticles.pop(self.hitParticles.index(particle))
                        #print self.hitParticles
            if event.type == pygame.MOUSEMOTION: 
                if not self.rotationMode and self.grabbed: 
                    for particle in self.hitParticles:
                        try:
                            if particle.oldpoint is not None:
                                #print particle.pos
                                diff = newpoint-particle.oldpoint
                                amount = (diff.x, diff.y)
                                particle.pos = (Vector(*particle.pos)+Vector(*amount)).toTuple()
                        except NameError: pass
                        
                        # Redraw the link so that the link can move with the particle
                        for p in particle.bondedFrom:
                            p.needRedraw = True
                elif self.rotationMode:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    
                    centrePoint = Vector() 
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAnglex = float(event.rel[1])*math.pi/180
                    dAngley = -float(event.rel[0])*math.pi/180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (relativePosVector.z*relativePosVector.z+relativePosVector.y*relativePosVector.y)**0.5
                        newAnglex = (math.atan2(relativePosVector.z,relativePosVector.y)+dAnglex)
                        particle.pos = (posVector.x, radius*math.cos(newAnglex)+centrePoint.y, radius*math.sin(newAnglex)+centrePoint.z)
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (relativePosVector.z*relativePosVector.z+relativePosVector.x*relativePosVector.x)**0.5
                        newAngley = (math.atan2(relativePosVector.z,relativePosVector.x)+dAngley)
                        particle.pos = (radius*math.cos(newAngley)+centrePoint.x, posVector.y, radius*math.sin(newAngley)+centrePoint.z)      
                        particle.drotation.y = float(event.rel[0])
                        particle.drotation.x = float(event.rel[1])
                        particle.drotation %= 360
            
            try:
                for particle in self.hitParticles:
                    particle.oldpoint = newpoint                    
            except NameError: pass    
                    
            # Keyboard events handling
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.quit()
                elif event.key == pygame.K_BACKSPACE:
                    if self.currentLevel > 0:
                        items = self.currentParentParticleID.split(':')
                        items.pop()
                        self.currentParentParticleID = ':'.join(items)
                        self.gotoDisplayLevel(-1)
                    else:
                        print "Warning: The first hierarchy level has reached!"
                elif event.key == pygame.K_RETURN:
                    if self.currentLevel < self.maxLevel and len(self.selectedParticles) == 1:
                        hasChildParticles = False
                        for particle in self.physics.particles:
                            if particle.ID.find(self.selectedParticles[0].ID) == 0 and particle.ID != self.selectedParticles[0].ID:
                                hasChildParticles = True
                                break
                        if hasChildParticles:
                            self.currentParentParticleID = self.selectedParticles[0].ID
                            self.gotoDisplayLevel(1)
                        else:
                            print 'Warning: The particle you double-clicked has no children!'
                    else:
                        if self.currentLevel == self.maxLevel:
                            print "Warning: max hierarchy level has reached!"
                        if len(self.selectedParticles) != 1:
                            print "Tips: To extend a node, please click to select the node (only one) you want to extend first."
                        
                elif event.key == pygame.K_LSHIFT or event.key == pygame.K_RSHIFT:
                    self.multiSelectMode = True
                elif event.key == pygame.K_LCTRL or event.key == pygame.K_RCTRL:
                    self.rotationMode = True
                elif event.key == pygame.K_PAGEUP:
                    self.display.viewerposition.z -= 0.5
                elif event.key == pygame.K_PAGEDOWN:
                    self.display.viewerposition.z += 0.5
                elif event.key == pygame.K_w:
                    self.display.viewerposition.y += 0.5
                elif event.key == pygame.K_s:
                    self.display.viewerposition.y -= 0.5
                elif event.key == pygame.K_a:
                    self.display.viewerposition.x -= 0.5
                elif event.key == pygame.K_d:
                    self.display.viewerposition.x += 0.5
                elif event.key == pygame.K_UP:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector() 
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = -20*math.pi/180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (relativePosVector.z*relativePosVector.z+relativePosVector.y*relativePosVector.y)**0.5
                        newAngle = (math.atan2(relativePosVector.z,relativePosVector.y)+dAngle)
                        particle.pos = (posVector.x, radius*math.cos(newAngle)+centrePoint.y, radius*math.sin(newAngle)+centrePoint.z)
                        particle.drotation = Vector(dAngle*180/math.pi,0,0)      
                elif event.key == pygame.K_DOWN:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector() 
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = 20*math.pi/180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (relativePosVector.z*relativePosVector.z+relativePosVector.y*relativePosVector.y)**0.5
                        newAngle = (math.atan2(relativePosVector.z,relativePosVector.y)+dAngle)
                        particle.pos = (posVector.x, radius*math.cos(newAngle)+centrePoint.y, radius*math.sin(newAngle)+centrePoint.z)
                        particle.drotation = Vector(dAngle*180/math.pi,0,0) 
                elif event.key == pygame.K_LEFT:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector() 
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = 20*math.pi/180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (relativePosVector.z*relativePosVector.z+relativePosVector.x*relativePosVector.x)**0.5
                        newAngle = (math.atan2(relativePosVector.z,relativePosVector.x)+dAngle)
                        particle.pos = (radius*math.cos(newAngle)+centrePoint.x, posVector.y, radius*math.sin(newAngle)+centrePoint.z)
                        particle.drotation = Vector(0,-dAngle*180/math.pi,0)
                elif event.key == pygame.K_RIGHT:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector() 
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = -20*math.pi/180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (relativePosVector.z*relativePosVector.z+relativePosVector.x*relativePosVector.x)**0.5
                        newAngle = (math.atan2(relativePosVector.z,relativePosVector.x)+dAngle)
                        particle.pos = (radius*math.cos(newAngle)+centrePoint.x, posVector.y, radius*math.sin(newAngle)+centrePoint.z)
                        particle.drotation = Vector(0,-dAngle*180/math.pi,0)
                elif event.key == pygame.K_COMMA:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector() 
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = 20*math.pi/180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (relativePosVector.x*relativePosVector.x+relativePosVector.y*relativePosVector.y)**0.5
                        newAngle = (math.atan2(relativePosVector.y,relativePosVector.x)+dAngle)
                        particle.pos = (radius*math.cos(newAngle)+centrePoint.x, radius*math.sin(newAngle)+centrePoint.y, posVector.z)
                        particle.drotation = Vector(0,0,dAngle*180/math.pi)
                elif event.key == pygame.K_PERIOD:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector() 
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = -20*math.pi/180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (relativePosVector.x*relativePosVector.x+relativePosVector.y*relativePosVector.y)**0.5
                        newAngle = (math.atan2(relativePosVector.y,relativePosVector.x)+dAngle)
                        particle.pos = (radius*math.cos(newAngle)+centrePoint.x, radius*math.sin(newAngle)+centrePoint.y, posVector.z)
                        particle.drotation = Vector(0,0,dAngle*180/math.pi)
                
            #print self.display.viewerposition
            # Scroll if self.display.viewerposition changes
            if self.display.viewerposition.copy() != self.viewerOldPos:
                self.scroll()
                self.viewerOldPos = self.display.viewerposition.copy()
#                for particle in self.currentDisplayedPhysics.particles:
#                    particle.oldpoint = None
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LSHIFT or event.key == pygame.K_RSHIFT:
                    self.multiSelectMode = False
                elif event.key == pygame.K_LCTRL or event.key == pygame.K_RCTRL:
                    self.rotationMode = False                 
Пример #26
0
    def handleEvents(self):
        """ Handle events. """
        while self.dataReady("events"):
            event = self.recv("events")
            if event.type == pygame.MOUSEBUTTONDOWN or pygame.MOUSEMOTION and self.grabbed:
                if not self.rotationMode:
                    for particle in self.hitParticles:
                        p1 = Vector(*particle.pos).copy()
                        p1.x += 10
                        p2 = Vector(*particle.pos).copy()
                        p2.y += 10
                        #z = Intersect.ray_Plane(Vector(0,0,0), event.direction, [Vector(*particle.pos)-self.display.viewerposition, p1, p2])
                        z = Intersect.ray_Plane(Vector(
                            0, 0, 0), event.direction, [
                                Vector(*particle.pos) -
                                Vector(0, 0, self.display.viewerposition.z),
                                p1 -
                                Vector(0, 0, self.display.viewerposition.z),
                                p2 -
                                Vector(0, 0, self.display.viewerposition.z)
                            ])
                        newpoint = event.direction * z
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    # Handle double click
                    clickPos = event.pos
                    currentTime = time.time()
                    elapsedTime = currentTime - self.lastClickTime
                    if clickPos == self.lastClickPos and elapsedTime < self.dClickRes:
                        if self.currentLevel < self.maxLevel and len(
                                self.selectedParticles) == 1:
                            hasChildParticles = False
                            for particle in self.physics.particles:
                                if particle.ID.find(
                                        self.selectedParticles[0].ID
                                ) == 0 and particle.ID != self.selectedParticles[
                                        0].ID:
                                    hasChildParticles = True
                                    break
                            if hasChildParticles:
                                self.currentParentParticleID = self.selectedParticles[
                                    0].ID
                                self.gotoDisplayLevel(1)
                            else:
                                print 'Warning: The particle you double-clicked has no children!'

                        else:
                            if self.currentLevel == self.maxLevel:
                                print "Warning: max hierarchy level has reached!"
                            if len(self.selectedParticles) != 1:
                                print "Tips: To extend a node, please double-click the node you want to extend"
                    else:
                        if not self.rotationMode:
                            for particle in self.currentDisplayedPhysics.particles:
                                if particle.identifier in event.hitobjects:
                                    #particle.oldpos = particle.oldpos - self.display.viewerposition
                                    self.grabbed = True
                                    #particle.scaling = Vector(0.9,0.9,0.9)
                                    self.hitParticles.append(particle)
                                    self.selectParticle(particle)
                                    #print str(id(particle))+'hit'
                                    #print self.hitParticles
                            # If click places other than particles in non multiSelectMode, deselect all
                            if not self.hitParticles and not self.multiSelectMode:
                                self.deselectAll()
                    self.lastClickPos = clickPos
                    self.lastClickTime = currentTime
                if event.button == 3:
                    if self.currentLevel > 0:
                        items = self.currentParentParticleID.split(':')
                        items.pop()
                        self.currentParentParticleID = ':'.join(items)
                        self.gotoDisplayLevel(-1)
                    else:
                        print "Warning: The first hierarchy level has reached!"
                if event.button == 4:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        posVector.z -= 1
                        particle.pos = posVector.toTuple()
                if event.button == 5:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        posVector.z += 1
                        particle.pos = posVector.toTuple()
            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    for particle in self.hitParticles:
                        self.grabbed = False
                        particle.oldpoint = None
                        #particle.scaling = Vector(1,1,1)
                        self.hitParticles.pop(
                            self.hitParticles.index(particle))
                        #print self.hitParticles
            if event.type == pygame.MOUSEMOTION:
                if not self.rotationMode and self.grabbed:
                    for particle in self.hitParticles:
                        try:
                            if particle.oldpoint is not None:
                                #print particle.pos
                                diff = newpoint - particle.oldpoint
                                amount = (diff.x, diff.y)
                                particle.pos = (Vector(*particle.pos) +
                                                Vector(*amount)).toTuple()
                        except NameError:
                            pass

                        # Redraw the link so that the link can move with the particle
                        for p in particle.bondedFrom:
                            p.needRedraw = True
                elif self.rotationMode:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles

                    centrePoint = Vector()
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAnglex = float(event.rel[1]) * math.pi / 180
                    dAngley = -float(event.rel[0]) * math.pi / 180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (
                            relativePosVector.z * relativePosVector.z +
                            relativePosVector.y * relativePosVector.y)**0.5
                        newAnglex = (math.atan2(relativePosVector.z,
                                                relativePosVector.y) + dAnglex)
                        particle.pos = (posVector.x,
                                        radius * math.cos(newAnglex) +
                                        centrePoint.y,
                                        radius * math.sin(newAnglex) +
                                        centrePoint.z)
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (
                            relativePosVector.z * relativePosVector.z +
                            relativePosVector.x * relativePosVector.x)**0.5
                        newAngley = (math.atan2(relativePosVector.z,
                                                relativePosVector.x) + dAngley)
                        particle.pos = (radius * math.cos(newAngley) +
                                        centrePoint.x, posVector.y,
                                        radius * math.sin(newAngley) +
                                        centrePoint.z)
                        particle.drotation.y = float(event.rel[0])
                        particle.drotation.x = float(event.rel[1])
                        particle.drotation %= 360

            try:
                for particle in self.hitParticles:
                    particle.oldpoint = newpoint
            except NameError:
                pass

            # Keyboard events handling
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.quit()
                elif event.key == pygame.K_BACKSPACE:
                    if self.currentLevel > 0:
                        items = self.currentParentParticleID.split(':')
                        items.pop()
                        self.currentParentParticleID = ':'.join(items)
                        self.gotoDisplayLevel(-1)
                    else:
                        print "Warning: The first hierarchy level has reached!"
                elif event.key == pygame.K_RETURN:
                    if self.currentLevel < self.maxLevel and len(
                            self.selectedParticles) == 1:
                        hasChildParticles = False
                        for particle in self.physics.particles:
                            if particle.ID.find(
                                    self.selectedParticles[0].ID
                            ) == 0 and particle.ID != self.selectedParticles[
                                    0].ID:
                                hasChildParticles = True
                                break
                        if hasChildParticles:
                            self.currentParentParticleID = self.selectedParticles[
                                0].ID
                            self.gotoDisplayLevel(1)
                        else:
                            print 'Warning: The particle you double-clicked has no children!'
                    else:
                        if self.currentLevel == self.maxLevel:
                            print "Warning: max hierarchy level has reached!"
                        if len(self.selectedParticles) != 1:
                            print "Tips: To extend a node, please click to select the node (only one) you want to extend first."

                elif event.key == pygame.K_LSHIFT or event.key == pygame.K_RSHIFT:
                    self.multiSelectMode = True
                elif event.key == pygame.K_LCTRL or event.key == pygame.K_RCTRL:
                    self.rotationMode = True
                elif event.key == pygame.K_PAGEUP:
                    self.display.viewerposition.z -= 0.5
                elif event.key == pygame.K_PAGEDOWN:
                    self.display.viewerposition.z += 0.5
                elif event.key == pygame.K_w:
                    self.display.viewerposition.y += 0.5
                elif event.key == pygame.K_s:
                    self.display.viewerposition.y -= 0.5
                elif event.key == pygame.K_a:
                    self.display.viewerposition.x -= 0.5
                elif event.key == pygame.K_d:
                    self.display.viewerposition.x += 0.5
                elif event.key == pygame.K_UP:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector()
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = -20 * math.pi / 180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (
                            relativePosVector.z * relativePosVector.z +
                            relativePosVector.y * relativePosVector.y)**0.5
                        newAngle = (math.atan2(relativePosVector.z,
                                               relativePosVector.y) + dAngle)
                        particle.pos = (posVector.x,
                                        radius * math.cos(newAngle) +
                                        centrePoint.y,
                                        radius * math.sin(newAngle) +
                                        centrePoint.z)
                        particle.drotation = Vector(dAngle * 180 / math.pi, 0,
                                                    0)
                elif event.key == pygame.K_DOWN:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector()
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = 20 * math.pi / 180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (
                            relativePosVector.z * relativePosVector.z +
                            relativePosVector.y * relativePosVector.y)**0.5
                        newAngle = (math.atan2(relativePosVector.z,
                                               relativePosVector.y) + dAngle)
                        particle.pos = (posVector.x,
                                        radius * math.cos(newAngle) +
                                        centrePoint.y,
                                        radius * math.sin(newAngle) +
                                        centrePoint.z)
                        particle.drotation = Vector(dAngle * 180 / math.pi, 0,
                                                    0)
                elif event.key == pygame.K_LEFT:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector()
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = 20 * math.pi / 180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (
                            relativePosVector.z * relativePosVector.z +
                            relativePosVector.x * relativePosVector.x)**0.5
                        newAngle = (math.atan2(relativePosVector.z,
                                               relativePosVector.x) + dAngle)
                        particle.pos = (radius * math.cos(newAngle) +
                                        centrePoint.x, posVector.y,
                                        radius * math.sin(newAngle) +
                                        centrePoint.z)
                        particle.drotation = Vector(0, -dAngle * 180 / math.pi,
                                                    0)
                elif event.key == pygame.K_RIGHT:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector()
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = -20 * math.pi / 180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (
                            relativePosVector.z * relativePosVector.z +
                            relativePosVector.x * relativePosVector.x)**0.5
                        newAngle = (math.atan2(relativePosVector.z,
                                               relativePosVector.x) + dAngle)
                        particle.pos = (radius * math.cos(newAngle) +
                                        centrePoint.x, posVector.y,
                                        radius * math.sin(newAngle) +
                                        centrePoint.z)
                        particle.drotation = Vector(0, -dAngle * 180 / math.pi,
                                                    0)
                elif event.key == pygame.K_COMMA:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector()
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = 20 * math.pi / 180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (
                            relativePosVector.x * relativePosVector.x +
                            relativePosVector.y * relativePosVector.y)**0.5
                        newAngle = (math.atan2(relativePosVector.y,
                                               relativePosVector.x) + dAngle)
                        particle.pos = (radius * math.cos(newAngle) +
                                        centrePoint.x,
                                        radius * math.sin(newAngle) +
                                        centrePoint.y, posVector.z)
                        particle.drotation = Vector(0, 0,
                                                    dAngle * 180 / math.pi)
                elif event.key == pygame.K_PERIOD:
                    if self.selectedParticles:
                        particles = self.selectedParticles
                    else:
                        particles = self.currentDisplayedPhysics.particles
                    centrePoint = Vector()
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        centrePoint += posVector
                    centrePoint /= len(particles)
                    dAngle = -20 * math.pi / 180
                    for particle in particles:
                        posVector = Vector(*particle.pos)
                        relativePosVector = posVector - centrePoint
                        radius = (
                            relativePosVector.x * relativePosVector.x +
                            relativePosVector.y * relativePosVector.y)**0.5
                        newAngle = (math.atan2(relativePosVector.y,
                                               relativePosVector.x) + dAngle)
                        particle.pos = (radius * math.cos(newAngle) +
                                        centrePoint.x,
                                        radius * math.sin(newAngle) +
                                        centrePoint.y, posVector.z)
                        particle.drotation = Vector(0, 0,
                                                    dAngle * 180 / math.pi)

            #print self.display.viewerposition
            # Scroll if self.display.viewerposition changes
            if self.display.viewerposition.copy() != self.viewerOldPos:
                self.scroll()
                self.viewerOldPos = self.display.viewerposition.copy()
#                for particle in self.currentDisplayedPhysics.particles:
#                    particle.oldpoint = None
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LSHIFT or event.key == pygame.K_RSHIFT:
                    self.multiSelectMode = False
                elif event.key == pygame.K_LCTRL or event.key == pygame.K_RCTRL:
                    self.rotationMode = False
Пример #27
0
    def main(self):
        """\
 
        
        """
        # create display request for itself
        self.size = Vector(0, 0, 0)
        disprequest = {
            "OGL_DISPLAYREQUEST": True,
            "objectid": id(self),
            "callback": (self, "callback"),
            "events": (self, "events"),
            "size": self.size
        }
        # send display request
        self.send(disprequest, "display_signal")
        # wait for response on displayrequest and get identifier of the viewer
        while not self.dataReady("callback"):
            yield 1
        self.identifier = self.recv("callback")

        self.addListenEvents([
            pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION,
            pygame.KEYDOWN, pygame.KEYUP
        ])
        pygame.key.set_repeat(100, 100)

        while True:
            # process incoming messages
            if self.dataReady("inbox"):
                message = self.recv("inbox")
                self.doCommand(message)
                #print message

                # wait for response on displayrequest and get identifier of the particle
                if self.isNewNode:
                    while not self.dataReady("callback"):
                        yield 1
                    self.physics.particles[-1].identifier = self.recv(
                        "callback")
                    self.isNewNode = False
            else:
                self.lastIdleTime = 0

            yield 1

            if self.lastIdleTime + 1.0 < time.time():
                #print [particle.pos for particle in self.physics.particles]
                avoidedList = []
                avoidedList.extend(self.hitParticles)
                avoidedList.extend(self.selectedParticles)

                #self.currentDisplayedPhysics.particleDict[ident].breakAllBonds()
                self.currentDisplayedPhysics.particles = []
                if self.physics.particles != []:
                    for particle in self.physics.particles:
                        if self.currentParentParticleID == '':
                            if ':' not in particle.ID:
                                self.currentDisplayedPhysics.add(particle)
                                particle.oldpos = particle.initialpos
                        elif particle.ID.find(
                                self.currentParentParticleID
                        ) == 0 and particle.ID.count(':') == self.currentLevel:
                            self.currentDisplayedPhysics.add(particle)
                            particle.oldpos = particle.initialpos
                self.currentDisplayedPhysics.run(self.simCyclesPerRedraw,
                                                 avoidedList=avoidedList)
                #print [particle.pos for particle in self.physics.particles]

                # Draw particles if new or updated
                for particle in self.currentDisplayedPhysics.particles:
                    if particle.needRedraw:
                        self.drawParticles(particle)
                        #particle.needRedraw = False

                self.handleEvents()

                # Perform transformation
                for particle in self.currentDisplayedPhysics.particles:
                    transform_update = particle.applyTransforms()
                    if transform_update is not None:
                        self.send(transform_update, "display_signal")
                        #print transform_update
                        #print [particle.pos for particle in self.physics.particles]

                self.lastIdleTime = time.time()
            else:
                yield 1
            if self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, Axon.Ipc.shutdownMicroprocess):
                    self.quit(msg)
Пример #28
0
class CheckersInteractor(Interactor):
    def __init__(self, **argd):
        super(CheckersInteractor, self).__init__(**argd)

        self.addInbox("position")
        self.addOutbox("movement")

        self.liftheight = argd.get("liftheight", 0.2)
        self.colour = argd.get("colour")

        self.grabbed = False
        self.position = None
        self.oldpoint = None
        self.lastValidPos = None

        if self.nolink == False:
            self.link((self, "movement"), (self.target, "rel_position"))
            self.link((self.target, "position"), (self, "position"))

    def setup(self):
        self.addListenEvents(
            [pygame.MOUSEMOTION, pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP])

    def handleEvents(self):
        while self.dataReady("events"):
            event = self.recv("events")

            if self.position is not None:
                if event.type == pygame.MOUSEBUTTONDOWN or pygame.MOUSEMOTION and self.grabbed:
                    p1 = self.position.copy()
                    p1.x += 10
                    p2 = self.position.copy()
                    p2.y += 10
                    z = Intersect.ray_Plane(event.viewerposition,
                                            event.direction,
                                            [self.position, p1, p2])
                    newpoint = event.direction * z

                if event.type == pygame.MOUSEBUTTONDOWN and self.identifier in event.hitobjects:
                    if event.button == 1:
                        self.grabbed = True
                        self.send((0, 0, self.liftheight), "movement")

                if event.type == pygame.MOUSEBUTTONUP:
                    if event.button == 1 and self.grabbed:
                        self.grabbed = False
                        # place piece in the middle of a black field
                        alignedpos = self.position.copy()
                        alignedpos.x = floor(alignedpos.x) + 0.5
                        alignedpos.y = floor(alignedpos.y) + 0.5

                        diff = alignedpos - self.position
                        self.send((diff.x, diff.y, -self.liftheight),
                                  "movement")

                        self.position = alignedpos

                        fr = (floor(self.lastValidPos.x) + 4,
                              floor(self.lastValidPos.y) + 4)
                        to = (floor(alignedpos.x) + 4, floor(alignedpos.y) + 4)
                        self.send(
                            {
                                "PLACEMENT": True,
                                "from": fr,
                                "to": to,
                                "colour": self.colour,
                                "objectid": id(self)
                            }, "outbox")

                if event.type == pygame.MOUSEMOTION:
                    if self.grabbed == True:
                        if self.oldpoint is not None:
                            diff = newpoint - self.oldpoint
                            diff.z = 0
                            self.send(diff.toTuple(), "movement")

                try:
                    self.oldpoint = newpoint
                except NameError:
                    pass

    def frame(self):
        while self.dataReady("position"):
            self.position = Vector(*self.recv("position"))
            if self.lastValidPos is None:
                self.lastValidPos = self.position.copy()

        while self.dataReady("inbox"):

            msg = self.recv("inbox")
            if msg == "ACK":
                self.lastValidPos = self.position.copy()
            elif msg == "INVALID":
                diff = self.lastValidPos - self.position
                diff.z = 0
                self.send(diff.toTuple(), "movement")
Пример #29
0
    def draw(self):
        """Draw CUBOID Particle."""
        hs = self.size / 2

        # draw faces
        glBegin(GL_QUADS)
        glColor4f(self.sidecurcolour[0] / 256.0, self.sidecurcolour[1] / 256.0,
                  self.sidecurcolour[2] / 256.0, 0.5)

        glVertex3f(hs.x, hs.y, hs.z)
        glVertex3f(hs.x, -hs.y, hs.z)
        glVertex3f(hs.x, -hs.y, -hs.z)
        glVertex3f(hs.x, hs.y, -hs.z)

        glVertex3f(-hs.x, hs.y, hs.z)
        glVertex3f(-hs.x, -hs.y, hs.z)
        glVertex3f(-hs.x, -hs.y, -hs.z)
        glVertex3f(-hs.x, hs.y, -hs.z)

        glVertex3f(hs.x, hs.y, hs.z)
        glVertex3f(-hs.x, hs.y, hs.z)
        glVertex3f(-hs.x, hs.y, -hs.z)
        glVertex3f(hs.x, hs.y, -hs.z)

        glVertex3f(hs.x, -hs.y, hs.z)
        glVertex3f(-hs.x, -hs.y, hs.z)
        glVertex3f(-hs.x, -hs.y, -hs.z)
        glVertex3f(hs.x, -hs.y, -hs.z)
        glEnd()

        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texID)
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)

        glBegin(GL_QUADS)
        # back plane
        glTexCoord2f(self.tex_w, 1.0 - self.tex_h)
        glVertex3f(hs.x, hs.y, -hs.z)
        glTexCoord2f(0.0, 1.0 - self.tex_h)
        glVertex3f(-hs.x, hs.y, -hs.z)
        glTexCoord2f(0.0, 1.0)
        glVertex3f(-hs.x, -hs.y, -hs.z)
        glTexCoord2f(self.tex_w, 1.0)
        glVertex3f(hs.x, -hs.y, -hs.z)
        # front plane
        glTexCoord2f(0.0, 1.0 - self.tex_h)
        glVertex3f(-hs.x, -hs.y, hs.z)
        glTexCoord2f(self.tex_w, 1.0 - self.tex_h)
        glVertex3f(hs.x, -hs.y, hs.z)
        glTexCoord2f(self.tex_w, 1.0)
        glVertex3f(hs.x, hs.y, hs.z)
        glTexCoord2f(0.0, 1.0)
        glVertex3f(-hs.x, hs.y, hs.z)

        glEnd()

        glDisable(GL_TEXTURE_2D)

        # Draw links
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadMatrixf(self.linkTransform.getMatrix())
        for p in self.bondedTo:
            glBegin(GL_LINES)
            glVertex3f(*self.initialpos.toTuple())
            glVertex3f(*(Vector(*p.pos) - Vector(*self.pos)).toTuple())
            glEnd()
        glPopMatrix()
Пример #30
0
 def __init__(self, **argd):
     """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
     super(SphereParticle3D, self).__init__(**argd)
     self.drotation = Vector(0, 0, 90)
Пример #31
0
    def main(self):
        """Main loop."""
        # Make display request for event listening purpose
        self.size = Vector(0, 0, 0)
        disprequest = {
            "OGL_DISPLAYREQUEST": True,
            "objectid": id(self),
            "callback": (self, "callback"),
            "events": (self, "events"),
            "size": self.size
        }
        # send display request
        self.send(disprequest, "display_signal")
        # Wait for response on displayrequest and get identifier of the viewer
        while not self.dataReady("callback"):
            yield 1
        self.identifier = self.recv("callback")

        self.initialiseComponent()

        while True:
            # Process incoming messages
            if self.dataReady("inbox"):
                message = self.recv("inbox")
                self.doCommand(message)

                # Wait for response on displayrequest and get identifier of the particle
                if self.isNewNode:
                    while not self.dataReady("callback"):
                        yield 1
                    self.physics.particles[-1].identifier = self.recv(
                        "callback")
                    self.isNewNode = False
            else:
                self.lastIdleTime = 0

            yield 1

            if self.lastIdleTime + 1.0 < time.time():
                #Freeze selected particles so that they are not subject to the physics law
                for particle in self.selectedParticles:
                    particle.freeze()
                # Do interaction between particles
                self.currentDisplayedPhysics.run(self.simCyclesPerRedraw)
                # Unfreeze selected particles
                for particle in self.selectedParticles:
                    particle.unFreeze()

                # Draw particles if new or updated
                for particle in self.currentDisplayedPhysics.particles:
                    if particle.needRedraw:
                        self.drawParticles(particle)

                self.handleEvents()

                # Perform transformation
                for particle in self.currentDisplayedPhysics.particles:
                    transform_update = particle.applyTransforms()
                    if transform_update is not None:
                        self.send(transform_update, "display_signal")

                self.lastIdleTime = time.time()
            else:
                yield 1
            if self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, Axon.Ipc.shutdownMicroprocess):
                    self.quit(msg)
Пример #32
0
 def handleMouseEvents(self, event):
     """Handle mouse events."""
     if event.type == pygame.MOUSEBUTTONDOWN or pygame.MOUSEMOTION and self.grabbed:
         if not self.rotationMode:
             for particle in self.hitParticles:
                 p1 = Vector(*particle.pos).copy()
                 p1.x += 10
                 p2 = Vector(*particle.pos).copy()
                 p2.y += 10
                 # Get the position of mouse
                 z = Intersect.ray_Plane(Vector(0,0,0), event.direction, [Vector(*particle.pos)-Vector(0,0,self.display.viewerposition.z), p1-Vector(0,0,self.display.viewerposition.z), p2-Vector(0,0,self.display.viewerposition.z)])
                 newpoint = event.direction * z
     if event.type == pygame.MOUSEBUTTONDOWN:
         if event.button == 1:
             # Handle double click
             clickPos = event.pos
             currentTime = time.time()
             elapsedTime = currentTime - self.lastClickTime
             # If it's a double-click
             if clickPos == self.lastClickPos and elapsedTime<self.dClickRes:
                 self.gotoDisplayLevel(1)
             else: # Single click
                 if not self.rotationMode: # Select particle
                     for particle in self.currentDisplayedPhysics.particles:
                         if particle.identifier in event.hitobjects:
                             self.grabbed = True
                             self.hitParticles.append(particle)
                             self.selectParticle(particle)
                     # If click places other than particles in non multiSelectMode, deselect all
                     if not self.hitParticles and not self.multiSelectMode:
                         self.deselectAll()
             self.lastClickPos = clickPos
             self.lastClickTime = currentTime
         elif event.button == 3: # Right-clicked
             self.gotoDisplayLevel(-1)
         elif event.button == 4: # Scrolled-up: zoom out
             if self.selectedParticles:
                 particles = self.selectedParticles
             else:
                 particles = self.currentDisplayedPhysics.particles
             for particle in particles:
                 posVector = Vector(*particle.pos)
                 posVector.z -= 1
                 particle.pos = posVector.toTuple()
         elif event.button == 5: # Scrolled-down: zoom in
             if self.selectedParticles:
                 particles = self.selectedParticles
             else:
                 particles = self.currentDisplayedPhysics.particles
             for particle in particles:
                 posVector = Vector(*particle.pos)
                 posVector.z += 1
                 particle.pos = posVector.toTuple()
     if event.type == pygame.MOUSEBUTTONUP:
         if event.button == 1:  
             for particle in self.hitParticles:
                 self.grabbed = False
                 particle.oldpoint = None
                 self.hitParticles.pop(self.hitParticles.index(particle))
     if event.type == pygame.MOUSEMOTION: 
         if not self.rotationMode and self.grabbed: # Drag particles
             for particle in self.hitParticles:
                 try:
                     if particle.oldpoint is not None:
                         diff = newpoint-particle.oldpoint
                         amount = (diff.x, diff.y)
                         particle.pos = (Vector(*particle.pos)+Vector(*amount)).toTuple()
                 except NameError: pass
                 
                 # Redraw the link so that the link can move with the particle
                 for p in particle.bondedFrom:
                     p.needRedraw = True
         elif self.rotationMode: # Rotate particles
             dAnglex = float(event.rel[1])
             dAngley = -float(event.rel[0])
             self.rotateParticles(self.selectedParticles, (dAnglex,dAngley,0))
     
     try:
         for particle in self.hitParticles:
             particle.oldpoint = newpoint                    
     except NameError: pass    
Пример #33
0
 def handleEvents(self):
     while self.dataReady("events"):
         event = self.recv("events")
         if event.type == pygame.MOUSEBUTTONDOWN and self.identifier in event.hitobjects:
             self.rotation += Vector(0, 0, 10)
             self.rotation %= 360