Пример #1
0
    def get_heightmap_tex(self, size, filename = None):
        """Generate texture of map
        """
        mod = self.world_size / size
        image = PNMImage(size, size)
        for x in xrange(size):
            for y in xrange(size):
                px = x * mod
                py = y * mod
                height = self[px, py]
                color = height / 50
                r = 0
                g = 0
                b = 0
                if color > 255:
                    color = 255
                if color < 0:
                    color = abs(color)
                    b = color
                else:
                    g = color
                image.setPixel(x, y, (r, g, b))

        if filename != None:
            image.write(filename)

        #for x in xrange(-1, 2):
            #for y in xrange(-1, 2):
               #image.setPixel(int(world.chunks_map.charX)+x, int(world.chunks_map.charY)+y, (255, 0, 0))

        texture = Texture()
        texture.load(image)
        return texture
Пример #2
0
	def makeSlopeMap(self):
		
		self.slopeMap = PNMImage()
		if SAVED_SLOPE_MAPS:
			fileName = "maps/slope/" + self.name + ".png"
			if self.slopeMap.read(Filename(fileName)):
				logging.info( "read slopemap from " + fileName)
				return
				
		self.slopeMap = PNMImage(self.terrain.heightMapSize, self.terrain.heightMapSize)
		self.slopeMap.makeGrayscale()
		self.slopeMap.setMaxval(65535)
		
		size = self.slopeMap.getYSize()
		getNormal = self.getNormal
		setGray = self.slopeMap.setGray
		
		for x in range(size):
			for y in range(size):
				#note getNormal works at the same resolution as the heightmap
				normal = getNormal(x, y)
				# feed pixel into image
				# why is it necessary to invert the y axis I wonder?
				#logging.info( normal)
				normal.z /= self.terrain.getSz()
				normal.normalize()
				slope = 1.0 - normal.dot(Vec3(0, 0, 1))
				setGray(x, y, slope)
				
		if SAVED_SLOPE_MAPS:
			fileName = "maps/slope/" + self.name + ".png"
			logging.info( "saving slopemap to " + fileName)
			self.slopeMap.write(Filename(fileName))
Пример #3
0
 def loadFlatQuad(self, fullFilename):
     cm = CardMaker("cm-%s" % fullFilename)
     cm.setColor(1.0, 1.0, 1.0, 1.0)
     aspect = base.camLens.getAspectRatio()
     htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
     htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)
     cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
     bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1)
     bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)
     cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))
     card = cm.generate()
     quad = NodePath(card)
     jpgFile = PNMImage(WEB_WIDTH, WEB_HEIGHT)
     smallerJpgFile = PNMImage()
     readFile = smallerJpgFile.read(Filename(fullFilename))
     if readFile:
         jpgFile.copySubImage(smallerJpgFile, 0, 0)
         guiTex = Texture("guiTex")
         guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
         guiTex.setMinfilter(Texture.FTLinear)
         guiTex.load(jpgFile)
         guiTex.setWrapU(Texture.WMClamp)
         guiTex.setWrapV(Texture.WMClamp)
         ts = TextureStage("webTS")
         quad.setTexture(ts, guiTex)
         quad.setTransparency(0)
         quad.setTwoSided(True)
         quad.setColor(1.0, 1.0, 1.0, 1.0)
         result = quad
     else:
         result = None
     Texture.setTexturesPower2(1)
     return result
Пример #4
0
    def _createMapTextureCard(self):
        mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION)
        mapImage.fill(*self._bgColor)
        fgColor = VBase4D(*self._fgColor)
        for x in xrange(self._mazeHeight):
            for y in xrange(self._mazeWidth):
                if self._mazeCollTable[y][x] == 1:
                    ax = float(x) / self._mazeWidth * MAP_RESOLUTION
                    invertedY = self._mazeHeight - 1 - y
                    ay = float(invertedY) / self._mazeHeight * MAP_RESOLUTION
                    self._drawSquare(mapImage, int(ax), int(ay), 10, fgColor)

        mapTexture = Texture('mapTexture')
        mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba)
        mapTexture.setMinfilter(Texture.FTLinear)
        mapTexture.load(mapImage)
        mapTexture.setWrapU(Texture.WMClamp)
        mapTexture.setWrapV(Texture.WMClamp)
        mapImage.clear()
        del mapImage
        cm = CardMaker('map_cardMaker')
        cm.setFrame(-1.0, 1.0, -1.0, 1.0)
        map = self.attachNewNode(cm.generate())
        map.setTexture(mapTexture, 1)
        return map
Пример #5
0
    def make_blocks_texmap(self):
        images = []
        # 0 - sand
        images.append(PNMImage('res/textures/{0}sand.png'.format(
                                        Config().tex_suffix)))
        # 1 - land
        images.append(PNMImage('res/textures/{0}land.png'.format(
                                        Config().tex_suffix)))
        # 2 - low_mount
        images.append(PNMImage("res/textures/{0}low_mount.png".format(
                                        Config().tex_suffix)))
        # 3 - mid_mount
        images.append(PNMImage("res/textures/{0}mid_mount.png".format(
                                        Config().tex_suffix)))
        # 4 - high_mount
        images.append(PNMImage("res/textures/{0}high_mount.png".format(
                                        Config().tex_suffix)))
        d = images[0].getReadXSize()
        # 16 x 16 textures
        size = d * self.map_size
        image_all = PNMImage(size, size)
        n = 0
        for i in xrange(0, size, d):
            for j in xrange(0, size, d):
                image_all.copySubImage(images[n], j, i)
                n += 1
                if n >= len(images):
                    break
            if n >= len(images):
                break

        self['world_blocks'] = Texture()
        self['world_blocks'].load(image_all)
        self['world_blocks'].setMagfilter(Texture.FTLinearMipmapLinear)
        self['world_blocks'].setMinfilter(Texture.FTLinearMipmapLinear)
Пример #6
0
    def paintEvent(self,  event):

        screenData = StringStream() # Used to pass the data as a string
        screenImage = PNMImage() # Converts the texture data into a format usable with Qt

        if self.pandaTexture.hasRamImage():
            print "Should draw yes?"
            self.pandaTexture.store(screenImage)
            screenImage.write(screenData, "test.ppm")
            self.paintPixmap.loadFromData(screenData.getData())
            self.paintSurface.setPixmap(self.paintPixmap)
Пример #7
0
	def __init__(self, terrain, x, y):
		"""Builds a Tile for the terrain at input coordinates.
		
		Important settings are used directly from the terrain.
		This allows for easier setting changes and reduces memory overhead.
		x and y parameters give the appropriate world coordinates of this tile.
		
		"""
		
		self.terrain = terrain
		self.xOffset = x
		self.yOffset = y
		self.heightMapDetail = 1 # higher means greater detail
		
		self.name = "ID" + str(terrain.id) + "_X" + str(x) + "_Y" + str(y)
		GeoMipTerrain.__init(self, name=self.name)
		
		self.image = PNImage()
		
		#self.setAutoFlatten(GeoMipTerrain.AFMOff
		self.setFocalPoint(self.terrain.focus)
		self.setAutoFlatten(GeoMipTerrain.AFMOff)
		self.getRoot().setPos(x, y, 0)
		if self.terrain.bruteForce:
			GeoMipTerrain.setBruteForce(self, True)
			GeoMipTerrain.setBlockSize(self, self.terrain.heightMapSize * self.heightMapDetail)
		else:
			GeoMipTerrain.setBlockSize(self, self.terrain.blockSize/2)
			#self.setBorderStitching(1)
			self.setNear(self.terrain.near)
			self.setFar(self.terrain.far)
Пример #8
0
    def noiseTaskVerySmart(self, Task=None):
        if Task == None:
            o = 0
        else:
            o = Task.frame
        p = Perlin.Perlin(numberOfOctaves=1, smooth=False, seed=0)
        freq = 2 ** o
        self.oldImage = self.myImage
        self.myImage = PNMImage(freq + 1, freq + 1)
        self.myImage.makeGrayscale()
        self.myImage.gaussianFilterFrom(1.0, self.oldImage)

        for x in range(0, freq + 1):
            for y in range(0, freq + 1):
                self.myImage.setGray(
                    x, y, self.myImage.getGray(x, y) + p.intNoise2D(x * freq, y * freq) * (0.75 ** o) / 2
                )

        self.myTexture.load(self.myImage)
        if Task != None:
            if freq < self.size:
                return Task.cont
            else:
                print time() - self.startTime
                return Task.done
def createPickingImage(size):
  ''' create a picking image with uniq colors for each point in the image
  '''
  image = PNMImage(*size)
  for x in xrange(size[0]):
    for y in xrange(size[1]):
      r = x % 256
      g = y % 256
      b = (x // 256) + (y//256) * 16
      image.setXelVal(x,y,r,g,b)
  
  # Reverse way is:
  #    tx = r + ((b%16)*256)
  #    ty = g + ((b//16)*256)
  imageFilename = 'data/textures/index-%i-%i.png' % (size[0], size[1])
  image.write(Filename(imageFilename))
Пример #10
0
 def get_map_2d_tex(self, map2d, factor = 1):
     """Generate texture for map2d, factor - for size [size / factor]
     """
     size = map2d.size / factor
     image = PNMImage(size, size)
     for x in xrange(size):
         for y in xrange(size):
             px = x * factor
             py = y * factor
             if map2d[(px, py)] <= map2d.water_z:
                 image.setPixel(x, y, (0, 0, 100))
             else:
                 image.setPixel(x, y, (0, 100, 0))
     texture = Texture()
     texture.load(image)
     return texture
Пример #11
0
	def setupHeightfield( self ):
		# Prep terrain textures
		#coverTextureFile = "data/textures/ground/green.jpg"
		#self.mCoverTexture = loader.loadTexture(coverTextureFile)
		
		# Setup heightfield
		self.mHeightFieldTesselator = HeightfieldTesselator("Heightfield")
		#fName = "data/textures/ground/heightfield.png"
		#self.mHeightFieldTesselator.setPolyCount(10000)
		#fileObj = Filename(fName)
		self.mTerrainVScale = self.mTerrainUScale = 1.0/1024.0
			
		myImage=PNMImage(256,256)
		myImage.makeGrayscale()
	
		p = Perlin(numberOfOctaves = 10, persistance = 0.65, smooth = False)
		for y in range(0,256):
			for x in range(0,256):
				i = p.noise2D(float(x)/256.0,float(y)/256.0)
				myImage.setGray(x, y, abs(i))
	
		bigImage=PNMImage(1024, 1024)
		bigImage.gaussianFilterFrom(1.0, myImage)
		fileObj = Filename("data/textures/ground/myHeightfield.png")
		bigImage.write(fileObj)
		#myTexture = Texture()
		#myTexture.load(bigImage)
		

		
		self.mHeightFieldTesselator.setHeightfield(fileObj)
		self.mTerrainHeight = MAPSIZE/10
		self.mHeightFieldTesselator.setVerticalScale(self.mTerrainHeight)
		self.mHorizontalScale = MAPSIZE/1024.0
		self.mHeightFieldTesselator.setHorizontalScale(self.mHorizontalScale)
		self.mHeightFieldNode = None

#		self.tex0 = loader.loadTexture( 'models/textures/ground/schachbrett.png' )
		self.tex0 = loader.loadTexture( 'data/textures/ground/mud-tile.png' )
		#self.tex1 = loader.loadTexture( 'data/models/textures/ground/green.jpg' )
		#self.tex2 = loader.loadTexture( 'data/models/textures/ground/grey-green-leaves.jpg' )

		#self.ts0 = TextureStage( 'dirt' )
		#self.ts1 = TextureStage( 'fungus' )
		#self.ts2 = TextureStage( 'grass' )
		
		self.updateHeightField()
Пример #12
0
def grassTexture(imgSize=(256,256)):
    """Return a green, 'grassy' texture (PNMImage) of the given image size,
    produced using 2D Perlin noise."""

    # Initialuse the PNMImage object
    img = PNMImage(*imgSize)

    # Initalise 4 PerlinNoise2 objects to produce noise at different scales
    noise1 = PerlinNoise2()
    noise1.setScale(2.0)
    noise2 = PerlinNoise2()
    noise2.setScale(5.0)
    noise3 = PerlinNoise2()
    noise3.setScale(0.25)
    noise4 = PerlinNoise2()
    noise4.setScale(0.125)

    # For each pixel in the image, set the red and blue values of the pixel to
    # constant values, and set the green value of the pixel using all 4
    # PerlinNoise2 objects.
    red = 0.125 # Colour values in PNMImage are doubles in the range [0.0,1.0]
    blue = 0.0625
    for x in xrange(imgSize[0]):
        for y in xrange(imgSize[1]):
            img.setRed(x,y,red)
            img.setBlue(x,y,blue)
            pos = Vec2(1.0/32*x, 1.0/32*y)
            img.setGreen(x,y,(0.5 + noise1(pos)*0.0625 + noise2(pos)*0.0625 +
                              noise3(pos)*0.125 + noise4(pos)*0.0625))

    return img
Пример #13
0
def generate_map_texture(map_tree, factor):
    map_world = map_tree.map3d
    size = map_world.size / factor
    image = PNMImage(size, size)
    #image.fill(0,0,0)
    for x in xrange(size):
        for y in xrange(size):
            px = x * factor
            py = y * factor
            if map_world[(px, py)] <= map_world.water_z:
                image.setPixel(x, y, (0, 0, 100))
            else:
                image.setPixel(x, y, (0, 100, 0))
    char_x, char_y, char_z = map_tree.coords
    char_x = char_x / factor
    char_y = char_y / factor
    image.setPixel(char_x, char_y, (255, 0, 0))
    #if factor>2:
        #image.setPixel(char_x, char_y, (255, 0, 0))
    #else:
        #for x in xrange(char_x - 1, char_x+2):
            #cx = x
            #if cx > size-1: cx = size-1
            #if cx < 0: cx = 0
            #for y in xrange(char_y - 1, char_y+2):
                #cy = y
                #if cy > size-1: cy = size-1
                #if cy < 0: cy = 0
                #image.setPixel(cx, cy, (255, 0, 0))
    texture = Texture()
    texture.load(image)
    return texture
Пример #14
0
def getWaterSurface(manager, polycount=50000, size=(512, 512)):
    # Get cache directory...
    cacheDir = manager.get("paths").getConfig().find("cache").get("path")

    # Check if the data required already exists...
    cachedWaterSurface = "%s/plane-%dx%d-%dk.bam" % (cacheDir, size[0], size[1], int(polycount / 1000))
    try:
        return loader.loadModel(cachedWaterSurface)
    except:
        pass

    # Make cache directory if needed...
    if not os.path.isdir(cacheDir):
        os.mkdir(cacheDir)

    # Put in an image...
    img = PNMImage(*size)
    img.makeGrayscale()
    img.fill(0, 0, 0)
    img.write("%s/black-%dx%d.png" % (cacheDir, size[0], size[1]))

    # Put in a mesh...
    ht = HeightfieldTesselator("plane")
    assert ht.setHeightfield(Filename("%s/black-%dx%d.png" % (cacheDir, size[0], size[1])))
    ht.setPolyCount(polycount)
    ht.setFocalPoint(size[0] * 0.5, size[1] * 0.5)
    node = ht.generate()
    node.setPos(-0.5 * size[0], 0.5 * size[1], 0)
    node.flattenLight()
    node.writeBamFile(cachedWaterSurface)

    return node
Пример #15
0
	def run(self):
		size = 256
		pb = Perlin.Perlin( persistance = 0.500, smooth = False, seed = random.random() )
		myImage2 = pb.imgNoise2D(size,True)
		
		myImage=PNMImage(size,size)
		myImage.makeGrayscale()
		myImage.setMaxval( (2<<16)-1 )
		myImage.fill(0.5)
		line = lineDrawer.LineDrawer(myImage,(42,180),(13,253),13)
		
		for x in range(size):
			for y in range(size):
				gray = myImage.getGray(x,y) - 0.5
				gray = gray + (myImage2.getGray(x,y) - 0.5)
				myImage.setGray(x,y,gray + 0.5)
		

		self.myTexture.load(myImage)
Пример #16
0
    def draw_map(self, heightmap, height_modifier):
        """Draws the heightmap in the image
       The range of values is assumed to be 0.0 to 1.0 in a 2D, square array.
       The range is converted to grayscale values of 0 to 255.
       A heightmap modifier is added to boost height differences.
    """
        # get size
        size = (len(heightmap), len(heightmap[0]))

        # create image
        hmap = PNMImage(size[0], size[1])

        # draw map
        for y in range(size[0]):
            for x in range(size[1]):
                h = (heightmap[x][y]) * height_modifier
                try:
                    hmap.setXel(x, y, h)
                except:
                    print "Error on x,y: ", str((x, y)), "; map --> 0-255 value: ", str((heightmap[x][y], h))

        return hmap
Пример #17
0
    def _createMaskTextureCard(self):
        self._maskImage = PNMImage(self._maskResolution, self._maskResolution,
                                   4)
        for x in xrange(self._maskResolution):
            for y in xrange(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)

        self.maskTexture = Texture('maskTexture')
        self.maskTexture.setupTexture(Texture.TT2dTexture,
                                      self._maskResolution,
                                      self._maskResolution, 1,
                                      Texture.TUnsignedByte, Texture.FRgba)
        self.maskTexture.setMinfilter(Texture.FTLinear)
        self.maskTexture.setWrapU(Texture.WMClamp)
        self.maskTexture.setWrapV(Texture.WMClamp)
        self.maskTexture.load(self._maskImage)
        base.graphicsEngine.renderFrame()
        cm = CardMaker('mask_cardMaker')
        cm.setFrame(-1.1, 1.1, -1.1, 1.1)
        mask = self.attachNewNode(cm.generate())
        mask.setTexture(self.maskTexture, 1)
        mask.setTransparency(1)
        return mask
    def makeHeightMap(self):
        """Generate a new heightmap image.

        Panda3d GeoMipMaps require an image from which to build and update
        their height field. This function creates the correct image using the
        tile's position and the Terrain's getHeight() function.

        """

        if SAVED_HEIGHT_MAPS:
            fileName = "maps/height/" + self.name + ".png"
            self.getRoot().setTag('EditableTerrain', '1')
            if self.image.read(Filename(fileName)):
                logging.info("read heightmap from " + fileName)
                return

        heightMapSize = self.terrain.tileSize * self.heightMapDetail + 1
        self.image = PNMImage(heightMapSize, heightMapSize, 1, 65535)

        ySize = self.image.getYSize() - 1
        getHeight = self.terrain.getHeight
        setGray = self.image.setGray
        xo = self.xOffset
        yo = self.yOffset
        d = self.heightMapDetail

        for x in range(self.image.getXSize()):
            for y in range(ySize + 1):
                height = getHeight(x / d + xo, y / d + yo)
                #  feed pixel into image
                # why is it necessary to invert the y axis I wonder?
                setGray(x, ySize - y, height)
        #self.postProcessImage()
        if SAVED_HEIGHT_MAPS:
            fileName = "maps/height/" + self.name + ".png"
            logging.info("saving heightmap to " + fileName)
            self.image.write(Filename(fileName))
Пример #19
0
	def __init__( self ):
		'''try:
			import psyco
			psyco.full()
		except ImportError:
			pass'''
		
		self.ts0 = TextureStage( 'dirtL0' )
		self.ts1 = TextureStage( 'dirtL1' )
		self.ts2 = TextureStage( 'dirtL3' )
		self.tex0 = loader.loadTexture( 'mud-tile.png' )
		
		self.mTerrainHeight = MAPSIZE*3
		self.mHorizontalScale = MAPSIZE/TEXSIZE
		
		size = int(TEXSIZE) + 1
		pb = Perlin.Perlin( persistance = 0.500, smooth = False, seed = random.random() )
		myImage2 = pb.imgNoise2D(size,True)
		
		self.myImage=PNMImage(size,size)
		self.myImage.makeGrayscale()
		self.myImage.setMaxval( (2<<16)-1 )
		
		line = lineDrawer.LineDrawer(self.myImage,(42,180),(13,240),30)
		
		for x in range(size):
			for y in range(size):
				if self.myImage.getGray(x,y) > myImage2.getGray(x,y):
					gray = self.myImage.getGray(x,y) - 0.5
				else:
					gray = myImage2.getGray(x,y) - 0.5
				self.myImage.setGray(x,y,gray + 0.5)
		
		#size = int(TEXSIZE) + 1
		#randSeed = random.random()
		#p1 = Perlin.Perlin( persistance = 0.500, smooth = False, seed = randSeed )
		#self.myImage = p1.imgNoise2D(size,True)
		
		self.terrain1 = GeoMipTerrain("myTerrain1")
		self.terrain2 = GeoMipTerrain("myTerrain2")
		self.setupHeightfield(self.terrain1)
		self.setupHeightfield(self.terrain2)
		
		self.terrain1.getRoot().reparentTo(render)
		self.terrain2.getRoot().reparentTo(render)
		
		self.accept( "g", self.flattenArea)
		self.accept( "u", self.updateWithNewImage)
Пример #20
0
 def rotateHue(self, tex, value=0.1):
     '''
     '''
     img = PNMImage()
     tex.store(img)
     for y in range(img.getReadYSize()):
         for x in range(img.getReadXSize()):
             r, g, b = img.getXel(x, y)
             h, s, v = colorsys.rgb_to_hsv(r, g, b)
             h += value
             if h < 0:
                 h += 360
             r, g, b = colorsys.hsv_to_rgb(h, s, v)
             img.setXel(x, y, r, g, b)
     tex.load(img)
Пример #21
0
    def make_blocks_texmap(self):
        images = []
        # 0 - sand
        images.append(
            PNMImage('res/textures/{0}sand.png'.format(Config().tex_suffix)))
        # 1 - land
        images.append(
            PNMImage('res/textures/{0}land.png'.format(Config().tex_suffix)))
        # 2 - low_mount
        images.append(
            PNMImage("res/textures/{0}low_mount.png".format(
                Config().tex_suffix)))
        # 3 - mid_mount
        images.append(
            PNMImage("res/textures/{0}mid_mount.png".format(
                Config().tex_suffix)))
        # 4 - high_mount
        images.append(
            PNMImage("res/textures/{0}high_mount.png".format(
                Config().tex_suffix)))
        d = images[0].getReadXSize()
        # 16 x 16 textures
        size = d * self.map_size
        image_all = PNMImage(size, size)
        n = 0
        for i in xrange(0, size, d):
            for j in xrange(0, size, d):
                image_all.copySubImage(images[n], j, i)
                n += 1
                if n >= len(images):
                    break
            if n >= len(images):
                break

        self['world_blocks'] = Texture()
        self['world_blocks'].load(image_all)
        self['world_blocks'].setMagfilter(Texture.FTLinearMipmapLinear)
        self['world_blocks'].setMinfilter(Texture.FTLinearMipmapLinear)
Пример #22
0
	def flattenArea( self ):
		tilePos = (500,500)
		tileSize = (4000,4000)
		
		imgTilePos = self.world2MapPos(tilePos)
		imgTileSize = self.world2MapPos( (tilePos[0] + tileSize[0], tilePos[1] + tileSize[1]) )
		imgTileSize = (imgTileSize[0] - imgTilePos[0], imgTileSize[1] - imgTilePos[1])
		
		tileSquare = PNMImage(Filename("tile.png"))
		
		tileStamp = PNMImage(int(imgTileSize[0] * (5/3)),int(imgTileSize[1] * (5/3)))
		tileStamp.makeGrayscale()
		tileStamp.addAlpha()
		
		tileStamp.gaussianFilterFrom(1, tileSquare)
		
		count = 4
		total = 0.0
		
		selectXLow = int(imgTilePos[0] + imgTileSize[0] * 0.25)
		selectXHigh = int(imgTilePos[0] + imgTileSize[0] * 0.75)
		selectYLow = int(imgTilePos[1] + imgTileSize[1] * 0.25)
		selectYHigh = int(imgTilePos[1] + imgTileSize[1] * 0.75)
		
		total += self.myImage.getGray(selectXLow,selectYLow)
		total += self.myImage.getGray(selectXLow,selectYLow)
		total += self.myImage.getGray(selectXHigh,selectYHigh)
		total += self.myImage.getGray(selectXHigh,selectYHigh)
		average = total/count
		
		tileStamp.fill(average)
		
		edgeWidth = imgTilePos[0]*(1/3)
		
		self.myImage.blendSubImage(tileStamp, int( imgTilePos[0]-edgeWidth), 
											  int( imgTilePos[1]-edgeWidth), 
										0, 0, int(imgTileSize[0]*( 5/3 )  ), 
											  int(imgTileSize[1]*( 5/3 )  ), 1)
Пример #23
0
    def _createMapTextureCard(self):
        """
        This will return a NodePath with a card textured with the minimap.  The
        minimap texture is dynamically created from the map data.
        """
        # create and fill empty map image
        mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION)
        blockFiles = []
        for i in range(5):
            blockFiles.append(PNMImage())
            #blockFiles[i].read(Filename("mapBlock%i.jpg"%(i+1)))
            # TODO:maze either reference a set of textures for each piece or fill with color
            blockFiles[i].read(Filename('phase_4/maps/male_sleeve4New.jpg'))
        mapImage.fill(0.8, 0.8, 0.8)

        # iterate through the map data and place a block in the map image where appropriate
        for x in range( len(self._mazeLayout[0]) ):
            for y in range( len(self._mazeLayout) ):
                if self._mazeLayout[y][x]:
                    ax = float(x)/len(self._mazeLayout[0]) * MAP_RESOLUTION
                    ay = float(y)/len(self._mazeLayout) * MAP_RESOLUTION

                    #TODO:maze use different blocks for different wall types or items
                    #mapImage.copySubImage(random.choice(blockFiles), int(ax), int(ay), 20, 20, 32, 32)

                    #TODO:maze find the ideal block texture size for the map so we dont
                    #          have to do this strange offset
                    #mapImage.copySubImage(blockFiles[0], int(ax), int(ay), 0, 0, 32, 32)
                    self._drawSquare(mapImage, int(ax), int(ay), 10, VBase4D(0.5, 0.5, 0.5, 1.0))

        # create a texture from the map image
        mapTexture = Texture("mapTexture")
        mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba)
        mapTexture.setMinfilter(Texture.FTLinear)
        mapTexture.load(mapImage)
        mapTexture.setWrapU(Texture.WMClamp)
        mapTexture.setWrapV(Texture.WMClamp)

        mapImage.clear()
        del mapImage

        # put the texture on a card and return it
        cm = CardMaker("map_cardMaker")
        cm.setFrame(-1.0,1.0,-1.0,1.0)
        map = self.attachNewNode(cm.generate())
        map.setTexture(mapTexture, 1)
        return map
 def __createBuffer(self):
   ''' create the buffer we render in the background into '''
   print "I: TexturePainter.__createBuffer"
   # the window has been modified
   if WindowManager.activeWindow:
     # on window resize there seems to be never a active window
     win = WindowManager.activeWindow.win
   else:
     win = base.win
   
   # get the window size
   self.windowSizeX = win.getXSize()
   self.windowSizeY = win.getYSize()
   
   # create a buffer in which we render the model using a shader
   self.paintMap = Texture()
   # 1.5.4 cant handle non power of 2 buffers
   self.modelColorBuffer = createOffscreenBuffer(-3, TEXTUREPAINTER_BACKGROUND_BUFFER_RENDERSIZE[0], TEXTUREPAINTER_BACKGROUND_BUFFER_RENDERSIZE[1]) #self.windowSizeX, self.windowSizeY)
   self.modelColorBuffer.addRenderTexture(self.paintMap, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor)
   self.modelColorCam = base.makeCamera(self.modelColorBuffer, lens=base.cam.node().getLens(), sort=1)
   
   # Create a small buffer for the shader program that will fetch the point from the texture made
   # by the self.modelColorBuffer
   self.colorPickerImage = PNMImage()
   self.colorPickerTex = Texture()
   self.colorPickerBuffer = base.win.makeTextureBuffer("color picker buffer", 2, 2, self.colorPickerTex, True)
   
   self.colorPickerScene = NodePath('color picker scene')
   
   self.colorPickerCam = base.makeCamera(self.colorPickerBuffer, lens=base.cam.node().getLens(), sort=2)
   self.colorPickerCam.reparentTo(self.colorPickerScene)
   self.colorPickerCam.setY(-2)
   
   cm = CardMaker('color picker scene card')
   cm.setFrameFullscreenQuad()
   pickerCard = self.colorPickerScene.attachNewNode(cm.generate())
   
   loadPicker = NodePath(PandaNode('pointnode'))
   loadPicker.setShader(Shader.make(COLOR_PICKER_SHADER), 10001)
   
   # Feed the paintmap from the paintBuffer to the shader and initial mouse positions
   self.colorPickerScene.setShaderInput('paintmap', self.paintMap)
   self.colorPickerScene.setShaderInput('mousepos', 0, 0, 0, 1)
   self.colorPickerCam.node().setInitialState(loadPicker.getState())
 def __startEditor(self, editModel, editTexture, backgroundShader=MODEL_COLOR_SHADER):
   print "I: TexturePainter.__startEditor"
   
   # this is needed as on startup the editor may not have had a window etc.
   self.__windowEvent()
   
   if not editModel or not editTexture:
     print "W: TexturePainter.__startEditor: model or texture invalid", editModel, editTexture
     return False
   
   self.editModel = editModel
   self.editTexture = editTexture
   self.editImage = None
   self.backgroundShader = backgroundShader
   
   if type(self.editTexture) == Texture:
     # if the image to modify is a texture, create a pnmImage which we modify
     self.editImage = PNMImage()
     # copy the image from the texture to the working layer
     self.editTexture.store(self.editImage)
   else:
     self.editImage = self.editTexture
   
   # create the brush for painting
   self.painter = PNMPainter(self.editImage)
   self.setBrushSettings( *self.getBrushSettings() )
   
   self.__updateModel()
   
   # start edit
   messenger.send(EVENT_TEXTUREPAINTER_STARTEDIT)
   
   for startEvent in TEXTUREPAINTER_START_PAINT_EVENTS:
     self.accept(startEvent, self.__startPaint)
   for stopEvent in TEXTUREPAINTER_STOP_PAINT_EVENTS:
     self.accept(stopEvent, self.__stopPaint)
   
   self.modelColorCam.node().copyLens(WindowManager.activeWindow.camera.node().getLens())
   
   taskMgr.add(self.__paintTask, 'paintTask')
   
   #modelModificator.toggleEditmode(False)
   
   self.isPainting = False
Пример #26
0
def greenNoise(imgSize=(32,32),scale=0.25):
    """Return a PNMImage of the given size containing Perlin noise at the given
    scale in the green colour values of the image pixels."""

    # Initialuse the PNMImage object
    img = PNMImage(*imgSize)

    # Initalise PerlinNoise2 object
    noise = PerlinNoise2()
    noise.setScale(scale)

    # Fill in the pixels of img, setting the red and blue values of each pixel
    # to 0 and the green value to Perlin noise.
    for x in xrange(imgSize[0]):
        for y in xrange(imgSize[1]):
            img.setRed(x,y,0)
            img.setBlue(x,y,0)
            pos = Vec2(1.0/32*x, 1.0/32*y)
            img.setGreen(x,y,(noise(pos)+1.0)/2.0)

    return img
Пример #27
0
 def __init__(self):
     self.size = 64
     self.p = Perlin.Perlin(numberOfOctaves=10, persistance=0.75, smooth=False)
     self.myImage = PNMImage(self.size, self.size)
     self.myImage.makeGrayscale()
     self.myTexture = Texture()
     self.myImage.fill(0.5)
     self.myTexture.load(self.myImage)
     self.imageObject = OnscreenImage(image=self.myTexture, pos=(0, 0, 0))
     self.myList = [None] * (self.size)
     for a in range(self.size):
         self.myList[a] = [0.5] * (self.size)
     taskMgr.add(self.noiseTaskVerySmart, "perlinNoiseTask")
     self.startTime = time()
     self.noiseTaskVerySmart()
     self.accept("arrow_up", self.run)
     self.i = [None] * (self.size + 1)
     for x in range(0, self.size + 1):
         self.i[x] = [None] * (self.size + 1)
Пример #28
0
    def _createMaskTextureCard(self):
        self._maskImage = PNMImage(self._maskResolution, self._maskResolution, 4)
        for x in xrange(self._maskResolution):
            for y in xrange(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)

        self.maskTexture = Texture('maskTexture')
        self.maskTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.maskTexture.setMinfilter(Texture.FTLinear)
        self.maskTexture.setWrapU(Texture.WMClamp)
        self.maskTexture.setWrapV(Texture.WMClamp)
        self.maskTexture.load(self._maskImage)
        base.graphicsEngine.renderFrame()
        cm = CardMaker('mask_cardMaker')
        cm.setFrame(-1.1, 1.1, -1.1, 1.1)
        mask = self.attachNewNode(cm.generate())
        mask.setTexture(self.maskTexture, 1)
        mask.setTransparency(1)
        return mask
Пример #29
0
 def get_map_2d_tex(self, map2d, factor=1):
     """Generate texture for map2d, factor - for size [size / factor]
     """
     size = map2d.size / factor
     image = PNMImage(size, size)
     for x in xrange(size):
         for y in xrange(size):
             px = x * factor
             py = y * factor
             if map2d[(px, py)] <= map2d.water_z:
                 image.setPixel(x, y, (0, 0, 100))
             else:
                 image.setPixel(x, y, (0, 100, 0))
     texture = Texture()
     texture.load(image)
     return texture
Пример #30
0
def createPickingImage(size):
    ''' create a picking image with uniq colors for each point in the image
  '''
    image = PNMImage(*size)
    for x in xrange(size[0]):
        for y in xrange(size[1]):
            r = x % 256
            g = y % 256
            b = (x // 256) + (y // 256) * 16
            image.setXelVal(x, y, r, g, b)

    # Reverse way is:
    #    tx = r + ((b%16)*256)
    #    ty = g + ((b//16)*256)
    imageFilename = 'data/textures/index-%i-%i.png' % (size[0], size[1])
    image.write(Filename(imageFilename))
Пример #31
0
    def __init__(self, *args):
        '''
        '''
        ShowBase.__init__(self)

        base.setBackgroundColor(0, 0, 0)

        self.mdl = self.loader.loadModel("data/models/vehicles/vehicle01.egg")
        self.mdl.reparentTo(render)

        # Add the Skybox
        self.skybox = self.loader.loadModel("data/models/skybox.egg")
        t = Texture()
        # t.load(PNMImage("../skybox/skybox_tronic.png"))
        t.load(PNMImage("../skybox/test.png"))
        self.skybox.setTexture(t)
        self.skybox.setBin("background", 1)
        self.skybox.setDepthWrite(0)
        self.skybox.setDepthTest(0)
        self.skybox.setLightOff()
        self.skybox.setScale(10000)
        self.skybox.reparentTo(render)
Пример #32
0
 def load(self, container, name="New Region"):
     '''Loads a new region, usually from connecting to a server
     Or starting a new or previously saved region.
     '''
     import base64
     self.heightmap = PNMImage()
     imageString = base64.b64decode(container.heightmap)
     self.heightmap.read(StringStream(imageString))
     self.region_size = (self.heightmap.getXSize()-1, self.heightmap.getYSize()-1)
     
     position = 0
     tileid = 0
     total_tiles = self.region_size[0] * self.region_size[1]
     ranges = []
     tiles = []
     
     for tile in container.tiles:
         tiles.append((tile.id, tile.cityid))
     for n in range(len(tiles)):
         try:
             ranges.append((tiles[n][0], tiles[n+1][0]-1, tiles[n][1]))
         except:
             ranges.append((tiles[n][0], total_tiles, tiles[n][1]))
     for r in ranges:
         for x in range(r[0], r[1]+1):
             #print "r0, r1, x", r[0], r[1], x
             self.tiles.append(Tile(tileid, r[2]))
             #print "Len", len(self.tiles)
             tileid += 1
     
     position = 0
     for y in range(self.region_size[1]):
         for x in range(self.region_size[0]):
             self.tiles[position].coords = (x,y)
             position += 1
             
     for city in container.cities:
         self.newCity(city)
     messenger.send("generateRegion", [self.heightmap, self.tiles, self.cities, container])
Пример #33
0
	def makeHeightMap(self):
		"""Generate a new heightmap image.
		
		Panda3d GeoMipMaps require an image from which to build and update
        their height field. This function creates the correct image using the
        tile's position and the Terrain's getHeight() function.
		
		"""
		
		if SAVED_HEIGHT_MAPS:
			fileName = "maps/height/" + self.name + ".png"
			self.getRoot().setTag('EditableTerrain', '1')
			if self.image.read(Filename(fileName)):
				logging.info( "read heightmap from " + fileName)
				return
				
		heightMapSize = self.terrain.tileSize * self.heightMapDetail + 1
		self.image = PNMImage(heightMapSize, heightMapSize, 1, 65535)
		
		ySize = self.image.getYSize() - 1
		getHeight = self.terrain.getHeight
		setGray = self.image.setGray
		xo = self.xOffset
		yo = self.yOffset
		d = self.heightMapDetail
		
		for x in range(self.image.getXSize()):
			for y in range(ySize + 1):
				height = getHeight(x / d + xo, y / d + yo)
				# feed pixel into image
				# why is it necessary to invert the y axis I wonder?
				setGray(x, ySize - y, height)
		#self.postProcessImage()
		if SAVED_HEIGHT_MAPS:	
			fileName = "maps/height/" + self.name + ".png"
			logging.info( "saving heightmap to " + fileName)
			self.image.write(Filename(fileName))
Пример #34
0
  def make_data(self, hmapfile):
    # open heightmap for reading pixel data
    heightmap = PNMImage()
    heightmap.read(Filename(hmapfile))
    xs = heightmap.getXSize()
    ys = heightmap.getYSize()

    # generate data bi-dimensional array
    data = []
    for x in range(xs):
      data.append([])
      for y in range(ys):
        # set data dictionary properties
        # name
        name = "cell_" + str(x) + "_" + str(y)
        # height
        height = (heightmap.getXel(x, ys - y - 1)[0] * 10)

        if self.retro == True:
          if height < 1 :
            height = height / 5
            height = int(height)
        # c and rgb
        c = [random.random(), random.random(), random.random()]
        rgb = (int(c[0] * 255), int(c[1] * 255), int(c[2] * 255))
        # default texture
        texture = self.tiles[0]['tex']
        texturenum = 0
        score = self.tiles[0]['score']

        # from rgb we assign tex and score
        for n in range(len(self.tiles)):
          if rgb == self.tiles[n]['rgb']:
            texture = self.tiles[n]['tex']
            texturenum = n
            score = self.tiles[n]['score']
            break

        # set terrain data dictionary
        data[x].append({'name':name, 'h':height, 'c':c, 'rgb':rgb, 'tex':texture,
                        'texnum':texturenum, 'score':score})
    return data
Пример #35
0
class MazeMapGui(DirectFrame):
    notify = directNotify.newCategory('MazeMapGui')

    def __init__(self, mazeCollTable, maskResolution = None, radiusRatio = None, bgColor = (0.8, 0.8, 0.8), fgColor = (0.5, 0.5, 0.5, 1.0)):
        DirectFrame.__init__(self, relief=None, state=DGG.NORMAL, sortOrder=DGG.BACKGROUND_SORT_INDEX)
        self.hide()
        self._bgColor = bgColor
        self._fgColor = fgColor
        self._mazeCollTable = mazeCollTable
        self._mazeWidth = len(self._mazeCollTable[0])
        self._mazeHeight = len(self._mazeCollTable)
        self._maskResolution = maskResolution or DEFAULT_MASK_RESOLUTION
        if radiusRatio is None:
            self._radius = self._maskResolution * DEFAULT_RADIUS_RATIO
        else:
            self._radius = self._maskResolution * radiusRatio
        self._revealedCells = []
        for y in xrange(self._mazeHeight):
            self._revealedCells.append([])
            for u in xrange(self._mazeWidth):
                self._revealedCells[y].append(False)

        self._revealFunctions = {MazeRevealType.SmoothCircle: self._revealSmoothCircle,
         MazeRevealType.HardCircle: self._revealHardCircle,
         MazeRevealType.Square: self._revealSquare}
        self._revealFunction = MAZE_REVEAL_TYPE
        self.map = self._createMapTextureCard()
        self.map.reparentTo(self)
        self.maskedLayer = self.attachNewNode('maskedLayer')
        self.mask = self._createMaskTextureCard()
        self.mask.reparentTo(self)
        self.visibleLayer = self.attachNewNode('visibleLayer')
        self._laffMeterModel = loader.loadModel('phase_3/models/gui/laff_o_meter')
        self._toon2marker = {}
        return

    def _createMapTextureCard(self):
        mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION)
        mapImage.fill(*self._bgColor)
        fgColor = VBase4D(*self._fgColor)
        for x in xrange(self._mazeHeight):
            for y in xrange(self._mazeWidth):
                if self._mazeCollTable[y][x] == 1:
                    ax = float(x) / self._mazeWidth * MAP_RESOLUTION
                    invertedY = self._mazeHeight - 1 - y
                    ay = float(invertedY) / self._mazeHeight * MAP_RESOLUTION
                    self._drawSquare(mapImage, int(ax), int(ay), 10, fgColor)

        mapTexture = Texture('mapTexture')
        mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba)
        mapTexture.setMinfilter(Texture.FTLinear)
        mapTexture.load(mapImage)
        mapTexture.setWrapU(Texture.WMClamp)
        mapTexture.setWrapV(Texture.WMClamp)
        mapImage.clear()
        del mapImage
        cm = CardMaker('map_cardMaker')
        cm.setFrame(-1.0, 1.0, -1.0, 1.0)
        map = self.attachNewNode(cm.generate())
        map.setTexture(mapTexture, 1)
        return map

    def _createMaskTextureCard(self):
        self._maskImage = PNMImage(self._maskResolution, self._maskResolution, 4)
        for x in xrange(self._maskResolution):
            for y in xrange(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)

        self.maskTexture = Texture('maskTexture')
        self.maskTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.maskTexture.setMinfilter(Texture.FTLinear)
        self.maskTexture.setWrapU(Texture.WMClamp)
        self.maskTexture.setWrapV(Texture.WMClamp)
        self.maskTexture.load(self._maskImage)
        base.graphicsEngine.renderFrame()
        cm = CardMaker('mask_cardMaker')
        cm.setFrame(-1.1, 1.1, -1.1, 1.1)
        mask = self.attachNewNode(cm.generate())
        mask.setTexture(self.maskTexture, 1)
        mask.setTransparency(1)
        return mask

    def _drawSquare(self, image, ulx, uly, size, color):
        x = int(ulx)
        while x <= ulx + size:
            y = int(uly)
            while y <= uly + size:
                if x > 0 and y > 0 and x < image.getXSize() and y < image.getYSize():
                    image.setXelA(x, y, color)
                y += 1

            x += 1

    def destroy(self):
        del self._mazeCollTable
        del self._maskResolution
        del self._radius
        del self._revealedCells
        del self._revealFunctions
        del self._revealFunction
        self.map.removeNode()
        del self.map
        self.mask.removeNode()
        del self.mask
        self.maskedLayer.removeNode()
        del self.maskedLayer
        self.visibleLayer.removeNode()
        del self.visibleLayer
        self._maskImage.clear()
        del self._maskImage
        self.maskTexture.clear()
        del self.maskTexture
        self._laffMeterModel.removeNode()
        del self._laffMeterModel
        DirectFrame.destroy(self)

    def _revealSmoothCircle(self, x, y, center):
        length = (Vec2(x, y) - center).length()
        goalAlpha = max(0.0, length / float(self._radius) - 0.5)
        self._maskImage.setXelA(x, y, VBase4D(0.0, 0.0, 0.0, min(self._maskImage.getAlpha(x, y), goalAlpha * 2.0)))

    def _revealHardCircle(self, x, y, center):
        length = (Vec2(x, y) - center).length()
        if length <= self._radius:
            self._maskImage.setXelA(x, y, VBase4D(0, 0, 0, 0))

    def _revealSquare(self, x, y, center):
        self._maskImage.setXelA(x, y, VBase4D(0, 0, 0, 0))

    def _drawHole(self, x, y):
        center = Vec2(x, y)
        ul = center - Vec2(self._radius, self._radius)
        lr = center + Vec2(self._radius, self._radius)
        x = int(ul[0])
        while x <= lr[0]:
            y = int(ul[1])
            while y <= lr[1]:
                if x > 0 and y > 0 and x < self._maskResolution and y < self._maskResolution:
                    self._revealFunctions[self._revealFunction](x, y, center)
                y += 1

            x += 1

        self.maskTexture.load(self._maskImage)
        self.mask.setTexture(self.maskTexture, 1)

    def _createSimpleMarker(self, size, color = (1, 1, 1)):
        halfSize = size * 0.5
        cm = CardMaker('mazemap_simple_marker')
        cm.setFrame(-halfSize, halfSize, -halfSize, halfSize)
        markerNP = self.maskedLayer.attachNewNode(cm.generate())
        markerNP.setColor(*color)
        return markerNP

    def tile2gui(self, x, y):
        y = self._mazeHeight - y
        cellWidth = self._maskResolution / self._mazeWidth
        cellHeight = self._maskResolution / self._mazeHeight
        ax = float(x) / self._mazeWidth * self._maskResolution
        ax += cellWidth
        ay = float(y) / self._mazeHeight * self._maskResolution
        ay += cellHeight
        return (ax, ay)

    def gui2pos(self, x, y):
        return (x / self._maskResolution * 2.0 - 0.97, 0, y / self._maskResolution * -2.0 + 1.02)

    def _getToonMarker(self, toon):
        hType = toon.style.getType()
        if hType == 'rabbit':
            hType = 'bunny'
        return self._laffMeterModel.find('**/' + hType + 'head')

    def addToon(self, toon, tX, tY):
        marker = NodePath('toon_marker-%i' % toon.doId)
        marker.reparentTo(self)
        self._getToonMarker(toon).copyTo(marker)
        marker.setColor(toon.style.getHeadColor())
        if toon.isLocal():
            marker.setScale(0.07)
        else:
            marker.setScale(0.05)
        marker.flattenStrong()
        marker.setPos(*self.gui2pos(*self.tile2gui(tX, tY)))
        self._toon2marker[toon] = marker

    def removeToon(self, toon):
        if not self._toon2marker.has_key(toon):
            return
        self._toon2marker[toon].removeNode()
        del self._toon2marker[toon]

    def updateToon(self, toon, tX, tY):
        if not self._toon2marker.has_key(toon):
            return
        x, y = self.tile2gui(tX, tY)
        self._toon2marker[toon].setPos(*self.gui2pos(x, y))
        if tY < 0 or tY >= len(self._revealedCells):
            self.notify.warning('updateToon earlying out:')
            self.notify.warning('(tX, tY): (%s, %s)' % (tX, tY))
            self.notify.warning('len(_revealedCells): %s' % (len(self._revealedCells),))
            if len(self._revealedCells) > 0:
                self.notify.warning('len(_revealedCells[0]): %s' % (len(self._revealedCells[0]),))
            return
        if tX < 0 or tX >= len(self._revealedCells[tY]):
            self.notify.warning('updateToon earlying out:')
            self.notify.warning('(tX, tY): (%s, %s)' % (tX, tY))
            self.notify.warning('len(_revealedCells): %s' % (len(self._revealedCells),))
            if tY < len(self._revealedCells):
                self.notify.warning('len(_revealedCells[tY]): %s' % (len(self._revealedCells[tY]),))
            elif len(self._revealedCells) > 0:
                self.notify.warning('len(_revealedCells[0]): %s' % (len(self._revealedCells[0]),))
            return
        if not self._revealedCells[tY][tX]:
            self._drawHole(x, y)
            self._revealedCells[tY][tX] = True

    def revealCell(self, x, y):
        ax, ay = self.tile2gui(x, y)
        if not self._revealedCells[y][x]:
            self._drawHole(ax, ay)
            self._revealedCells[y][x] = True

    def revealAll(self):
        for x in xrange(self._maskResolution):
            for y in xrange(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 0)

        self.revealCell(0, 0)

    def reset(self):
        for x in xrange(self._maskResolution):
            for y in xrange(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)
Пример #36
0
class TexturePainter(DirectObject):
    def __init__(self):
        self.editTexture = None
        self.editModel = None

        self.texturePainterStatus = TEXTURE_PAINTER_STATUS_DISABLED

        self.paintColor = VBase4D(1, 1, 1, 1)
        self.paintSize = 10
        self.paintEffect = PNMBrush.BEBlend
        self.paintSmooth = True
        self.paintMode = TEXTUREPAINTER_FUNCTION_PAINT_POINT

        self.painter = None

    # --- creation and destroying of the whole editor ---
    def enableEditor(self):
        ''' create the editor
    change from disabled to enabled'''
        if self.texturePainterStatus == TEXTURE_PAINTER_STATUS_DISABLED:
            self.texturePainterStatus = TEXTURE_PAINTER_STATUS_ENABLED
            self.__enableEditor()
        else:
            print "E: TexturePainter.enableEditor: not disabled", self.texturePainterStatus

    def disableEditor(self):
        ''' destroy the editor, automatically stop the editor and painting
    change from enabled to disabled'''
        # try stopping if more advanced mode
        #if self.texturePainterStatus == TEXTURE_PAINTER_STATUS_INITIALIZED:
        #  self.stopEditor()

        if self.texturePainterStatus == TEXTURE_PAINTER_STATUS_ENABLED:
            self.texturePainterStatus = TEXTURE_PAINTER_STATUS_DISABLED
            self.__disableEditor()
        else:
            print "E: TexturePainter.disableEditor: not enabled", self.texturePainterStatus

    # ---
    def startEditor(self,
                    editModel,
                    editTexture,
                    backgroundShader=MODEL_COLOR_SHADER):
        ''' prepare to paint
    change from enabled to initialized'''
        if self.texturePainterStatus == TEXTURE_PAINTER_STATUS_ENABLED:
            self.texturePainterStatus = TEXTURE_PAINTER_STATUS_INITIALIZED
            self.__startEditor(editModel, editTexture, backgroundShader)
        else:
            print "E: TexturePainter.startEditor: not enabled", self.texturePainterStatus

    def stopEditor(self):
        ''' stop painting, automatically stop painting
    change from initialized to enabled'''
        #if self.texturePainterStatus == TEXTURE_PAINTER_STATUS_INITIALIZED:
        #  self.stopPaint()
        if self.texturePainterStatus == TEXTURE_PAINTER_STATUS_INITIALIZED:
            self.texturePainterStatus = TEXTURE_PAINTER_STATUS_ENABLED
            return self.__stopEditor()
        else:
            print "E: TexturePainter.startEditor: not initialized", self.texturePainterStatus

    """ # this is not externally callable
  # ---
  def startPaint(self):
    ''' start painting on the model
    change from initialized to running '''
    if self.texturePainterStatus == TEXTURE_PAINTER_STATUS_INITIALIZED:
      self.texturePainterStatus = TEXTURE_PAINTER_STATUS_RUNNING
      self.__startPaint()
    else:
      print "E: TexturePainter.startPaint: not enabled", self.texturePainterStatus"""

    def stopPaint(self):
        ''' stop painting
    change from running to initialized '''
        if self.texturePainterStatus == TEXTURE_PAINTER_STATUS_RUNNING:
            self.texturePainterStatus = TEXTURE_PAINTER_STATUS_INITIALIZED
            self.__stopPaint()
        else:
            print "E: TexturePainter.stopPaint: not running", self.texturePainterStatus

    # --- brush settings for painting ---
    ''' changing brush settings is possible all the time '''

    def setBrushSettings(self, color, size, smooth, effect):
        #print "I: TexturePainter.setBrushSettings", color, size, smooth, effect
        self.paintColor = color
        self.paintSize = size
        self.paintEffect = effect
        self.paintSmooth = smooth
        if effect in [
                PNMBrush.BESet, PNMBrush.BEBlend, PNMBrush.BEDarken,
                PNMBrush.BELighten
        ]:
            self.brush = PNMBrush.makeSpot(color, size, smooth, effect)
            #if self.paintModel:
            if self.painter:
                self.painter.setPen(self.brush)

    def getBrushSettings(self):
        return self.paintColor, self.paintSize, self.paintSmooth, self.paintEffect

    def setPaintMode(self, newMode):
        self.paintMode = newMode
        # clear last point if mode changed
        if newMode == TEXTUREPAINTER_FUNCTION_PAINT_POINT or \
           newMode == TEXTUREPAINTER_FUNCTION_READ:
            self.lastPoint = None

    def getPaintMode(self):
        return self.paintMode

    def __enableEditor(self):
        ''' create the background rendering etc., but the model is not yet defined '''
        print "I: TexturePainter.__enableEditor"
        # the buffer the model with the color texture is rendered into
        self.modelColorBuffer = None
        self.modelColorCam = None
        # the buffer the picked position color is rendered into
        self.colorPickerBuffer = None
        self.colorPickerCam = None
        # create the buffers
        self.__createBuffer()

        # when the window is resized, the background buffer etc must be updated.
        self.accept("window-event", self.__windowEvent)

        # some debugging stuff
        self.accept("v", base.bufferViewer.toggleEnable)
        self.accept("V", base.bufferViewer.toggleEnable)

    def __disableEditor(self):
        print "I: TexturePainter.__disableEditor"

        self.__destroyBuffer()

        # ignore window-event and debug
        self.ignoreAll()

    def __windowEvent(self, win=None):
        ''' when the editor is enabled, update the buffers etc. when the window
    is resized '''
        print "I: TexturePainter.windowEvent"

        # with a fixed backgroudn buffer size this is not needed anymore

        if False:
            #if self.texturePainterStatus != TEXTURE_PAINTER_STATUS_DISABLED:
            if self.modelColorBuffer:
                if WindowManager.activeWindow:
                    # on window resize there seems to be never a active window
                    win = WindowManager.activeWindow.win
                else:
                    win = base.win
                if self.modelColorBuffer.getXSize() != win.getXSize(
                ) or self.modelColorBuffer.getYSize() != win.getYSize():
                    '''print "  - window resized",\
              self.modelColorBuffer.getXSize(),\
              win.getXSize(),\
              self.modelColorBuffer.getYSize(),\
              win.getYSize()'''
                    # if the buffer size doesnt match the window size (window has been resized)
                    self.__destroyBuffer()
                    self.__createBuffer()
                    self.__updateModel()
            else:
                print "W: TexturePainter.__windowEvent: no buffer"
                self.__createBuffer()

    def __createBuffer(self):
        ''' create the buffer we render in the background into '''
        print "I: TexturePainter.__createBuffer"
        # the window has been modified
        if WindowManager.activeWindow:
            # on window resize there seems to be never a active window
            win = WindowManager.activeWindow.win
        else:
            win = base.win

        # get the window size
        self.windowSizeX = win.getXSize()
        self.windowSizeY = win.getYSize()

        # create a buffer in which we render the model using a shader
        self.paintMap = Texture()
        # 1.5.4 cant handle non power of 2 buffers
        self.modelColorBuffer = createOffscreenBuffer(
            -3, TEXTUREPAINTER_BACKGROUND_BUFFER_RENDERSIZE[0],
            TEXTUREPAINTER_BACKGROUND_BUFFER_RENDERSIZE[1]
        )  #self.windowSizeX, self.windowSizeY)
        self.modelColorBuffer.addRenderTexture(self.paintMap,
                                               GraphicsOutput.RTMBindOrCopy,
                                               GraphicsOutput.RTPColor)
        self.modelColorCam = base.makeCamera(self.modelColorBuffer,
                                             lens=base.cam.node().getLens(),
                                             sort=1)

        # Create a small buffer for the shader program that will fetch the point from the texture made
        # by the self.modelColorBuffer
        self.colorPickerImage = PNMImage()
        self.colorPickerTex = Texture()
        self.colorPickerBuffer = base.win.makeTextureBuffer(
            "color picker buffer", 2, 2, self.colorPickerTex, True)

        self.colorPickerScene = NodePath('color picker scene')

        self.colorPickerCam = base.makeCamera(self.colorPickerBuffer,
                                              lens=base.cam.node().getLens(),
                                              sort=2)
        self.colorPickerCam.reparentTo(self.colorPickerScene)
        self.colorPickerCam.setY(-2)

        cm = CardMaker('color picker scene card')
        cm.setFrameFullscreenQuad()
        pickerCard = self.colorPickerScene.attachNewNode(cm.generate())

        loadPicker = NodePath(PandaNode('pointnode'))
        loadPicker.setShader(Shader.make(COLOR_PICKER_SHADER), 10001)

        # Feed the paintmap from the paintBuffer to the shader and initial mouse positions
        self.colorPickerScene.setShaderInput('paintmap', self.paintMap)
        self.colorPickerScene.setShaderInput('mousepos', 0, 0, 0, 1)
        self.colorPickerCam.node().setInitialState(loadPicker.getState())

    def __destroyBuffer(self):
        print "I: TexturePainter.__destroyBuffer"
        if self.modelColorBuffer:

            # Destroy the buffer
            base.graphicsEngine.removeWindow(self.modelColorBuffer)
            self.modelColorBuffer = None
            # Remove the camera
            self.modelColorCam.removeNode()
            del self.modelColorCam

            self.colorPickerScene.removeNode()
            del self.colorPickerScene
            # remove cam
            self.colorPickerCam.removeNode()
            del self.colorPickerCam
            # Destroy the buffer
            base.graphicsEngine.removeWindow(self.colorPickerBuffer)
            self.colorPickerBuffer = None

            del self.colorPickerTex
            del self.colorPickerImage

    def __startEditor(self,
                      editModel,
                      editTexture,
                      backgroundShader=MODEL_COLOR_SHADER):
        print "I: TexturePainter.__startEditor"

        # this is needed as on startup the editor may not have had a window etc.
        self.__windowEvent()

        if not editModel or not editTexture:
            print "W: TexturePainter.__startEditor: model or texture invalid", editModel, editTexture
            return False

        self.editModel = editModel
        self.editTexture = editTexture
        self.editImage = None
        self.backgroundShader = backgroundShader

        if type(self.editTexture) == Texture:
            # if the image to modify is a texture, create a pnmImage which we modify
            self.editImage = PNMImage()
            # copy the image from the texture to the working layer
            self.editTexture.store(self.editImage)
        else:
            self.editImage = self.editTexture

        # create the brush for painting
        self.painter = PNMPainter(self.editImage)
        self.setBrushSettings(*self.getBrushSettings())

        self.__updateModel()

        # start edit
        messenger.send(EVENT_TEXTUREPAINTER_STARTEDIT)

        for startEvent in TEXTUREPAINTER_START_PAINT_EVENTS:
            self.accept(startEvent, self.__startPaint)
        for stopEvent in TEXTUREPAINTER_STOP_PAINT_EVENTS:
            self.accept(stopEvent, self.__stopPaint)

        self.modelColorCam.node().copyLens(
            WindowManager.activeWindow.camera.node().getLens())

        taskMgr.add(self.__paintTask, 'paintTask')

        #modelModificator.toggleEditmode(False)

        self.isPainting = False

    def __stopEditor(self):
        print "I: TexturePainter.__stopEditor"
        for startEvent in TEXTUREPAINTER_START_PAINT_EVENTS:
            self.ignore(startEvent)
        for stopEvent in TEXTUREPAINTER_STOP_PAINT_EVENTS:
            self.ignore(stopEvent)

        taskMgr.remove('paintTask')
        # stop edit end

        # must be reset before we loose the properties
        if self.editModel and self.editTexture and self.editImage:
            try:
                # hide the model from cam 2
                self.editModel.hide(BitMask32.bit(1))
                self.editModel = None
            except:
                print "E: TexturePainter.__stopEditor: the model has already been deleted"

        # stop edit
        messenger.send(EVENT_TEXTUREPAINTER_STOPEDIT)

        self.editImage = None
        self.editTexture = None
        self.painter = None
        self.brush = None

        #modelModificator.toggleEditmode(True)

    def __updateModel(self):
        if self.editModel:
            # create a image with the same size of the texture
            textureSize = (self.editTexture.getXSize(),
                           self.editTexture.getYSize())

            # create a dummy node, where we setup the parameters for the background rendering
            loadPaintNode = NodePath(PandaNode('paintnode'))
            loadPaintNode.setShader(Shader.make(self.backgroundShader), 10001)
            loadPaintNode.setShaderInput('texsize', textureSize[0],
                                         textureSize[1], 0, 0)

            # copy the state onto the camera
            self.modelColorCam.node().setInitialState(loadPaintNode.getState())

            # the camera gets a special bitmask, to show/hide models from it
            self.modelColorCam.node().setCameraMask(BitMask32.bit(1))

            if False:
                # doesnt work, but would be nicer (not messing with the default render state)

                hiddenNode = NodePath(PandaNode('hiddennode'))
                hiddenNode.hide(BitMask32.bit(1))
                showTroughNode = NodePath(PandaNode('showtroughnode'))
                showTroughNode.showThrough(BitMask32.bit(1))

                self.modelColorCam.node().setTagStateKey(
                    'show-on-backrender-cam')
                self.modelColorCam.node().setTagState('False',
                                                      hiddenNode.getState())
                self.modelColorCam.node().setTagState(
                    'True', showTroughNode.getState())

                render.setTag('show-on-backrender-cam', 'False')
                self.editModel.setTag('show-on-backrender-cam', 'True')
            else:
                # make only the model visible to the background camera
                render.hide(BitMask32.bit(1))
                self.editModel.showThrough(BitMask32.bit(1))

    # --- start the paint tasks ---
    def __startPaint(self):
        self.isPainting = True

    def __stopPaint(self):
        self.isPainting = False

    # --- modification tasks ---
    def __textureUpdateTask(self, task=None):
        ''' modify the texture using the edited image
    '''
        if type(self.editTexture) == Texture:
            self.editTexture.load(self.editImage)

        if task:  # task may be None
            return task.again

    def __paintTask(self, task):
        #print "I: TexturePainter.__paintTask:"

        if not WindowManager.activeWindow or not WindowManager.activeWindow.mouseWatcherNode.hasMouse(
        ):
            '''print "  - abort:", WindowManager.activeWindow
      if WindowManager.activeWindow:
        print "  - mouse:", WindowManager.activeWindow.mouseWatcherNode.hasMouse()'''
            return task.cont

        # update the camera according to the active camera
        #self.modelColorCam.setMat(render, WindowManager.activeWindow.camera.getMat(render))

        mpos = base.mouseWatcherNode.getMouse()
        x_ratio = min(max(((mpos.getX() + 1) / 2), 0), 1)
        y_ratio = min(max(((mpos.getY() + 1) / 2), 0), 1)
        mx = int(x_ratio * self.windowSizeX)
        my = self.windowSizeY - int(y_ratio * self.windowSizeY)

        self.colorPickerScene.setShaderInput('mousepos', x_ratio, y_ratio, 0,
                                             1)

        if self.colorPickerTex.hasRamImage():
            self.colorPickerTex.store(self.colorPickerImage)

            # get the color below the mousepick from the rendered frame
            r = self.colorPickerImage.getRedVal(0, 0)
            g = self.colorPickerImage.getGreenVal(0, 0)
            b = self.colorPickerImage.getBlueVal(0, 0)
            # calculate uv-texture position from the color
            x = r + ((b % 16) * 256)
            y = g + ((b // 16) * 256)

            if self.isPainting:
                self.__paintPixel(x, y)
                self.__textureUpdateTask()
        else:
            # this might happen if no frame has been rendered yet since creation of the texture
            print "W: TexturePainter.__paintTask: colorPickerTex.hasRamMipmapImage() =", self.colorPickerTex.hasRamImage(
            )

        return task.cont

    def __paintPixel(self, x, y):
        ''' paint at x/y with the defined settings '''

        imageMaxX = self.editImage.getXSize()
        imageMaxY = self.editImage.getYSize()

        def inImage(x, y):
            ''' is the given x/y position within the image '''
            return ((imageMaxX > x >= 0) and (imageMaxY > y >= 0))

        # how smooth should be painted
        if self.paintSmooth:
            # a smooth brush
            hardness = 1.0
        else:
            # a hard brush
            hardness = 0.1
        hardness = min(1.0, max(0.05, hardness))

        # the paint radius
        radius = int(round(self.paintSize / 2.0))
        radiusSquare = float(radius * radius)

        # a function to get the brush color/strength, depending on the radius
        def getBrushColor(diffPosX, diffPosY):
            distance = diffPosX**2 + diffPosY**2
            brushStrength = (
                1 - (min(distance, radiusSquare) / radiusSquare)) / hardness
            return min(1.0, max(0.0, brushStrength))

        if inImage(x, y):
            if self.paintMode == TEXTUREPAINTER_FUNCTION_PAINT_POINT:
                if self.paintEffect in [
                        PNMBrush.BESet, PNMBrush.BEBlend, PNMBrush.BEDarken,
                        PNMBrush.BELighten
                ]:
                    # render a spot into the texture
                    self.painter.drawPoint(x, y)

                elif self.paintEffect in [
                        TEXTUREPAINTER_BRUSH_FLATTEN,
                        TEXTUREPAINTER_BRUSH_SMOOTH,
                        TEXTUREPAINTER_BRUSH_RANDOMIZE
                ]:

                    if self.paintEffect == TEXTUREPAINTER_BRUSH_SMOOTH:
                        # calculate average values
                        data = dict()
                        smoothRadius = 2
                        for dx in xrange(-radius, radius + 1):
                            for dy in xrange(-radius, radius + 1):
                                if inImage(x + dx, y + dy):
                                    average = VBase4D(0)
                                    dividor = 0
                                    for px in xrange(-smoothRadius,
                                                     smoothRadius + 1):
                                        for py in xrange(
                                                -smoothRadius,
                                                smoothRadius + 1):
                                            if inImage(x + dx + px,
                                                       y + dy + py):
                                                average += self.editImage.getXelA(
                                                    x + dx + px, y + dy + py)
                                                dividor += 1
                                    average /= float(dividor)
                                    data[(x + dx, y + dy)] = average

                        # save to image
                        for (px, py), newValue in data.items():
                            currentValue = self.editImage.getXelA(px, py)
                            diffValue = currentValue - newValue

                            dx = px - x
                            dy = py - y

                            multiplier = getBrushColor(dx, dy)
                            print dx, dy, multiplier
                            '''if self.paintSmooth:
                multiplier = ((radius-math.fabs(dx))*(radius-math.fabs(dy))) / (radius*radius)
              else:
                # not sure if this is correct
                multiplier = ((radius-math.fabs(dx))*(radius-math.fabs(dy)))'''
                            '''r = currentValue.getX() * (1-multiplier*self.paintColor.getX()) + diffValue.getX() * multiplier*self.paintColor.getX()
              g = currentValue.getY() * (1-multiplier*self.paintColor.getY()) + diffValue.getY() * multiplier*self.paintColor.getY()
              b = currentValue.getZ() * (1-multiplier*self.paintColor.getZ()) + diffValue.getZ() * multiplier*self.paintColor.getZ()
              a = currentValue.getW() * (1-multiplier*self.paintColor.getW()) + diffValue.getW() * multiplier*self.paintColor.getW()'''
                            r = currentValue.getX(
                            ) - multiplier * diffValue.getX()
                            g = currentValue.getY(
                            ) - multiplier * diffValue.getY()
                            b = currentValue.getZ(
                            ) - multiplier * diffValue.getZ()
                            a = currentValue.getW(
                            ) - multiplier * diffValue.getW()
                            if self.editImage.hasAlpha():
                                self.editImage.setXelA(px, py,
                                                       VBase4D(r, g, b, a))
                            else:
                                self.editImage.setXel(px, py, VBase3D(r, g, b))

                            #self.editImage.setXelA(x,y,value)

                    if self.paintEffect == TEXTUREPAINTER_BRUSH_FLATTEN:
                        dividor = 0
                        average = VBase4D(0)
                        for dx in xrange(-radius, radius + 1):
                            for dy in xrange(-radius, radius + 1):
                                if inImage(x + dx, y + dy):
                                    multiplier = getBrushColor(dx, dy)
                                    '''if self.paintSmooth:
                    multiplier = ((radius-math.fabs(dx))*(radius-math.fabs(dy))) / (radius*radius)
                  else:
                    multiplier = ((radius-math.fabs(dx))*(radius-math.fabs(dy)))'''
                                    dividor += multiplier
                                    average += self.editImage.getXelA(
                                        x + dx, y + dy) * multiplier
                        average /= dividor
                        for dx in xrange(-radius, radius + 1):
                            for dy in xrange(-radius, radius + 1):
                                if inImage(x + dx, y + dy):
                                    multiplier = getBrushColor(dx, dy)
                                    '''if self.paintSmooth:
                    multiplier = ((radius-math.fabs(dx))*(radius-math.fabs(dy))) / (radius*radius)
                  else:
                    # not sure if this is correct
                    multiplier = ((radius-math.fabs(dx))*(radius-math.fabs(dy)))'''
                                    currentValue = self.editImage.getXelA(
                                        x + dx, y + dy)
                                    r = currentValue.getX() * (
                                        1 -
                                        multiplier * self.paintColor.getX()
                                    ) + average.getX(
                                    ) * multiplier * self.paintColor.getX()
                                    g = currentValue.getY() * (
                                        1 -
                                        multiplier * self.paintColor.getY()
                                    ) + average.getY(
                                    ) * multiplier * self.paintColor.getY()
                                    b = currentValue.getZ() * (
                                        1 -
                                        multiplier * self.paintColor.getZ()
                                    ) + average.getZ(
                                    ) * multiplier * self.paintColor.getZ()
                                    a = currentValue.getW() * (
                                        1 -
                                        multiplier * self.paintColor.getW()
                                    ) + average.getW(
                                    ) * multiplier * self.paintColor.getW()
                                    if self.editImage.hasAlpha():
                                        self.editImage.setXelA(
                                            x + dx, y + dy,
                                            VBase4D(r, g, b, a))
                                    else:
                                        self.editImage.setXel(
                                            x + dx, y + dy, VBase3D(r, g, b))

                    elif self.paintEffect == TEXTUREPAINTER_BRUSH_RANDOMIZE:
                        for dx in xrange(-radius, radius + 1):
                            for dy in xrange(-radius, radius + 1):
                                if inImage(x + dx, y + dy):
                                    r = VBase4D(
                                        random.random() *
                                        self.paintColor.getX() -
                                        self.paintColor.getX() / 2.,
                                        random.random() *
                                        self.paintColor.getY() -
                                        self.paintColor.getY() / 2.,
                                        random.random() *
                                        self.paintColor.getZ() -
                                        self.paintColor.getZ() / 2.,
                                        random.random() *
                                        self.paintColor.getW() -
                                        self.paintColor.getW() / 2.)
                                    multiplier = getBrushColor(dx, dy)
                                    '''if self.paintSmooth:
                    multiplier = ((radius-math.fabs(dx))*(radius-math.fabs(dy))) / (radius*radius)
                  else:
                    # not sure if this is correct
                    multiplier = ((radius-math.fabs(dx))*(radius-math.fabs(dy)))'''
                                    currentValue = self.editImage.getXelA(
                                        x + dx, y + dy)
                                    self.editImage.setXelA(
                                        x + dx, y + dy,
                                        currentValue + r * multiplier)

            elif self.paintMode == TEXTUREPAINTER_FUNCTION_READ:
                if inImage(x, y):
                    col = self.editImage.getXelA(x, y)
                    if self.editImage.hasAlpha():
                        self.paintColor = VBase4D(col[0], col[1], col[2],
                                                  col[3])
                    else:
                        self.paintColor = VBase4D(col[0], col[1], col[2], 1.0)
                    messenger.send(EVENT_TEXTUREPAINTER_BRUSHCHANGED)

            elif self.paintMode == TEXTUREPAINTER_FUNCTION_PAINT_LINE:
                if self.lastPoint != None:
                    self.painter.drawLine(x, y, self.lastPoint[0],
                                          self.lastPoint[1])

            elif self.paintMode == TEXTUREPAINTER_FUNCTION_PAINT_RECTANGLE:
                if self.lastPoint != None:
                    self.painter.drawRectangle(x, y, self.lastPoint[0],
                                               self.lastPoint[1])

            self.lastPoint = (x, y)
Пример #37
0
	def imgNoise2D(self, size = 512, autoOctave = False):
		myImage=PNMImage(1,1)
		myImage.makeGrayscale()
		myImage.setMaxval( (2<<16)-1 )
		myImage.fill(0.5)
		
		octaves = self.numberOfOctaves
		if autoOctave == True:
			octaves = int(math.log(size,2))
			self.pNoise = range(0,octaves)
			random.seed(self.seed)
			for i in range(1,octaves):
				self.pNoise[i] = PerlinNoise2( 1, 1, 256, random.randint(1,10000))
		
		for o in range(1,octaves):
			
			freq = 2**o
			oldImage = myImage
			myImage = PNMImage(freq+1,freq+1)
			myImage.makeGrayscale()
			myImage.setMaxval( (2<<16)-1 )
			myImage.gaussianFilterFrom(1.0, oldImage)
			
			for x in range(0,freq):
				for y in range(0,freq):
					newNoise = (self.pNoise[o].noise( x, y)*(self.persistance**o)) / 2
					myImage.setGray(x,y, myImage.getGray(x,y) + newNoise)#*32)
			for i in range(0,freq+1):
				myImage.setGray(i,freq, myImage.getGray(i%freq,0))
				myImage.setGray(freq,i, myImage.getGray(0,i%freq))
		
		oldImage = myImage
		myImage = PNMImage(size,size)
		myImage.makeGrayscale()
		myImage.setMaxval( (2<<16)-1 )
		myImage.gaussianFilterFrom(1.0, oldImage)
		
		return myImage
Пример #38
0
class MazeMapGui(DirectFrame):

    notify = directNotify.newCategory("MazeMapGui")

    def __init__(self, mazeLayout, maskResolution=None, radiusRatio=None):
        """
        Constructor for a MazeMap.  the mazeLayout parameter is a 2d array of
        bools (or ints... maybe more depth will be added with that).
        maskResolution is a value for the resolution of the mask covering the
        map.  It should range from 32 to 256.  radiusRatio is essentially
        the percentage of the map that is revealed with each step.
        """
        DirectFrame.__init__(self,
            relief = None,
            state = DGG.NORMAL,
            sortOrder = DGG.BACKGROUND_SORT_INDEX,
        )

        # store / set parameters
        self._mazeLayout = mazeLayout
        self._maskResolution = maskResolution or DEFAULT_MASK_RESOLUTION
        if radiusRatio is None:
            self._radius = self._maskResolution * DEFAULT_RADIUS_RATIO
        else:
            self._radius = self._maskResolution * radiusRatio

        # store false for all maze cells to represent that none of them have
        # been revealed yet.  This can prevent the expensive call to altering
        # the mask if a cell is already revealed
        self._revealedCells = []
        for y in range( len(self._mazeLayout) ):
            self._revealedCells.append([])
            for x in range( len(self._mazeLayout[0]) ):
                self._revealedCells[y].append(False)

        # create reveal function mappings
        self._revealFunctions = {
            MazeRevealType.SmoothCircle : self._revealSmoothCircle,
            MazeRevealType.HardCircle : self._revealHardCircle,
            MazeRevealType.Square : self._revealSquare,
        }
        self._revealFunction = MAZE_REVEAL_TYPE

        # create the map and the mask
        self.map = self._createMapTextureCard()
        self.map.reparentTo(self)
        self.maskedLayer = self.attachNewNode("maskedLayer")
        self.mask = self._createMaskTextureCard()
        self.mask.reparentTo(self)
        self.visibleLayer = self.attachNewNode("visibleLayer")

        #TODO:maze: handle locks and doors
        self._players = []
        self._locks = []
        self._doors = []

    #--- Initialization, Destruction, and Resetting ---#########################

    def _createMapTextureCard(self):
        """
        This will return a NodePath with a card textured with the minimap.  The
        minimap texture is dynamically created from the map data.
        """
        # create and fill empty map image
        mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION)
        blockFiles = []
        for i in range(5):
            blockFiles.append(PNMImage())
            #blockFiles[i].read(Filename("mapBlock%i.jpg"%(i+1)))
            # TODO:maze either reference a set of textures for each piece or fill with color
            blockFiles[i].read(Filename('phase_4/maps/male_sleeve4New.jpg'))
        mapImage.fill(0.8, 0.8, 0.8)

        # iterate through the map data and place a block in the map image where appropriate
        for x in range( len(self._mazeLayout[0]) ):
            for y in range( len(self._mazeLayout) ):
                if self._mazeLayout[y][x]:
                    ax = float(x)/len(self._mazeLayout[0]) * MAP_RESOLUTION
                    ay = float(y)/len(self._mazeLayout) * MAP_RESOLUTION

                    #TODO:maze use different blocks for different wall types or items
                    #mapImage.copySubImage(random.choice(blockFiles), int(ax), int(ay), 20, 20, 32, 32)

                    #TODO:maze find the ideal block texture size for the map so we dont
                    #          have to do this strange offset
                    #mapImage.copySubImage(blockFiles[0], int(ax), int(ay), 0, 0, 32, 32)
                    self._drawSquare(mapImage, int(ax), int(ay), 10, VBase4D(0.5, 0.5, 0.5, 1.0))

        # create a texture from the map image
        mapTexture = Texture("mapTexture")
        mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba)
        mapTexture.setMinfilter(Texture.FTLinear)
        mapTexture.load(mapImage)
        mapTexture.setWrapU(Texture.WMClamp)
        mapTexture.setWrapV(Texture.WMClamp)

        mapImage.clear()
        del mapImage

        # put the texture on a card and return it
        cm = CardMaker("map_cardMaker")
        cm.setFrame(-1.0,1.0,-1.0,1.0)
        map = self.attachNewNode(cm.generate())
        map.setTexture(mapTexture, 1)
        return map

    def _createMaskTextureCard(self):
        """
        This will return a NodePath with a card textured with the map mask.  It
        also creates several other members that re needed to change the mask.
        """
        # create and fill empty mask image
        self._maskImage = PNMImage(self._maskResolution, self._maskResolution, 4)
        for x in range(self._maskResolution):
            for y in range(self._maskResolution):
                #maskImage.setXel(x,y,mapImage.getRed(x/13,y/10),mapImage.getGreen(x/13,y/10),mapImage.getBlue(x/13,y/10))
                self._maskImage.setXelA(x,y,0,0,0,1)

        # create the texture for the mask
        self.maskTexture = Texture("maskTexture")
        self.maskTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.maskTexture.setMinfilter(Texture.FTLinear)
        self.maskTexture.setWrapU(Texture.WMClamp)
        self.maskTexture.setWrapV(Texture.WMClamp)

        self.maskTexture.load(self._maskImage)
        base.graphicsEngine.renderFrame()

        # put the mask texture on a card and return it
        cm = CardMaker("mask_cardMaker")
        cm.setFrame(-1.0,1.0,-1.0,1.0)
        mask = self.attachNewNode(cm.generate())
        mask.setTexture(self.maskTexture, 1)
        mask.setTransparency(1)
        return mask

    def _drawSquare(self, image, ulx, uly, size, color):
        """
        Draws a square on the supplied PNMImage starting at (ulx, uly) with a
        size of "size" and a color of "color".
        """
        x = int(ulx)
        while x <= ulx + size:
            y = int(uly)
            while y <= uly + size:
                if x > 0 and y > 0 and x < image.getXSize() and y < image.getYSize():
                    image.setXelA( x, y, color )
                y += 1
            x += 1

    def destroy(self):
        del self._mazeLayout
        del self._maskResolution
        del self._radius
        del self._revealedCells

        del self._revealFunctions
        del self._revealFunction

        # remove and delete all nodes
        self.map.removeNode()
        del self.map
        self.mask.removeNode()
        del self.mask
        self.maskedLayer.removeNode()
        del self.maskedLayer
        self.visibleLayer.removeNode()
        del self.visibleLayer

        # remove and delete all lists of nodes
        for p in self._players:
            p.removeNode()
        del self._players
        for k in self._locks:
            k.removeNode()
        del self._locks
        for d in self._doors:
            d.removeNode()
        del self._doors

        self._maskImage.clear()
        del self._maskImage

        self.maskTexture.clear()
        del self.maskTexture

        DirectFrame.destroy(self)

    #--- Reveal shape functions ---#############################################

    def _revealSmoothCircle(self, x, y, center):
        length = (Vec2(x,y)-center).length()
        goalAlpha = max(0.0, (length/float(self._radius)) - 0.5)
        self._maskImage.setXelA(
            x,
            y,
            VBase4D( 0.0, 0.0, 0.0, min(self._maskImage.getAlpha(x,y), goalAlpha*2.0))
        )

    def _revealHardCircle(self, x, y, center):
        length = (Vec2(x,y)-center).length()
        if length <= self._radius:
            self._maskImage.setXelA(x,y,VBase4D(0,0,0,0))

    def _revealSquare(self, x, y, center):
        self._maskImage.setXelA(x,y,VBase4D(0,0,0,0))

    #--- Private Functions ---##################################################

    def _drawHole(self, x, y):
        center = Vec2(x, y)
        ul = center - Vec2(self._radius, self._radius)
        lr = center + Vec2(self._radius, self._radius)
        x = int(ul[0])
        while x <= lr[0]:
            y = int(ul[1])
            while y <= lr[1]:
                if x > 0 and y > 0 and x < self._maskResolution and y < self._maskResolution:
                    self._revealFunctions[self._revealFunction](x, y, center)
                y += 1
            x += 1

        self.maskTexture.load(self._maskImage)
        self.mask.setTexture(self.maskTexture, 1)

    def _tileToActualPosition(self, x, y):
        y = len(self._mazeLayout) - y
        cellWidth = self._maskResolution / len(self._mazeLayout[0])
        cellHeight = self._maskResolution / len(self._mazeLayout)
        ax = float(x)/len(self._mazeLayout[0]) * self._maskResolution
        ax += cellWidth
        ay = float(y)/len(self._mazeLayout) * self._maskResolution
        ay += cellHeight
        return ax, ay

    #--- Member Functions ---###################################################

    def addDoor(self, x, y, color):
        """
        Adds a door to the minimap.  This will add a colored dot to the map
        that represents a door.
        --- This is subject to change pending a new player-lock data system. ---
        """
        assert self.notify.debugCall()

        x, y = self._tileToActualPosition(x, y)

        # TODO:maze: replace with door model / texture
        cm = CardMaker("door_cardMaker")
        cm.setFrame(-0.04,0.04,-0.04,0.04)
        #door = self.visibleLayer.attachNewNode(cm.generate())
        door = self.maskedLayer.attachNewNode(cm.generate())

        door.setColor(color)
        door.setPos(x/self._maskResolution*2.0 - 0.97, 0, y/self._maskResolution*-2.0 + 1.02)

        self._doors.append(door)

    def addLock(self, x, y, color):
        """
        Adds a lock to the minimap.  This will add a colored dot to the map
        that represents a lock.
        --- This is subject to change pending a new player-lock data system. ---
        """
        assert self.notify.debugCall()

        x, y = self._tileToActualPosition(x, y)

        # TODO:maze: replace with lock model / texture
        cm = CardMaker("lock_cardMaker")
        cm.setFrame(-0.04,0.04,-0.04,0.04)
        lock = self.maskedLayer.attachNewNode(cm.generate())

        lock.setColor(color)
        lock.setPos(x/self._maskResolution*2.0 - 0.97, 0, y/self._maskResolution*-2.0 + 1.02)

        self._locks.append(lock)

    def addPlayer(self, x, y, color):
        """
        Adds a player to the minimap.  This will add a colored dot to the map
        that represents the player.  The dot location can then be updated
        using the revealCell call.
        --- This is subject to change pending a new player-lock data system. ---
        """
        assert self.notify.debugCall()

        x, y = self._tileToActualPosition(x, y)

        # TODO:maze: replace with player model / texture
        cm = CardMaker("player_cardMaker")
        cm.setFrame(-0.04,0.04,-0.04,0.04)
        player = self.visibleLayer.attachNewNode(cm.generate())

        player.setColor(color)
        player.setPos(x/self._maskResolution*2.0 - 0.97, 0, y/self._maskResolution*-2.0 + 1.02)

        self._players.append(player)

    def revealCell(self, x, y, playerIndex=None):
        """
        Clears out the mask around the given cell and stores that the cell has
        been revealed to prevent attempting to edit the mask for the cell again.
        """

        ax, ay = self._tileToActualPosition(x, y)

        if not self._revealedCells[y][x]:
            self._drawHole(ax, ay)
            self._revealedCells[y][x] = True

        if playerIndex is not None:
            assert(playerIndex < len(self._players))
            self._players[playerIndex].setPos(ax/self._maskResolution*2.0 - 0.97, 0, ay/self._maskResolution*-2.0 + 1.02)

    def revealAll(self):
        """ Clears out all of the mask. """
        for x in range(self._maskResolution):
            for y in range(self._maskResolution):
                self._maskImage.setXelA(x,y,0,0,0,0)

    def reset(self):
        """ Turns all of the mask on, covering the entire map. """
        for x in range(self._maskResolution):
            for y in range(self._maskResolution):
                self._maskImage.setXelA(x,y,0,0,0,1)
Пример #39
0
    def collectPlayer(self, task):
        '''
        Wait until all players are ready
        '''
        if len(self._players) > 0 and self.player_buttonpressed[0] < task.time:
            if self._players[0].device.boost and self.countdown <= 0:
                loading = False
                for player in self._players:
                    if player.vehicle.model_loading:
                        loading = True
                        break
                self._notify.debug("Loading vehicle: %s" % (loading))
                if not loading:
                    taskMgr.remove("selectVehicle")
                    self.track = trackgen3d.Track3d(1000, 1800, 1600, 1200,
                                                    5)  # len(self._players))
                    self.streetPath = render.attachNewNode(
                        self.track.createRoadMesh())
                    # self.borderleftPath = render.attachNewNode(self.track.createBorderLeftMesh())
                    self.borderleftPath = render.attachNewNode(
                        self.track.createBorderLeftMesh())
                    self.borderrightPath = render.attachNewNode(
                        self.track.createBorderRightMesh())
                    self.borderleftcollisionPath = NodePath(
                        self.track.createBorderLeftCollisionMesh())
                    self.borderrightcollisionPath = NodePath(
                        self.track.createBorderRightCollisionMesh())
                    # #self.borderPath = render.attachNewNode(self.track.createBorderMesh())

                    textures = ["tube", "tube2", "street"]
                    tex = textures[random.randint(0, len(textures) - 1)]
                    roadtex = loader.loadTexture('data/textures/' + tex +
                                                 '.png')
                    bordertex = loader.loadTexture('data/textures/border.png')
                    self.streetPath.setTexture(roadtex)
                    self.borderleftPath.setTexture(bordertex)
                    self.borderrightPath.setTexture(bordertex)

                    # self.streetPath = loader.loadModel('data/models/Street.egg')
                    # self.streetPath = loader.loadModel('data/models/Street.egg')
                    # tex = loader.loadTexture('data/models/StreetTex.png')
                    # self.nodePath.setTexture(tex)

                    self._parent.startGame(self.streetPath,
                                           self.borderleftPath,
                                           self.borderrightPath,
                                           self.track.trackpoints,
                                           self.borderleftcollisionPath,
                                           self.borderrightcollisionPath)
                    return task.done

        for device in self.unusedDevices:
            if device.boost:
                self.countdown = COUNTDOWN_START
                self.player_buttonpressed.append(0)
                self._parent.addPlayer(device)

                # Set the PlayerCam to the Vehicle select menu Node
                vehicleSelectNode = NodePath("VehicleSelectNode")
                self._players[-1].camera.camera.reparentTo(vehicleSelectNode)

                # Light, that casts shadows
                plight = Spotlight('plight')
                plight.setColor(VBase4(10.0, 10.0, 10.0, 1))
                if (base.win.getGsg().getSupportsBasicShaders() != 0):
                    pass
                    # plight.setShadowCaster(True, 2048, 2048)#enable shadows for this light ##TODO wegen Linux

                # Light
                plight.getLens().setFov(80)
                plnp = vehicleSelectNode.attachNewNode(plight)
                plnp.setPos(2, -10, 10)
                plnp.lookAt(0, 0, 0)
                vehicleSelectNode.setLight(plnp)
                # vehicleSelectNode.setShaderAuto()#enable autoshader so we can use shadows

                # Light
                ambilight = AmbientLight('ambilight')
                ambilight.setColor(VBase4(0.2, 0.2, 0.2, 1))
                vehicleSelectNode.setLight(
                    vehicleSelectNode.attachNewNode(ambilight))
                self.platform.instanceTo(
                    vehicleSelectNode)  # Load the platform

                # instance shown text
                self.countdown_node.instanceTo(
                    vehicleSelectNode)  # Instance the Countdown
                self.loading.instanceTo(
                    vehicleSelectNode)  # Show the Loading-Text
                self.attributes.copyTo(vehicleSelectNode).hide()
                self._players[-1].vehicle.model_loading = True

                # start loading the model
                loader.loadModel(self.vehicle_list[0],
                                 callback=self._players[-1].setVehicle)
                self._notify.debug("Loading initial vehicle: %s" %
                                   (self.vehicle_list[0]))
                self.unusedDevices.remove(device)
                self.player_buttonpressed[-1] = task.time + self.KEY_DELAY

                # Add the Skybox
                skybox = loader.loadModel("data/models/skybox.egg")
                t = Texture()
                t.load(PNMImage("data/textures/skybox_hangar.png"))
                skybox.setTexture(t)
                skybox.setBin("background", 1)
                skybox.setDepthWrite(0)
                skybox.setDepthTest(0)
                skybox.setLightOff()
                skybox.setScale(10000)
                skybox.reparentTo(vehicleSelectNode)

        for player in self._players:
            if self.player_buttonpressed[self._players.index(
                    player)] < task.time:
                if player.device.use_item:
                    self.countdown = COUNTDOWN_START
                    self._notify.debug("Removing player: %s" % (player))
                    self.unusedDevices.append(player.device)
                    self.player_buttonpressed.pop(self._players.index(player))
                    self._parent.removePlayer(player)
        return task.cont
Пример #40
0
 def setupHalfTextures(self):
     self.setupLeftTexture()
     self.setupRightTexture()
     self.fullPnmImage = PNMImage(WEB_WIDTH, WEB_HEIGHT, 4)
     self.leftPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
     self.rightPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
Пример #41
0
class Region(DirectObject.DirectObject):
    '''Stuff'''
    def __init__(self):
        self.tiles = []
        self.cities = {}
        self.accept('loadRegion', self.load)
        self.accept("updatedTiles", self.updateTiles)
        self.accept("newCity", self.newCity)
        self.accept("clickForCity", self.checkCity)
        self.accept("unfoundCity", self.unfoundCity)
        self.accept("enterCity", self.enterCity)

    def load(self, container, name="New Region"):
        '''Loads a new region, usually from connecting to a server
        Or starting a new or previously saved region.
        '''
        import base64
        self.heightmap = PNMImage()
        imageString = base64.b64decode(container.heightmap)
        self.heightmap.read(StringStream(imageString))
        self.region_size = (self.heightmap.getXSize() - 1,
                            self.heightmap.getYSize() - 1)

        position = 0
        tileid = 0
        total_tiles = self.region_size[0] * self.region_size[1]
        ranges = []
        tiles = []

        for tile in container.tiles:
            tiles.append((tile.id, tile.cityid))
        for n in range(len(tiles)):
            try:
                ranges.append((tiles[n][0], tiles[n + 1][0] - 1, tiles[n][1]))
            except:
                ranges.append((tiles[n][0], total_tiles, tiles[n][1]))
        for r in ranges:
            for x in range(r[0], r[1] + 1):
                #print "r0, r1, x", r[0], r[1], x
                self.tiles.append(Tile(tileid, r[2]))
                #print "Len", len(self.tiles)
                tileid += 1

        position = 0
        for y in range(self.region_size[1]):
            for x in range(self.region_size[0]):
                self.tiles[position].coords = (x, y)
                position += 1

        for city in container.cities:
            self.newCity(city)
        messenger.send("generateRegion",
                       [self.heightmap, self.tiles, self.cities, container])

    def updateTiles(self, container):
        x = 0
        for tile in container:
            x += 1
            self.tiles[tile.id].cityid = tile.cityid
        print x, "tiles updated from server."
        messenger.send("updateRegion",
                       [self.heightmap, self.tiles, self.cities])

    def newCity(self, city):
        self.cities[city.id] = {
            "name": city.name,
            "mayor": city.mayor,
            "funds": city.funds,
            "population": city.population
        }

    def checkCity(self, cell):
        '''Checks for city in given cell for region gui display'''
        if not cell: return
        tile = self.getTile(cell[0], cell[1])
        if tile.cityid:
            messenger.send("showRegionCityWindow",
                           [tile.cityid, self.cities[tile.cityid]])

    def getTile(self, x, y):
        '''Returns tile by coordinate. 
        Thankfully smart enough to find a way to not iterate
        '''
        value = y * self.region_size[0] + x
        return self.tiles[value]

    def unfoundCity(self, ident):
        '''Unfounds a city'''
        del self.cities[ident]

    def enterCity(self, ident):
        '''Processess information needed for graphical elements to enter city view.'''
        # We need to send list of tiles for terrain manager
        tiles = []
        xsum = 0
        ysum = 0
        n = 0
        for tile in self.tiles:
            if tile.cityid is ident:
                tiles.append(tile)
                # We need to compute center of city to target camera there
                xsum += tile.coords[0]
                ysum += tile.coords[1]
                n += 1
        xavg = xsum / n
        yavg = ysum / n
        position = (xavg, yavg)
        # We need to send city info so gui elements can be drawn
        city = self.cities[ident]
        messenger.send('enterCityView', [ident, city, position, tiles])
Пример #42
0
	def import_(self, file_name, palettes):
		from pandac.PandaModules import PNMImage, Filename, VBase4D
		from pandac.PandaModules import Texture as P3DTexture
		
		pnm = PNMImage()
		pnm.read(Filename.fromOsSpecific(file_name))
		
		tex_pnm = PNMImage(17*256, 1024)
		tex_pnm.addAlpha()
		
		
		#convert data to same sequence as files
		texdata = []
		for y in range(1024):
			row = []
			for x in range(256):
				gray = pnm.getXel(x, y)
				pal_i = int(gray[0] * 15.0)
				row.append(pal_i)
			texdata.append(row)
		
		#update saving texture
		testpnm = PNMImage(256, 1024)
		
		palette = [(x, x, x, 1) for x in range(16)]
		colors = []
		for color in palette:
			color_list = [c / 15.0 for c in color[:3]]
			color_list.append(0 if color == (0, 0, 0, 0) else 1)
			colors.append(VBase4D(*color_list))
			
		for y in range(1024):
			row = texdata[y]
			for x in range(256):
				testpnm.setXelA(x, y, colors[row[x]])
		
		self.texture2.load(testpnm)
		self.texture2.setMagfilter(P3DTexture.FTNearest)
		self.texture2.setMinfilter(P3DTexture.FTLinear)

		
		#update texture visible on map


		self.palettes = []
		temp = []
		for x in range (16):
			temp.append((x, x, x, 1))
			
		self.palettes.append(temp)
		
		for y, palette in enumerate(palettes):
			selfpalette = []
			for x, color in enumerate(palette.colors.colors):
				selfpalette.append((color[0],color[1],color[2],1))
			self.palettes.append(selfpalette)
		
		i = 0
		for palette in self.palettes:
			colors = []
			for color in palette:
				color_list = [c / 15.0 for c in color[:3]]
				color_list.append(0 if color == (0, 0, 0, 0) else 1)
				colors.append(VBase4D(*color_list))
				
			for y in range(1024):
				row = texdata[y]
				for x in range(256):
					tex_pnm.setXelA(x + (256*i), y, colors[row[x]])	
			i += 1
			
		self.texture.load(tex_pnm)
		self.texture.setMagfilter(P3DTexture.FTNearest)
		self.texture.setMinfilter(P3DTexture.FTLinear)	
class TerrainTile(GeoMipTerrain):
    """TerrainTiles are the building blocks of a terrain."""
    def __init__(self, terrain, x, y):
        """Builds a Tile for the terrain at input coordinates.

        Important settings are used directly from the terrain.
        This allows for easier setting changes, and reduces memory overhead.
        x and y parameters give the appropriate world coordinates of this tile.

        """

        self.terrain = terrain
        self.xOffset = x
        self.yOffset = y
        self.heightMapDetail = 1  # higher means greater detail

        self.name = "ID" + str(terrain.id) + "_X" + str(x) + "_Y" + str(y)
        GeoMipTerrain.__init__(self, name=self.name)

        self.image = PNMImage()

        #self.setAutoFlatten(GeoMipTerrain.AFMOff)
        self.setFocalPoint(self.terrain.focus)
        self.setAutoFlatten(GeoMipTerrain.AFMOff)
        self.getRoot().setPos(x, y, 0)
        if self.terrain.bruteForce:
            GeoMipTerrain.setBruteforce(self, True)
            GeoMipTerrain.setBlockSize(
                self, self.terrain.heightMapSize * self.heightMapDetail)
        else:
            GeoMipTerrain.setBlockSize(self, self.terrain.blockSize / 2)
            #self.setBorderStitching(1)
            self.setNear(self.terrain.near)
            self.setFar(self.terrain.far)

    def update(self):
        """Updates the GeoMip to use the correct LOD on each block."""

        #logging.info("TerrainTile.update()")
        GeoMipTerrain.update(self)

    @pstat
    def updateTask(self, task):
        """Updates the GeoMip to use the correct LOD on each block."""

        self.update()
        return task.again

    #@pstat
    def setHeightField(self, filename):
        """Set the GeoMip heightfield from a heightmap image."""

        GeoMipTerrain.setHeightfield(self, filename)

    @pstat
    def generate(self):
        GeoMipTerrain.generate(self)

    @pstat
    def setHeight(self):
        """Sets the height field to match the height map image."""

        self.setHeightField(self.image)

    @pstat
    def makeHeightMap(self):
        """Generate a new heightmap image.

        Panda3d GeoMipMaps require an image from which to build and update
        their height field. This function creates the correct image using the
        tile's position and the Terrain's getHeight() function.

        """

        if SAVED_HEIGHT_MAPS:
            fileName = "maps/height/" + self.name + ".png"
            self.getRoot().setTag('EditableTerrain', '1')
            if self.image.read(Filename(fileName)):
                logging.info("read heightmap from " + fileName)
                return

        heightMapSize = self.terrain.tileSize * self.heightMapDetail + 1
        self.image = PNMImage(heightMapSize, heightMapSize, 1, 65535)

        ySize = self.image.getYSize() - 1
        getHeight = self.terrain.getHeight
        setGray = self.image.setGray
        xo = self.xOffset
        yo = self.yOffset
        d = self.heightMapDetail

        for x in range(self.image.getXSize()):
            for y in range(ySize + 1):
                height = getHeight(x / d + xo, y / d + yo)
                #  feed pixel into image
                # why is it necessary to invert the y axis I wonder?
                setGray(x, ySize - y, height)
        #self.postProcessImage()
        if SAVED_HEIGHT_MAPS:
            fileName = "maps/height/" + self.name + ".png"
            logging.info("saving heightmap to " + fileName)
            self.image.write(Filename(fileName))

    def postProcessImage(self):
        """Perform filters and manipulations on the heightmap image."""

        #self.image.gaussianFilter()

    def setWireFrame(self, state):
        self.getRoot().setRenderModeWireframe()

    def makeSlopeMap(self):

        self.slopeMap = PNMImage()
        if SAVED_SLOPE_MAPS:
            fileName = "maps/slope/" + self.name + ".png"
            if self.slopeMap.read(Filename(fileName)):
                logging.info("read slopemap from " + fileName)
                return

        self.slopeMap = PNMImage(self.terrain.heightMapSize,
                                 self.terrain.heightMapSize)
        self.slopeMap.makeGrayscale()
        self.slopeMap.setMaxval(65535)

        size = self.slopeMap.getYSize()
        getNormal = self.getNormal
        setGray = self.slopeMap.setGray

        for x in range(size):
            for y in range(size):
                #note getNormal works at the same resolution as the heightmap
                normal = getNormal(x, y)
                #  feed pixel into image
                # why is it necessary to invert the y axis I wonder?
                #logging.info( normal)
                normal.z /= self.terrain.getSz()
                normal.normalize()
                slope = 1.0 - normal.dot(Vec3(0, 0, 1))
                setGray(x, y, slope)

        if SAVED_SLOPE_MAPS:
            fileName = "maps/slope/" + self.name + ".png"
            logging.info("saving slopemap to " + fileName)
            self.slopeMap.write(Filename(fileName))

    def createGroups(self):
        self.statics = self.getRoot().attachNewNode(self.name + "_statics")
        self.statics.setSz(1.0 / self.terrain.getSz())
        self.statics.setSx(1.0 / self.terrain.getSx())
        self.statics.setSy(1.0 / self.terrain.getSy())

        self.statics.setShaderAuto()

    @pstat
    def make(self):
        """Build a finished renderable heightMap."""

        # apply shader
        #logging.info( "applying shader")
        self.terrain.texturer.apply(self.getRoot())

        # detail settings
        #self.getRoot().setSx(1.0 / self.heightMapDetail)
        #self.getRoot().setSy(1.0 / self.heightMapDetail)

        #logging.info( "making height map")
        self.makeHeightMap()
        #logging.info( "setHeight()")
        self.setHeight()
        #self.getRoot().setSz(self.maxHeight)

        #http://www.panda3d.org/forums/viewtopic.php?t=12054
        self.calcAmbientOcclusion()
        #logging.info( "generate()")
        self.generate()
        self.getRoot().setCollideMask(BitMask32.bit(1))

        #self.makeSlopeMap()
        #logging.info( "createGroups()")
        self.createGroups()
        self.terrain.populator.populate(self)
Пример #44
0
    def _loadInternal(self,
                      resType,
                      filename,
                      locationName=None,
                      preloading=False):
        '''
        Manages the actual loading of a resource given the resource filename and the resource location
        that contains it.

        @param resType: A constant that identifies the type of the resource.
        @param filename: The filename of the resource.
        @param locationName: The name of the resource location containing the resource. This is optional.
        @return: A pano.resources.Resource instance if preloading is True, or the actual resource instance
        if preloading is False or finally None if the resource couldn't be found.
        '''

        self.requests += 1

        if locationName is not None:
            location = self.locationsByName.get(locationName)
        else:
            location = self.locateResource(resType, filename)
        if location is None:
            self.log.error('Failed to locate resource %s' % filename)
            return None

        # get the full path to query the cache, sticky and preload stores
        fullPath = location.getResourceFullPath(filename)
        if fullPath is None:
            self.log.error('Failed to get full path to resource %s' % filename)
            return None

        # resource locations can be sticky
        if location.sticky:
            resource = self._getStickyResource(fullPath, resType)
            if resource is not None:
                if self.log.isEnabledFor(logging.DEBUG):
                    self.log.debug('Returning sticky resource %s' % fullPath)

                self.stickyLoads += 1
                if not preloading:
                    resource.requested = True
                return resource.data if not preloading else resource

        # if the location has a preload flag, then search first in the preload store
        if location.preload:
            resource = self._fetchPreloaded(fullPath, location.name)
            if resource is not None:
                self.preloadHits += 1
                if not preloading:
                    resource.requested = True
                return resource.data if not preloading else resource
            else:
                self.preloadMisses += 1

        # then search in our cache
#        resource = self._cacheLookup(fullPath, location.name)
#        if resource is not None:
#            if self.log.isEnabledFor(logging.DEBUG):
#                self.log.debug('Returning cached instance of resource %s' % fullPath)
#            if not preloading:
#                resource.requested = True
#            return resource.data if not preloading else resource

# finally load it from the resource location
        if ResourcesTypes.isParsedResource(resType):
            # Convention: construct resource name from the basename of the filename and by dropping the extension.
            resName = os.path.basename(filename)
            extIndex = resName.rfind('.')
            if extIndex >= 0:
                resName = resName[:extIndex]

            resData = self._loadParsedResource(resType, resName, fullPath,
                                               location)

        else:
            if ResourcesTypes.isPandaResource(resType):
                # for Panda resources we use the BaseLoader
                resName = filename
                try:
                    if resType == PanoConstants.RES_TYPE_MODELS:
                        resData = loader.loadModel(fullPath)

                    elif resType == PanoConstants.RES_TYPE_TEXTURES or resType == PanoConstants.RES_TYPE_VIDEOS:
                        resData = loader.loadTexture(fullPath)

                    elif resType == PanoConstants.RES_TYPE_IMAGES:
                        img = PNMImage()
                        img.read(fullPath)
                        resData = img

                    elif resType == PanoConstants.RES_TYPE_MUSIC:
                        resData = loader.loadMusic(fullPath)

                    elif resType == PanoConstants.RES_TYPE_SFX:
                        resData = loader.loadSfx(fullPath)

                    elif resType == PanoConstants.RES_TYPE_SHADERS:
                        resData = Shader.load(fullPath)

                except Exception:
                    self.log.exception(
                        'Panda loader failed to load resource %s' % fullPath)
                    return None

            elif ResourcesTypes.isStreamResource(resType):
                # we consider character based and binary based streams
                # by handling stream resources in a special way we can perhaps provide more efficient
                # handling of streams, i.e. memory mapped files, compressed streams, decryption, etc.
                resName = filename
                if resType == PanoConstants.RES_TYPE_SCRIPTS or resType == PanoConstants.RES_TYPE_TEXTS:
                    resData = self._loadCharacterStream(fullPath, location)
                else:
                    resData = self._loadBinaryStream(fullPath, location)

            elif ResourcesTypes.isOpaqueResource(resType):
                # opaque resources perform their own loading, we only load the file's contents without caring
                # about how it looks and pass it to the read() method.
                resName = os.path.basename(filename)
                resData = ResourcesTypes.constructOpaqueResource(
                    resType, resName, filename)
                opaque = self._loadBinaryStream(fullPath, location)
                fp = StringIO.StringIO(opaque)
                resData.read(fp)

            if resData is None:
                self.log.error('Failed to load resource %s' % fullPath)
                return None

        resource = Resource(resName, resData, resType, fullPath, location.name)
        resource.sticky = location.sticky
        resource.preload = location.preload
        if not preloading:
            resource.requested = True

        # consider caching the resource
        if not resource.sticky and not resource.preload:
            self._cacheResource(fullPath, resource, location.name)

        elif resource.sticky:
            self._addStickyResource(fullPath, resource, location.name)

        # when we are preloading, return the Resource instance instead
        return resource.data if not preloading else resource
Пример #45
0
class HtmlView(DirectObject):

    notify = DirectNotifyGlobal.directNotify.newCategory("HtmlView")
    useHalfTexture = base.config.GetBool("news-half-texture", 0)

    def __init__(self, parent=aspect2d):
        """Properly initialize ourself."""
        #AwWebViewListener.AwWebViewListener.__init__(self)
        self.parent = parent
        self.mx = 0
        self.my = 0
        self.htmlFile = "index.html"
        self.transparency = False  # this is important looks weird if it's true
        global GlobalWebcore
        if GlobalWebcore:
            # we get a C++ crash if we construct webcore a second time
            pass
        else:
            GlobalWebcore = AwWebCore(AwWebCore.LOGVERBOSE, True,
                                      AwWebCore.PFBGRA)
            GlobalWebcore.setBaseDirectory('.')
            for errResponse in xrange(400, 600):
                GlobalWebcore.setCustomResponsePage(errResponse, "error.html")

        self.webView = GlobalWebcore.createWebView(WEB_WIDTH, WEB_HEIGHT,
                                                   self.transparency, False,
                                                   70)
        #self.webView.setListener(self)
        #self.webView.setCallback("requestFPS");
        frameName = ''
        inGameNewsUrl = self.getInGameNewsUrl()
        #self.webView.loadURL2(inGameNewsUrl)

        self.imgBuffer = array.array('B')
        for i in xrange(WEB_WIDTH * WEB_HEIGHT):
            self.imgBuffer.append(0)
            self.imgBuffer.append(0)
            self.imgBuffer.append(0)
            self.imgBuffer.append(255)

        if self.useHalfTexture:
            self.leftBuffer = array.array('B')
            for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
                self.leftBuffer.append(0)
                self.leftBuffer.append(0)
                self.leftBuffer.append(0)
                self.leftBuffer.append(255)
            self.rightBuffer = array.array('B')
            for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
                self.rightBuffer.append(0)
                self.rightBuffer.append(0)
                self.rightBuffer.append(0)
                self.rightBuffer.append(255)

        self.setupTexture()
        if self.useHalfTexture:
            self.setupHalfTextures()

        #self.interval = LerpHprInterval(self.quad, 2, Vec3(360, 0, 0), Vec3(0, 0, 0))

        #self.accept("escape", sys.exit, [0])
        #self.accept("w", self.writeTex)

        self.accept("mouse1", self.mouseDown, [AwWebView.LEFTMOUSEBTN])
        self.accept("mouse3", self.mouseDown, [AwWebView.RIGHTMOUSEBTN])
        self.accept("mouse1-up", self.mouseUp, [AwWebView.LEFTMOUSEBTN])
        self.accept("mouse3-up", self.mouseUp, [AwWebView.RIGHTMOUSEBTN])

        #self.accept("f1", self.toggleRotation)
        #self.accept("f2", self.toggleTransparency)
        #self.accept("f3", self.reload)
        #self.accept("f4", self.zoomIn)
        #self.accept("f5", self.zoomOut)

        #taskMgr.doMethodLater(1.0, self.update, 'HtmlViewUpdateTask')
        # we get a problem if a mid-frame hearbeat fires of this task in conjunction with igLoop
        #taskMgr.add(self.update, 'HtmlViewUpdateTask',  priority = 51)
        #taskMgr.add(self.update, 'HtmlViewUpdateTask')
        #base.newsFrame = self

    def getInGameNewsUrl(self):
        """Get the appropriate URL to use if we are in test, qa, or live."""
        # First if all else fails, we hard code the live news url
        result = base.config.GetString(
            "fallback-news-url",
            "http://cdn.toontown.disney.go.com/toontown/en/gamenews/")
        # next check if we have an override, say they want to url to point to a file in their harddisk
        override = base.config.GetString("in-game-news-url", "")
        if override:
            self.notify.info(
                "got an override url,  using %s for in a game news" % override)
            result = override
        else:
            try:
                launcherUrl = base.launcher.getValue("GAME_IN_GAME_NEWS_URL",
                                                     "")
                if launcherUrl:
                    result = launcherUrl
                    self.notify.info(
                        "got GAME_IN_GAME_NEWS_URL from launcher using %s" %
                        result)
                else:
                    self.notify.info(
                        "blank GAME_IN_GAME_NEWS_URL from launcher, using %s" %
                        result)

            except:
                self.notify.warning(
                    "got exception getting GAME_IN_GAME_NEWS_URL from launcher, using %s"
                    % result)
        return result

    def setupTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)

        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)

        # the html area will be center aligned and vertically top aligned
        #cm.setFrame(-htmlWidth/2.0, htmlWidth/2.0, 1.0 - htmlHeight, 1.0)
        cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0,
                    htmlHeight / 2.0)

        bottomRightX = (WEB_WIDTH_PIXELS) / float(WEB_WIDTH + 1)
        bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)

        #cm.setUvRange(Point2(0,0), Point2(bottomRightX, bottomRightY))
        cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))

        card = cm.generate()
        self.quad = NodePath(card)
        self.quad.reparentTo(self.parent)

        self.guiTex = Texture("guiTex")
        self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1,
                                 Texture.TUnsignedByte, Texture.FRgba)
        self.guiTex.setMinfilter(Texture.FTLinear)
        self.guiTex.setKeepRamImage(True)
        self.guiTex.makeRamImage()
        self.guiTex.setWrapU(Texture.WMRepeat)
        self.guiTex.setWrapV(Texture.WMRepeat)

        ts = TextureStage('webTS')
        self.quad.setTexture(ts, self.guiTex)
        self.quad.setTexScale(ts, 1.0, -1.0)

        self.quad.setTransparency(0)
        self.quad.setTwoSided(True)
        self.quad.setColor(1.0, 1.0, 1.0, 1.0)
        #self.quad.setZ(0.1) # shtickerbook is moved up by 0.1

        self.calcMouseLimits()

    def setupHalfTextures(self):
        self.setupLeftTexture()
        self.setupRightTexture()
        self.fullPnmImage = PNMImage(WEB_WIDTH, WEB_HEIGHT, 4)
        self.leftPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
        self.rightPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)

    def setupLeftTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)

        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)

        # the html area will be center aligned and vertically top aligned
        #cm.setFrame(-htmlWidth/2.0, htmlWidth/2.0, 1.0 - htmlHeight, 1.0)
        cm.setFrame(-htmlWidth / 2.0, 0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.leftQuad = NodePath(card)
        self.leftQuad.reparentTo(self.parent)

        self.leftGuiTex = Texture("guiTex")
        self.leftGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH,
                                     WEB_HEIGHT, 1, Texture.TUnsignedByte,
                                     Texture.FRgba)
        self.leftGuiTex.setKeepRamImage(True)
        self.leftGuiTex.makeRamImage()
        self.leftGuiTex.setWrapU(Texture.WMClamp)
        self.leftGuiTex.setWrapV(Texture.WMClamp)

        ts = TextureStage('leftWebTS')
        self.leftQuad.setTexture(ts, self.leftGuiTex)
        self.leftQuad.setTexScale(ts, 1.0, -1.0)

        self.leftQuad.setTransparency(0)
        self.leftQuad.setTwoSided(True)
        self.leftQuad.setColor(1.0, 1.0, 1.0, 1.0)
        #self.quad.setZ(0.1) # shtickerbook is moved up by 0.1

    def setupRightTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)

        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)

        # the html area will be center aligned and vertically top aligned
        #cm.setFrame(-htmlWidth/2.0, htmlWidth/2.0, 1.0 - htmlHeight, 1.0)
        cm.setFrame(0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.rightQuad = NodePath(card)
        self.rightQuad.reparentTo(self.parent)

        self.rightGuiTex = Texture("guiTex")
        self.rightGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH,
                                      WEB_HEIGHT, 1, Texture.TUnsignedByte,
                                      Texture.FRgba)
        self.rightGuiTex.setKeepRamImage(True)
        self.rightGuiTex.makeRamImage()
        self.rightGuiTex.setWrapU(Texture.WMClamp)
        self.rightGuiTex.setWrapV(Texture.WMClamp)

        ts = TextureStage('rightWebTS')
        self.rightQuad.setTexture(ts, self.rightGuiTex)
        self.rightQuad.setTexScale(ts, 1.0, -1.0)

        self.rightQuad.setTransparency(0)
        self.rightQuad.setTwoSided(True)
        self.rightQuad.setColor(1.0, 1.0, 1.0, 1.0)
        #self.quad.setZ(0.1) # shtickerbook is moved up by 0.1

    def calcMouseLimits(self):
        ll = Point3()
        ur = Point3()
        self.quad.calcTightBounds(ll, ur)
        self.notify.debug("ll=%s ur=%s" % (ll, ur))

        # we need to get our relative position to aspect2d, since shtiker books is shifted
        offset = self.quad.getPos(aspect2d)
        self.notify.debug("offset = %s " % offset)
        ll.setZ(ll.getZ() + offset.getZ())
        ur.setZ(ur.getZ() + offset.getZ())

        self.notify.debug("new LL=%s, UR=%s" % (ll, ur))

        relPointll = self.quad.getRelativePoint(aspect2d, ll)
        self.notify.debug("relPoint = %s" % relPointll)
        self.mouseLL = (aspect2d.getScale()[0] * ll[0],
                        aspect2d.getScale()[2] * ll[2])
        self.mouseUR = (aspect2d.getScale()[0] * ur[0],
                        aspect2d.getScale()[2] * ur[2])
        self.notify.debug("original mouseLL=%s, mouseUR=%s" %
                          (self.mouseLL, self.mouseUR))

    def writeTex(self, filename="guiText.png"):
        self.notify.debug("writing texture")
        self.guiTex.generateRamMipmapImages()
        self.guiTex.write(filename)

    def toggleRotation(self):
        if self.interval.isPlaying():
            self.interval.finish()
        else:
            self.interval.loop()

    def mouseDown(self, button):
        messenger.send('wakeup')
        self.webView.injectMouseDown(button)

    def mouseUp(self, button):
        self.webView.injectMouseUp(button)

    def reload(self):
        pass
        #self.webView.loadFile(self.htmlFile, '')

    def zoomIn(self):
        self.webView.zoomIn()

    def zoomOut(self):
        self.webView.zoomOut()

    def toggleTransparency(self):
        self.transparency = not self.transparency
        self.webView.setTransparent(self.transparency)

    def update(self, task):
        global GlobalWebcore
        if base.mouseWatcherNode.hasMouse():
            x, y = self._translateRelativeCoordinates(
                base.mouseWatcherNode.getMouseX(),
                base.mouseWatcherNode.getMouseY())
            #self.notify.debug('got mouse move %d %d' % (x,y))
            #self.webView.injectMouseMove(x, y)

            if (self.mx - x) != 0 or (self.my - y) != 0:
                self.webView.injectMouseMove(x, y)
                #self.notify.debug('injecting mouse move %d %d' % (x,y))
                self.mx, self.my = x, y

            if self.webView.isDirty():
                #self.notify.debug("webview is dirty")
                self.webView.render(self.imgBuffer.buffer_info()[0],
                                    WEB_WIDTH * 4, 4)
                #Texture.setTexturesPower2(AutoTextureScale.ATSUp)
                Texture.setTexturesPower2(2)
                #self.notify.debug("about to modify ram image")
                textureBuffer = self.guiTex.modifyRamImage()
                #import pdb; pdb.set_trace()
                #self.notify.debug("about to call textureBuffer.setData")
                textureBuffer.setData(self.imgBuffer.tostring())
                #self.notify.debug("done calling setData")
                if self.useHalfTexture:
                    # TODO check with DRose, this feels inefficient
                    self.guiTex.store(self.fullPnmImage)
                    self.leftPnmImage.copySubImage(self.fullPnmImage, 0, 0, 0,
                                                   0, WEB_HALF_WIDTH,
                                                   WEB_HEIGHT)
                    self.rightPnmImage.copySubImage(self.fullPnmImage, 0, 0,
                                                    WEB_HALF_WIDTH, 0,
                                                    WEB_HALF_WIDTH, WEB_HEIGHT)
                    self.leftGuiTex.load(self.leftPnmImage)
                    self.rightGuiTex.load(self.rightPnmImage)
                    self.quad.hide()
                #Texture.setTexturesPower2(AutoTextureScale.ATSDown)
                Texture.setTexturesPower2(1)

            GlobalWebcore.update()
        return Task.cont

    def _translateRelativeCoordinates(self, x, y):
        sx = int((x - self.mouseLL[0]) / (self.mouseUR[0] - self.mouseLL[0]) *
                 WEB_WIDTH_PIXELS)
        sy = WEB_HEIGHT_PIXELS - int(
            (y - self.mouseLL[1]) /
            (self.mouseUR[1] - self.mouseLL[1]) * WEB_HEIGHT_PIXELS)
        return sx, sy

    def unload(self):
        """Clean up everything, especially the awesomium bits."""
        self.ignoreAll()
        self.webView.destroy()
        self.webView = None
        #global GlobalWebcore
        #GlobalWebcore = None
        pass

    # --------------------[ WebViewListener implementation ]--------------------------
    def onCallback(self, name, args):
        assert self.notify.debugStateCall(self)
        if name == "requestFPS":
            #self.webView.setProperty( "fps", JSValue("%.1f" % (1.0 / globalClock.getDt())) )
            #self.webView.executeJavascript("updateFPS()", "")
            pass

    def onBeginNavigation(self, url, frameName):
        assert self.notify.debugStateCall(self)
        pass

    def onBeginLoading(self, url, frameName, statusCode, mimeType):
        assert self.notify.debugStateCall(self)
        pass

    def onFinishLoading(self):
        assert self.notify.debugStateCall(self)
        self.notify.debug("finished loading")
        pass

    def onReceiveTitle(self, title, frameName):
        assert self.notify.debugStateCall(self)
        pass

    def onChangeTooltip(self, tooltip):
        assert self.notify.debugStateCall(self)
        pass

    def onChangeCursor(self, cursor):
        assert self.notify.debugStateCall(self)
        pass

    def onChangeKeyboardFocus(self, isFocused):
        assert self.notify.debugStateCall(self)
        pass

    def onChangeTargetURL(self, url):
        assert self.notify.debugStateCall(self)
        pass
Пример #46
0
def transparencyKey(filename):
    image = PNMImage(GAME+'/textures/effects/'+filename)
    image.addAlpha()
    backgroundColor = None
    for y in range(image.getYSize()):
        for x in range(image.getXSize()):
            if backgroundColor == None:
                backgroundColor = Color(image.getRedVal(x, y), image.getGreenVal(x, y), image.getGreenVal(x, y), 0)
            if image.getRedVal(x, y) == backgroundColor.R and \
                image.getGreenVal(x, y) == backgroundColor.G and \
                image.getGreenVal(x, y) == backgroundColor.B:
                # Transparent
                image.setAlpha(x, y, 0.0)
            else:
                # Opaque
                image.setAlpha(x, y, 1.0) 
    return image
Пример #47
0
class Sprite2d:
    class Cell:
        def __init__(self, col, row):
            self.col = col
            self.row = row

        def __str__(self):
            return "Cell - Col %d, Row %d" % (self.col, self.row)

    class Animation:
        def __init__(self, cells, fps):
            self.cells = cells
            self.fps = fps
            self.playhead = 0

    ALIGN_CENTER = "Center"
    ALIGN_LEFT = "Left"
    ALIGN_RIGHT = "Right"
    ALIGN_BOTTOM = "Bottom"
    ALIGN_TOP = "Top"

    TRANS_ALPHA = TransparencyAttrib.MAlpha
    TRANS_DUAL = TransparencyAttrib.MDual
    # One pixel is divided by this much. If you load a 100x50 image with PIXEL_SCALE of 10.0
    # you get a card that is 1 unit wide, 0.5 units high
    PIXEL_SCALE = 20.0

    def __init__(self, image_path, rowPerFace, name=None,\
         rows=1, cols=1, scale=1.0,\
         twoSided=False, alpha=TRANS_ALPHA,\
         repeatX=1, repeatY=1,\
         anchorX=ALIGN_CENTER, anchorY=ALIGN_BOTTOM):
        """
		Create a card textured with an image. The card is sized so that the ratio between the
		card and image is the same.
		"""

        global SpriteId
        self.spriteNum = str(SpriteId)
        SpriteId += 1

        scale *= self.PIXEL_SCALE

        self.animations = {}

        self.scale = scale
        self.repeatX = repeatX
        self.repeatY = repeatY
        self.flip = {'x': False, 'y': False}
        self.rows = rows
        self.cols = cols

        self.currentFrame = 0
        self.currentAnim = None
        self.loopAnim = False
        self.frameInterrupt = True

        # Create the NodePath
        if name:
            self.node = NodePath("Sprite2d:%s" % name)
        else:
            self.node = NodePath("Sprite2d:%s" % image_path)

        # Set the attribute for transparency/twosided
        self.node.node().setAttrib(TransparencyAttrib.make(alpha))
        if twoSided:
            self.node.setTwoSided(True)

        # Make a filepath
        self.imgFile = Filename(image_path)
        if self.imgFile.empty():
            raise IOError, "File not found"

        # Instead of loading it outright, check with the PNMImageHeader if we can open
        # the file.
        imgHead = PNMImageHeader()
        if not imgHead.readHeader(self.imgFile):
            raise IOError, "PNMImageHeader could not read file. Try using absolute filepaths"

        # Load the image with a PNMImage
        image = PNMImage()
        image.read(self.imgFile)

        self.sizeX = image.getXSize()
        self.sizeY = image.getYSize()

        # We need to find the power of two size for the another PNMImage
        # so that the texture thats loaded on the geometry won't have artifacts
        textureSizeX = self.nextsize(self.sizeX)
        textureSizeY = self.nextsize(self.sizeY)

        # The actual size of the texture in memory
        self.realSizeX = textureSizeX
        self.realSizeY = textureSizeY

        self.paddedImg = PNMImage(textureSizeX, textureSizeY)
        if image.hasAlpha():
            self.paddedImg.alphaFill(0)
        # Copy the source image to the image we're actually using
        self.paddedImg.blendSubImage(image, 0, 0)
        # We're done with source image, clear it
        image.clear()

        # The pixel sizes for each cell
        self.colSize = self.sizeX / self.cols
        self.rowSize = self.sizeY / self.rows

        # How much padding the texture has
        self.paddingX = textureSizeX - self.sizeX
        self.paddingY = textureSizeY - self.sizeY

        # Set UV padding
        self.uPad = float(self.paddingX) / textureSizeX
        self.vPad = float(self.paddingY) / textureSizeY

        # The UV dimensions for each cell
        self.uSize = (1.0 - self.uPad) / self.cols
        self.vSize = (1.0 - self.vPad) / self.rows

        self.cards = []
        self.rowPerFace = rowPerFace
        for i in range(len(rowPerFace)):
            card = CardMaker("Sprite2d-Geom")

            # The positions to create the card at
            if anchorX == self.ALIGN_LEFT:
                posLeft = 0
                posRight = (self.colSize / scale) * repeatX
            elif anchorX == self.ALIGN_CENTER:
                posLeft = -(self.colSize / 2.0 / scale) * repeatX
                posRight = (self.colSize / 2.0 / scale) * repeatX
            elif anchorX == self.ALIGN_RIGHT:
                posLeft = -(self.colSize / scale) * repeatX
                posRight = 0

            if anchorY == self.ALIGN_BOTTOM:
                posTop = 0
                posBottom = (self.rowSize / scale) * repeatY
            elif anchorY == self.ALIGN_CENTER:
                posTop = -(self.rowSize / 2.0 / scale) * repeatY
                posBottom = (self.rowSize / 2.0 / scale) * repeatY
            elif anchorY == self.ALIGN_TOP:
                posTop = -(self.rowSize / scale) * repeatY
                posBottom = 0

            card.setFrame(posLeft, posRight, posTop, posBottom)
            card.setHasUvs(True)
            self.cards.append(self.node.attachNewNode(card.generate()))
            self.cards[-1].setH(i * 360 / len(rowPerFace))

        # Since the texture is padded, we need to set up offsets and scales to make
        # the texture fit the whole card
        self.offsetX = (float(self.colSize) / textureSizeX)
        self.offsetY = (float(self.rowSize) / textureSizeY)

        # self.node.setTexScale(TextureStage.getDefault(), self.offsetX * repeatX, self.offsetY * repeatY)
        # self.node.setTexOffset(TextureStage.getDefault(), 0, 1-self.offsetY)

        self.texture = Texture()

        self.texture.setXSize(textureSizeX)
        self.texture.setYSize(textureSizeY)
        self.texture.setZSize(1)

        # Load the padded PNMImage to the texture
        self.texture.load(self.paddedImg)

        self.texture.setMagfilter(Texture.FTNearest)
        self.texture.setMinfilter(Texture.FTNearest)

        #Set up texture clamps according to repeats
        if repeatX > 1:
            self.texture.setWrapU(Texture.WMRepeat)
        else:
            self.texture.setWrapU(Texture.WMClamp)
        if repeatY > 1:
            self.texture.setWrapV(Texture.WMRepeat)
        else:
            self.texture.setWrapV(Texture.WMClamp)

        self.node.setTexture(self.texture)
        self.setFrame(0)

    def nextsize(self, num):
        """ Finds the next power of two size for the given integer. """
        p2x = max(1, log(num, 2))
        notP2X = modf(p2x)[0] > 0
        return 2**int(notP2X + p2x)

    def setFrame(self, frame=0):
        """ Sets the current sprite to the given frame """
        self.frameInterrupt = True  # A flag to tell the animation task to shut it up ur face
        self.currentFrame = frame
        self.flipTexture()

    def playAnim(self, animName, loop=False):
        """ Sets the sprite to animate the given named animation. Booleon to loop animation"""
        if not taskMgr.hasTaskNamed("Animate sprite" + self.spriteNum):
            if hasattr(self, "task"):
                taskMgr.remove("Animate sprite" + self.spriteNum)
                del self.task
            self.frameInterrupt = False  # Clear any previous interrupt flags
            self.loopAnim = loop
            self.currentAnim = self.animations[animName]
            self.currentAnim.playhead = 0
            self.task = taskMgr.doMethodLater(
                1.0 / self.currentAnim.fps, self.animPlayer,
                "Animate sprite" + self.spriteNum)

    def createAnim(self, animName, frameCols, fps=12):
        """ Create a named animation. Takes the animation name and a tuple of frame numbers """
        self.animations[animName] = Sprite2d.Animation(frameCols, fps)
        return self.animations[animName]

    def flipX(self, val=None):
        """ Flip the sprite on X. If no value given, it will invert the current flipping."""
        if val:
            self.flip['x'] = val
        else:
            if self.flip['x']:
                self.flip['x'] = False
            else:
                self.flip['x'] = True
        self.flipTexture()
        return self.flip['x']

    def flipY(self, val=None):
        """ See flipX """
        if val:
            self.flip['y'] = val
        else:
            if self.flip['y']:
                self.flip['y'] = False
            else:
                self.flip['y'] = True
        self.flipTexture()
        return self.flip['y']

    def updateCameraAngle(self, cameraNode):
        baseH = cameraNode.getH(render) - self.node.getH(render)
        degreesBetweenCards = 360 / len(self.cards)
        bestCard = int(
            ((baseH) + degreesBetweenCards / 2) % 360 / degreesBetweenCards)
        #print baseH, bestCard
        for i in range(len(self.cards)):
            if i == bestCard:
                self.cards[i].show()
            else:
                self.cards[i].hide()

    def flipTexture(self):
        """ Sets the texture coordinates of the texture to the current frame"""
        for i in range(len(self.cards)):
            currentRow = self.rowPerFace[i]

            sU = self.offsetX * self.repeatX
            sV = self.offsetY * self.repeatY
            oU = 0 + self.currentFrame * self.uSize
            #oU = 0 + self.frames[self.currentFrame].col * self.uSize
            #oV = 1 - self.frames[self.currentFrame].row * self.vSize - self.offsetY
            oV = 1 - currentRow * self.vSize - self.offsetY
            if self.flip['x'] ^ i == 1:  ##hack to fix side view
                #print "flipping, i = ",i
                sU *= -1
                #oU = self.uSize + self.frames[self.currentFrame].col * self.uSize
                oU = self.uSize + self.currentFrame * self.uSize
            if self.flip['y']:
                sV *= -1
                #oV = 1 - self.frames[self.currentFrame].row * self.vSize
                oV = 1 - currentRow * self.vSize
            self.cards[i].setTexScale(TextureStage.getDefault(), sU, sV)
            self.cards[i].setTexOffset(TextureStage.getDefault(), oU, oV)

    def clear(self):
        """ Free up the texture memory being used """
        self.texture.clear()
        self.paddedImg.clear()
        self.node.removeNode()

    def animPlayer(self, task):
        if self.frameInterrupt:
            return task.done
        #print "Playing",self.currentAnim.cells[self.currentAnim.playhead]
        self.currentFrame = self.currentAnim.cells[self.currentAnim.playhead]
        self.flipTexture()
        if self.currentAnim.playhead + 1 < len(self.currentAnim.cells):
            self.currentAnim.playhead += 1
            return task.again
        if self.loopAnim:
            self.currentAnim.playhead = 0
            return task.again
Пример #48
0
    def get_map_3d_tex(self, size, filename=None, charPos=None):
        """Generate texture of map
        """
        mod = self.world_size / size
        image = PNMImage(size, size)
        for x in xrange(size):
            for y in xrange(size):
                px = x * mod
                py = y * mod
                height = self[px, py]
                if height <= 0:
                    color = (abs(height) / 50) + 50
                    if color > 255:
                        color = 255
                    image.setPixel(x, y, (0, 0, 255 - color))
                else:
                    if height <= self.config.low_mount_level[1]:
                        color = height / 20
                        r = 0
                        g = 50 + color
                        b = 0
                        image.setPixel(x, y, (r, g, b))
                    elif height > self.config.low_mount_level[1]:
                        color = height / 50
                        r = color
                        g = color
                        b = color
                        if r > 255:
                            r = 255
                        if g > 255:
                            r = 255
                        if b > 255:
                            b = 255
                        image.setPixel(x, y, (r, g, b))

        if filename != None:
            image.write(filename)

        if charPos != None:
            charX, charY = charPos
            for x in xrange(-1, 2):
                for y in xrange(-1, 2):
                    image.setPixel(
                        int(charX / mod) + x,
                        int(charY / mod) + y, (255, 0, 0))

        texture = Texture()
        texture.load(image)
        return texture
Пример #49
0
class MazeMapGui(DirectFrame):
    __module__ = __name__
    notify = directNotify.newCategory('MazeMapGui')

    def __init__(self,
                 mazeCollTable,
                 maskResolution=None,
                 radiusRatio=None,
                 bgColor=(0.8, 0.8, 0.8),
                 fgColor=(0.5, 0.5, 0.5, 1.0)):
        DirectFrame.__init__(self,
                             relief=None,
                             state=DGG.NORMAL,
                             sortOrder=DGG.BACKGROUND_SORT_INDEX)
        self.hide()
        self._bgColor = bgColor
        self._fgColor = fgColor
        self._mazeCollTable = mazeCollTable
        self._mazeWidth = len(self._mazeCollTable[0])
        self._mazeHeight = len(self._mazeCollTable)
        if not maskResolution:
            self._maskResolution = DEFAULT_MASK_RESOLUTION
            self._radius = radiusRatio is None and self._maskResolution * DEFAULT_RADIUS_RATIO
        else:
            self._radius = self._maskResolution * radiusRatio
        self._revealedCells = []
        for y in range(self._mazeHeight):
            self._revealedCells.append([])
            for u in range(self._mazeWidth):
                self._revealedCells[y].append(False)

        self._revealFunctions = {
            MazeRevealType.SmoothCircle: self._revealSmoothCircle,
            MazeRevealType.HardCircle: self._revealHardCircle,
            MazeRevealType.Square: self._revealSquare
        }
        self._revealFunction = MAZE_REVEAL_TYPE
        self.map = self._createMapTextureCard()
        self.map.reparentTo(self)
        self.maskedLayer = self.attachNewNode('maskedLayer')
        self.mask = self._createMaskTextureCard()
        self.mask.reparentTo(self)
        self.visibleLayer = self.attachNewNode('visibleLayer')
        self._laffMeterModel = loader.loadModel(
            'phase_3/models/gui/laff_o_meter')
        self._toon2marker = {}
        return

    def _createMapTextureCard(self):
        mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION)
        mapImage.fill(*self._bgColor)
        fgColor = VBase4D(*self._fgColor)
        for x in range(self._mazeHeight):
            for y in range(self._mazeWidth):
                if self._mazeCollTable[y][x] == 1:
                    ax = float(x) / self._mazeWidth * MAP_RESOLUTION
                    invertedY = self._mazeHeight - 1 - y
                    ay = float(invertedY) / self._mazeHeight * MAP_RESOLUTION
                    self._drawSquare(mapImage, int(ax), int(ay), 10, fgColor)

        mapTexture = Texture('mapTexture')
        mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution,
                                self._maskResolution, 1, Texture.TUnsignedByte,
                                Texture.FRgba)
        mapTexture.setMinfilter(Texture.FTLinear)
        mapTexture.load(mapImage)
        mapTexture.setWrapU(Texture.WMClamp)
        mapTexture.setWrapV(Texture.WMClamp)
        mapImage.clear()
        del mapImage
        cm = CardMaker('map_cardMaker')
        cm.setFrame(-1.0, 1.0, -1.0, 1.0)
        map = self.attachNewNode(cm.generate())
        map.setTexture(mapTexture, 1)
        return map

    def _createMaskTextureCard(self):
        self._maskImage = PNMImage(self._maskResolution, self._maskResolution,
                                   4)
        for x in range(self._maskResolution):
            for y in range(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)

        self.maskTexture = Texture('maskTexture')
        self.maskTexture.setupTexture(Texture.TT2dTexture,
                                      self._maskResolution,
                                      self._maskResolution, 1,
                                      Texture.TUnsignedByte, Texture.FRgba)
        self.maskTexture.setMinfilter(Texture.FTLinear)
        self.maskTexture.setWrapU(Texture.WMClamp)
        self.maskTexture.setWrapV(Texture.WMClamp)
        self.maskTexture.load(self._maskImage)
        base.graphicsEngine.renderFrame()
        cm = CardMaker('mask_cardMaker')
        cm.setFrame(-1.1, 1.1, -1.1, 1.1)
        mask = self.attachNewNode(cm.generate())
        mask.setTexture(self.maskTexture, 1)
        mask.setTransparency(1)
        return mask

    def _drawSquare(self, image, ulx, uly, size, color):
        x = int(ulx)
        while x <= ulx + size:
            y = int(uly)
            while y <= uly + size:
                if x > 0 and y > 0 and x < image.getXSize(
                ) and y < image.getYSize():
                    image.setXelA(x, y, color)
                y += 1

            x += 1

    def destroy(self):
        del self._mazeCollTable
        del self._maskResolution
        del self._radius
        del self._revealedCells
        del self._revealFunctions
        del self._revealFunction
        self.map.removeNode()
        del self.map
        self.mask.removeNode()
        del self.mask
        self.maskedLayer.removeNode()
        del self.maskedLayer
        self.visibleLayer.removeNode()
        del self.visibleLayer
        self._maskImage.clear()
        del self._maskImage
        self.maskTexture.clear()
        del self.maskTexture
        self._laffMeterModel.removeNode()
        del self._laffMeterModel
        DirectFrame.destroy(self)

    def _revealSmoothCircle(self, x, y, center):
        length = (Vec2(x, y) - center).length()
        goalAlpha = max(0.0, length / float(self._radius) - 0.5)
        self._maskImage.setXelA(
            x, y,
            VBase4D(0.0, 0.0, 0.0,
                    min(self._maskImage.getAlpha(x, y), goalAlpha * 2.0)))

    def _revealHardCircle(self, x, y, center):
        length = (Vec2(x, y) - center).length()
        if length <= self._radius:
            self._maskImage.setXelA(x, y, VBase4D(0, 0, 0, 0))

    def _revealSquare(self, x, y, center):
        self._maskImage.setXelA(x, y, VBase4D(0, 0, 0, 0))

    def _drawHole(self, x, y):
        center = Vec2(x, y)
        ul = center - Vec2(self._radius, self._radius)
        lr = center + Vec2(self._radius, self._radius)
        x = int(ul[0])
        while x <= lr[0]:
            y = int(ul[1])
            while y <= lr[1]:
                if x > 0 and y > 0 and x < self._maskResolution and y < self._maskResolution:
                    self._revealFunctions[self._revealFunction](x, y, center)
                y += 1

            x += 1

        self.maskTexture.load(self._maskImage)
        self.mask.setTexture(self.maskTexture, 1)

    def _createSimpleMarker(self, size, color=(1, 1, 1)):
        halfSize = size * 0.5
        cm = CardMaker('mazemap_simple_marker')
        cm.setFrame(-halfSize, halfSize, -halfSize, halfSize)
        markerNP = self.maskedLayer.attachNewNode(cm.generate())
        markerNP.setColor(*color)
        return markerNP

    def tile2gui(self, x, y):
        y = self._mazeHeight - y
        cellWidth = self._maskResolution / self._mazeWidth
        cellHeight = self._maskResolution / self._mazeHeight
        ax = float(x) / self._mazeWidth * self._maskResolution
        ax += cellWidth
        ay = float(y) / self._mazeHeight * self._maskResolution
        ay += cellHeight
        return (ax, ay)

    def gui2pos(self, x, y):
        return (x / self._maskResolution * 2.0 - 0.97, 0,
                y / self._maskResolution * -2.0 + 1.02)

    def _getToonMarker(self, toon):
        hType = toon.style.getType()
        if hType == 'rabbit':
            hType = 'bunny'
        return self._laffMeterModel.find('**/' + hType + 'head')

    def addToon(self, toon, tX, tY):
        marker = NodePath('toon_marker-%i' % toon.doId)
        marker.reparentTo(self)
        self._getToonMarker(toon).copyTo(marker)
        marker.setColor(toon.style.getHeadColor())
        if toon.isLocal():
            marker.setScale(0.07)
        else:
            marker.setScale(0.05)
        marker.flattenStrong()
        marker.setPos(*self.gui2pos(*self.tile2gui(tX, tY)))
        self._toon2marker[toon] = marker

    def removeToon(self, toon):
        if not self._toon2marker.has_key(toon):
            return
        self._toon2marker[toon].removeNode()
        del self._toon2marker[toon]

    def updateToon(self, toon, tX, tY):
        if not self._toon2marker.has_key(toon):
            return
        x, y = self.tile2gui(tX, tY)
        self._toon2marker[toon].setPos(*self.gui2pos(x, y))
        if tY < 0 or tY >= len(self._revealedCells):
            self.notify.warning('updateToon earlying out:')
            self.notify.warning('(tX, tY): (%s, %s)' % (tX, tY))
            self.notify.warning('len(_revealedCells): %s' %
                                (len(self._revealedCells), ))
            if len(self._revealedCells) > 0:
                self.notify.warning('len(_revealedCells[0]): %s' %
                                    (len(self._revealedCells[0]), ))
            return
        if tX < 0 or tX >= len(self._revealedCells[tY]):
            self.notify.warning('updateToon earlying out:')
            self.notify.warning('(tX, tY): (%s, %s)' % (tX, tY))
            self.notify.warning('len(_revealedCells): %s' %
                                (len(self._revealedCells), ))
            if tY < len(self._revealedCells):
                self.notify.warning('len(_revealedCells[tY]): %s' %
                                    (len(self._revealedCells[tY]), ))
            elif len(self._revealedCells) > 0:
                self.notify.warning('len(_revealedCells[0]): %s' %
                                    (len(self._revealedCells[0]), ))
            return
        if not self._revealedCells[tY][tX]:
            self._drawHole(x, y)
            self._revealedCells[tY][tX] = True

    def revealCell(self, x, y):
        ax, ay = self.tile2gui(x, y)
        if not self._revealedCells[y][x]:
            self._drawHole(ax, ay)
            self._revealedCells[y][x] = True

    def revealAll(self):
        for x in range(self._maskResolution):
            for y in range(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 0)

        self.revealCell(0, 0)

    def reset(self):
        for x in range(self._maskResolution):
            for y in range(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)
Пример #50
0
 def setupHalfTextures(self):
     self.setupLeftTexture()
     self.setupRightTexture()
     self.fullPnmImage = PNMImage(WEB_WIDTH, WEB_HEIGHT, 4)
     self.leftPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
     self.rightPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
Пример #51
0
    def __init__(self, image_path, rowPerFace, name=None,\
         rows=1, cols=1, scale=1.0,\
         twoSided=False, alpha=TRANS_ALPHA,\
         repeatX=1, repeatY=1,\
         anchorX=ALIGN_CENTER, anchorY=ALIGN_BOTTOM):
        """
		Create a card textured with an image. The card is sized so that the ratio between the
		card and image is the same.
		"""

        global SpriteId
        self.spriteNum = str(SpriteId)
        SpriteId += 1

        scale *= self.PIXEL_SCALE

        self.animations = {}

        self.scale = scale
        self.repeatX = repeatX
        self.repeatY = repeatY
        self.flip = {'x': False, 'y': False}
        self.rows = rows
        self.cols = cols

        self.currentFrame = 0
        self.currentAnim = None
        self.loopAnim = False
        self.frameInterrupt = True

        # Create the NodePath
        if name:
            self.node = NodePath("Sprite2d:%s" % name)
        else:
            self.node = NodePath("Sprite2d:%s" % image_path)

        # Set the attribute for transparency/twosided
        self.node.node().setAttrib(TransparencyAttrib.make(alpha))
        if twoSided:
            self.node.setTwoSided(True)

        # Make a filepath
        self.imgFile = Filename(image_path)
        if self.imgFile.empty():
            raise IOError, "File not found"

        # Instead of loading it outright, check with the PNMImageHeader if we can open
        # the file.
        imgHead = PNMImageHeader()
        if not imgHead.readHeader(self.imgFile):
            raise IOError, "PNMImageHeader could not read file. Try using absolute filepaths"

        # Load the image with a PNMImage
        image = PNMImage()
        image.read(self.imgFile)

        self.sizeX = image.getXSize()
        self.sizeY = image.getYSize()

        # We need to find the power of two size for the another PNMImage
        # so that the texture thats loaded on the geometry won't have artifacts
        textureSizeX = self.nextsize(self.sizeX)
        textureSizeY = self.nextsize(self.sizeY)

        # The actual size of the texture in memory
        self.realSizeX = textureSizeX
        self.realSizeY = textureSizeY

        self.paddedImg = PNMImage(textureSizeX, textureSizeY)
        if image.hasAlpha():
            self.paddedImg.alphaFill(0)
        # Copy the source image to the image we're actually using
        self.paddedImg.blendSubImage(image, 0, 0)
        # We're done with source image, clear it
        image.clear()

        # The pixel sizes for each cell
        self.colSize = self.sizeX / self.cols
        self.rowSize = self.sizeY / self.rows

        # How much padding the texture has
        self.paddingX = textureSizeX - self.sizeX
        self.paddingY = textureSizeY - self.sizeY

        # Set UV padding
        self.uPad = float(self.paddingX) / textureSizeX
        self.vPad = float(self.paddingY) / textureSizeY

        # The UV dimensions for each cell
        self.uSize = (1.0 - self.uPad) / self.cols
        self.vSize = (1.0 - self.vPad) / self.rows

        self.cards = []
        self.rowPerFace = rowPerFace
        for i in range(len(rowPerFace)):
            card = CardMaker("Sprite2d-Geom")

            # The positions to create the card at
            if anchorX == self.ALIGN_LEFT:
                posLeft = 0
                posRight = (self.colSize / scale) * repeatX
            elif anchorX == self.ALIGN_CENTER:
                posLeft = -(self.colSize / 2.0 / scale) * repeatX
                posRight = (self.colSize / 2.0 / scale) * repeatX
            elif anchorX == self.ALIGN_RIGHT:
                posLeft = -(self.colSize / scale) * repeatX
                posRight = 0

            if anchorY == self.ALIGN_BOTTOM:
                posTop = 0
                posBottom = (self.rowSize / scale) * repeatY
            elif anchorY == self.ALIGN_CENTER:
                posTop = -(self.rowSize / 2.0 / scale) * repeatY
                posBottom = (self.rowSize / 2.0 / scale) * repeatY
            elif anchorY == self.ALIGN_TOP:
                posTop = -(self.rowSize / scale) * repeatY
                posBottom = 0

            card.setFrame(posLeft, posRight, posTop, posBottom)
            card.setHasUvs(True)
            self.cards.append(self.node.attachNewNode(card.generate()))
            self.cards[-1].setH(i * 360 / len(rowPerFace))

        # Since the texture is padded, we need to set up offsets and scales to make
        # the texture fit the whole card
        self.offsetX = (float(self.colSize) / textureSizeX)
        self.offsetY = (float(self.rowSize) / textureSizeY)

        # self.node.setTexScale(TextureStage.getDefault(), self.offsetX * repeatX, self.offsetY * repeatY)
        # self.node.setTexOffset(TextureStage.getDefault(), 0, 1-self.offsetY)

        self.texture = Texture()

        self.texture.setXSize(textureSizeX)
        self.texture.setYSize(textureSizeY)
        self.texture.setZSize(1)

        # Load the padded PNMImage to the texture
        self.texture.load(self.paddedImg)

        self.texture.setMagfilter(Texture.FTNearest)
        self.texture.setMinfilter(Texture.FTNearest)

        #Set up texture clamps according to repeats
        if repeatX > 1:
            self.texture.setWrapU(Texture.WMRepeat)
        else:
            self.texture.setWrapU(Texture.WMClamp)
        if repeatY > 1:
            self.texture.setWrapV(Texture.WMRepeat)
        else:
            self.texture.setWrapV(Texture.WMClamp)

        self.node.setTexture(self.texture)
        self.setFrame(0)
Пример #52
0
Файл: GXO.py Проект: crempp/psg
class GXOStar(GXOBase):
    def __init__(self, parent=render, pos=Vec3(50, 0, 0)):
        GXOBase.__init__(self, parent, pos)

        self._initializeFlare()

    def _initializeFlare(self):
        # Parameters
        self.distance = 130000.0
        self.threshold = 0.3
        self.radius = 0.8
        self.strength = 1.0
        self.suncolor = Vec4(1, 1, 1, 1)
        self.suncardcolor = Vec4(1, 1, 0, 0)

        # Initialize some values
        self.obscured = 0.0

        # flaredata will hold the rendered image
        self.flaredata = PNMImage()
        # flaretexture will store the rendered buffer
        self.flaretexture = Texture()

        # Create a 10x10 texture buffer for the flare
        self.flarebuffer = base.win.makeTextureBuffer("Flare Buffer", 10, 10)
        # Attach the texture to the buffer
        self.flarebuffer.addRenderTexture(self.flaretexture,
                                          GraphicsOutput.RTMCopyRam)
        self.flarebuffer.setSort(-100)

        # Camera that renders the flare buffer
        self.flarecamera = base.makeCamera(self.flarebuffer)
        #self.flarecamera.reparentTo(base.cam)
        #self.flarecamera.setPos(-50,0,0)
        self.ortlens = OrthographicLens()
        self.ortlens.setFilmSize(
            10, 10)  # or whatever is appropriate for your scene
        self.ortlens.setNearFar(1, self.distance)
        self.flarecamera.node().setLens(self.ortlens)
        self.flarecamera.node().setCameraMask(GXMgr.MASK_GXM_HIDDEN)

        # Create a light for the flare
        self.sunlight = self.baseNode.attachNewNode(
            PointLight("Sun:Point Light"))
        self.sunlight.node().setColor(self.suncolor)
        self.sunlight.node().setAttenuation(Vec3(0.1, 0.04, 0.0))

        # Load texture cards
        # Create a nodepath that'll hold the texture cards for the new lens-flare
        self.texcardNP = aspect2d.attachNewNode('Sun:flareNode1')
        self.texcardNP.attachNewNode('Sun:fakeHdr')
        self.texcardNP.attachNewNode('Sun:starburstNode')
        # Load a circle and assign it a color. This will be used to calculate
        # Flare occlusion
        self.starcard = loader.loadModel('../data/models/unitcircle.egg')
        self.starcard.reparentTo(self.baseNode)
        self.starcard.setColor(self.suncardcolor)
        self.starcard.setScale(1)
        #self.starcard.setTransparency(TransparencyAttrib.MAlpha)
        # This is necessary since a billboard always rotates the y-axis to the
        # target but we need the z-axis
        self.starcard.setP(-90)
        self.starcard.setBillboardPointEye(self.flarecamera, 0.0)
        # Don't let the main camera see the star card
        self.starcard.show(GXMgr.MASK_GXM_HIDDEN)
        self.starcard.hide(GXMgr.MASK_GXM_VISIBLE)

        #the models are really just texture cards create with egg-texture-cards
        # from the actual pictures
        self.hdr = loader.loadModel('../data/models/fx_flare.egg')
        self.hdr.reparentTo(self.texcardNP.find('**/Sun:fakeHdr'))

        # Flare specs
        self.starburst_0 = loader.loadModel(
            '../data/models/fx_starburst_01.egg')
        self.starburst_1 = loader.loadModel(
            '../data/models/fx_starburst_02.egg')
        self.starburst_2 = loader.loadModel(
            '../data/models/fx_starburst_03.egg')
        self.starburst_0.setPos(0.5, 0, 0.5)
        self.starburst_1.setPos(0.5, 0, 0.5)
        self.starburst_2.setPos(0.5, 0, 0.5)
        self.starburst_0.setScale(.2)
        self.starburst_1.setScale(.2)
        self.starburst_2.setScale(.2)
        self.starburst_0.reparentTo(
            self.texcardNP.find('**/Sun:starburstNode'))
        self.starburst_1.reparentTo(
            self.texcardNP.find('**/Sun:starburstNode'))
        self.starburst_2.reparentTo(
            self.texcardNP.find('**/Sun:starburstNode'))

        self.texcardNP.setTransparency(TransparencyAttrib.MAlpha)
        # Put the texture cards in the background bin
        self.texcardNP.setBin('background', 0)
        # The texture cards do not affect the depth buffer
        self.texcardNP.setDepthWrite(False)

        #attach a node to the screen middle, used for some math
        self.mid2d = aspect2d.attachNewNode('mid2d')

        #start the task that implements the lens-flare
        taskMgr.add(self._flareTask, 'Sun:flareTask')

    ## this function returns the aspect2d position of a light source, if it enters the cameras field of view
    def _get2D(self, nodePath):
        #get the position of the light source relative to the cam
        p3d = base.cam.getRelativePoint(nodePath, Point3(0, 0, 0))
        p2d = Point2()

        #project the light source into the viewing plane and return 2d coordinates, if it is in the visible area(read: not behind the cam)
        if base.cam.node().getLens().project(p3d, p2d):
            return p2d

        return None

    def _getObscured(self, color):
        # This originally looked for the radius of the light but that caused
        # assertion errors. Now I use the radius of the hdr model.
        bounds = self.starcard.getBounds()
        #print ("bounds=%s rad=%s"%(bounds,bounds.getRadius()))
        if not bounds.isEmpty():
            r = bounds.getRadius()
            # Setting the film size sets the field-of-view and the aspect ratio
            # Maybe this should be done with setAspectRation() and setFov()
            self.ortlens.setFilmSize(r * self.radius, r * self.radius)

            # Point the flarecamera at the sun so we can determine if anything
            # is obscurring the sun
            self.flarecamera.lookAt(self.baseNode)

            # Renders the next frame in all the registered windows, and flips
            # all of the frame buffers. This will populate flaretexture since
            # it's attached to the flarebuffer.
            # Save the rendered frame in flaredata
            base.graphicsEngine.renderFrame()
            self.flaretexture.store(self.flaredata)

            #print ("flaredata=%s | color=%s"%(self.flaredata.getXel(5,5), color))

            # Initialize the obscured factor
            obscured = 100.0
            color = VBase3D(color[0], color[1], color[2])
            for x in xrange(0, 9):
                for y in xrange(0, 9):
                    if color.almostEqual(self.flaredata.getXel(x, y),
                                         self.threshold):
                        obscured -= 1.0
        else:
            obscured = 0
        return obscured

    def _flareTask(self, task):
        #going through the list of lightNodePaths
        #for index in xrange(0, len(self.lightNodes)):

        pos2d = self._get2D(self.sunlight)
        #if the light source is visible from the cam's point of view,
        # display the lens-flare
        if pos2d:
            #print ("Flare visible")

            # The the obscured factor
            obscured = self._getObscured(self.suncardcolor)
            # Scale it to [0,1]
            self.obscured = obscured / 100
            ##print obscured

            # Length is the length of the vector that goes from the screen
            # middle to the pos of the light. The length gets smaller the
            # closer the light is to the screen middle, however, since
            # length is used to calculate the brightness of the effect we
            # actually need an inverse behaviour, since the brightness
            # will be greates when center of screen= pos of light
            length = math.sqrt(pos2d.getX() * pos2d.getX() +
                               pos2d.getY() * pos2d.getY())
            invLength = 1.0 - length * 2
            # Subtract the obscured factor from the inverted distence and
            # we have a value that simulates the power of the flare
            #brightness
            flarePower = invLength - self.obscured
            #print("light pos=%s | length=%s"%(pos2d,length))
            print("obs=%s | length=%s | inv=%s | pow=%s" %
                  (self.obscured, length, invLength, flarePower))

            # Clamp the flare power to some values
            if flarePower < 0 and self.obscured > 0: flarePower = 0.0
            if flarePower < 0 and self.obscured <= 0: flarePower = 0.3
            if flarePower > 1: flarePower = 1

            print("flarepower=%s" % (flarePower))

            #
            if self.obscured >= 0.8:
                self.texcardNP.find('**/Sun:starburstNode').hide()
            else:
                self.texcardNP.find('**/Sun:starburstNode').show()

                #drawing the lens-flare effect...
                r = self.suncolor.getX()
                g = self.suncolor.getY()
                b = self.suncolor.getZ()
                r = math.sqrt(r * r + length * length) * self.strength
                g = math.sqrt(g * g + length * length) * self.strength
                b = math.sqrt(b * b + length * length) * self.strength
                print("%s,%s,%s" % (r, g, b))

                #
                if self.obscured > 0.19:
                    a = self.obscured - 0.2
                else:
                    a = 0.4 - flarePower

                #
                if a < 0: a = 0
                if a > 0.8: a = 0.8

                #
                self.hdr.setColor(r, g, b, 0.8 - a)
                self.hdr.setR(90 * length)
                self.texcardNP.find('**/Sun:starburstNode').setColor(
                    r, g, b, 0.5 + length)
                self.hdr.setPos(pos2d.getX(), 0, pos2d.getY())
                self.hdr.setScale(8.5 + (5 * length))

                vecMid = Vec2(self.mid2d.getX(), self.mid2d.getZ())
                vec2d = Vec2(vecMid - pos2d)
                vec3d = Vec3(vec2d.getX(), 0, vec2d.getY())

                self.starburst_0.setPos(self.hdr.getPos() - (vec3d * 10))
                self.starburst_1.setPos(self.hdr.getPos() - (vec3d * 5))
                self.starburst_2.setPos(self.hdr.getPos() - (vec3d * 10))
                self.texcardNP.show()
                #print "a",a
        else:
            #hide the lens-flare effect for a light source, if it is not visible...
            self.texcardNP.hide()

        return Task.cont
Пример #53
0
class HtmlView(DirectObject):
    notify = DirectNotifyGlobal.directNotify.newCategory('HtmlView')
    useHalfTexture = base.config.GetBool('news-half-texture', 0)

    def __init__(self, parent=aspect2d):
        global GlobalWebcore
        self.parent = parent
        self.mx = 0
        self.my = 0
        self.htmlFile = 'index.html'
        self.transparency = False
        if GlobalWebcore:
            pass
        else:
            GlobalWebcore = AwWebCore(AwWebCore.LOGVERBOSE, True,
                                      AwWebCore.PFBGRA)
            GlobalWebcore.setBaseDirectory('.')
            for errResponse in xrange(400, 600):
                GlobalWebcore.setCustomResponsePage(errResponse, 'error.html')

        self.webView = GlobalWebcore.createWebView(WEB_WIDTH, WEB_HEIGHT,
                                                   self.transparency, False,
                                                   70)
        frameName = ''
        inGameNewsUrl = self.getInGameNewsUrl()
        self.imgBuffer = array.array('B')
        for i in xrange(WEB_WIDTH * WEB_HEIGHT):
            self.imgBuffer.append(0)
            self.imgBuffer.append(0)
            self.imgBuffer.append(0)
            self.imgBuffer.append(255)

        if self.useHalfTexture:
            self.leftBuffer = array.array('B')
            for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
                self.leftBuffer.append(0)
                self.leftBuffer.append(0)
                self.leftBuffer.append(0)
                self.leftBuffer.append(255)

            self.rightBuffer = array.array('B')
            for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
                self.rightBuffer.append(0)
                self.rightBuffer.append(0)
                self.rightBuffer.append(0)
                self.rightBuffer.append(255)

        self.setupTexture()
        if self.useHalfTexture:
            self.setupHalfTextures()
        self.accept('mouse1', self.mouseDown, [AwWebView.LEFTMOUSEBTN])
        self.accept('mouse3', self.mouseDown, [AwWebView.RIGHTMOUSEBTN])
        self.accept('mouse1-up', self.mouseUp, [AwWebView.LEFTMOUSEBTN])
        self.accept('mouse3-up', self.mouseUp, [AwWebView.RIGHTMOUSEBTN])

    def getInGameNewsUrl(self):
        result = base.config.GetString(
            'fallback-news-url',
            'http://cdn.toontown.disney.go.com/toontown/en/gamenews/')
        override = base.config.GetString('in-game-news-url', '')
        if override:
            self.notify.info(
                'got an override url,  using %s for in a game news' % override)
            result = override
        else:
            try:
                launcherUrl = base.launcher.getValue('GAME_IN_GAME_NEWS_URL',
                                                     '')
                if launcherUrl:
                    result = launcherUrl
                    self.notify.info(
                        'got GAME_IN_GAME_NEWS_URL from launcher using %s' %
                        result)
                else:
                    self.notify.info(
                        'blank GAME_IN_GAME_NEWS_URL from launcher, using %s' %
                        result)
            except:
                self.notify.warning(
                    'got exception getting GAME_IN_GAME_NEWS_URL from launcher, using %s'
                    % result)

        return result

    def setupTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)
        cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0,
                    htmlHeight / 2.0)
        bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1)
        bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)
        cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))
        card = cm.generate()
        self.quad = NodePath(card)
        self.quad.reparentTo(self.parent)
        self.guiTex = Texture('guiTex')
        self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1,
                                 Texture.TUnsignedByte, Texture.FRgba)
        self.guiTex.setMinfilter(Texture.FTLinear)
        self.guiTex.setKeepRamImage(True)
        self.guiTex.makeRamImage()
        self.guiTex.setWrapU(Texture.WMRepeat)
        self.guiTex.setWrapV(Texture.WMRepeat)
        ts = TextureStage('webTS')
        self.quad.setTexture(ts, self.guiTex)
        self.quad.setTexScale(ts, 1.0, -1.0)
        self.quad.setTransparency(0)
        self.quad.setTwoSided(True)
        self.quad.setColor(1.0, 1.0, 1.0, 1.0)
        self.calcMouseLimits()

    def setupHalfTextures(self):
        self.setupLeftTexture()
        self.setupRightTexture()
        self.fullPnmImage = PNMImage(WEB_WIDTH, WEB_HEIGHT, 4)
        self.leftPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
        self.rightPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)

    def setupLeftTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)
        cm.setFrame(-htmlWidth / 2.0, 0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.leftQuad = NodePath(card)
        self.leftQuad.reparentTo(self.parent)
        self.leftGuiTex = Texture('guiTex')
        self.leftGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH,
                                     WEB_HEIGHT, 1, Texture.TUnsignedByte,
                                     Texture.FRgba)
        self.leftGuiTex.setKeepRamImage(True)
        self.leftGuiTex.makeRamImage()
        self.leftGuiTex.setWrapU(Texture.WMClamp)
        self.leftGuiTex.setWrapV(Texture.WMClamp)
        ts = TextureStage('leftWebTS')
        self.leftQuad.setTexture(ts, self.leftGuiTex)
        self.leftQuad.setTexScale(ts, 1.0, -1.0)
        self.leftQuad.setTransparency(0)
        self.leftQuad.setTwoSided(True)
        self.leftQuad.setColor(1.0, 1.0, 1.0, 1.0)

    def setupRightTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)
        cm.setFrame(0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.rightQuad = NodePath(card)
        self.rightQuad.reparentTo(self.parent)
        self.rightGuiTex = Texture('guiTex')
        self.rightGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH,
                                      WEB_HEIGHT, 1, Texture.TUnsignedByte,
                                      Texture.FRgba)
        self.rightGuiTex.setKeepRamImage(True)
        self.rightGuiTex.makeRamImage()
        self.rightGuiTex.setWrapU(Texture.WMClamp)
        self.rightGuiTex.setWrapV(Texture.WMClamp)
        ts = TextureStage('rightWebTS')
        self.rightQuad.setTexture(ts, self.rightGuiTex)
        self.rightQuad.setTexScale(ts, 1.0, -1.0)
        self.rightQuad.setTransparency(0)
        self.rightQuad.setTwoSided(True)
        self.rightQuad.setColor(1.0, 1.0, 1.0, 1.0)

    def calcMouseLimits(self):
        ll = Point3()
        ur = Point3()
        self.quad.calcTightBounds(ll, ur)
        self.notify.debug('ll=%s ur=%s' % (ll, ur))
        offset = self.quad.getPos(aspect2d)
        self.notify.debug('offset = %s ' % offset)
        ll.setZ(ll.getZ() + offset.getZ())
        ur.setZ(ur.getZ() + offset.getZ())
        self.notify.debug('new LL=%s, UR=%s' % (ll, ur))
        relPointll = self.quad.getRelativePoint(aspect2d, ll)
        self.notify.debug('relPoint = %s' % relPointll)
        self.mouseLL = (aspect2d.getScale()[0] * ll[0],
                        aspect2d.getScale()[2] * ll[2])
        self.mouseUR = (aspect2d.getScale()[0] * ur[0],
                        aspect2d.getScale()[2] * ur[2])
        self.notify.debug('original mouseLL=%s, mouseUR=%s' %
                          (self.mouseLL, self.mouseUR))

    def writeTex(self, filename='guiText.png'):
        self.notify.debug('writing texture')
        self.guiTex.generateRamMipmapImages()
        self.guiTex.write(filename)

    def toggleRotation(self):
        if self.interval.isPlaying():
            self.interval.finish()
        else:
            self.interval.loop()

    def mouseDown(self, button):
        messenger.send('wakeup')
        self.webView.injectMouseDown(button)

    def mouseUp(self, button):
        self.webView.injectMouseUp(button)

    def reload(self):
        pass

    def zoomIn(self):
        self.webView.zoomIn()

    def zoomOut(self):
        self.webView.zoomOut()

    def toggleTransparency(self):
        self.transparency = not self.transparency
        self.webView.setTransparent(self.transparency)

    def update(self, task):
        if base.mouseWatcherNode.hasMouse():
            x, y = self._translateRelativeCoordinates(
                base.mouseWatcherNode.getMouseX(),
                base.mouseWatcherNode.getMouseY())
            if self.mx - x != 0 or self.my - y != 0:
                self.webView.injectMouseMove(x, y)
                self.mx, self.my = x, y
            if self.webView.isDirty():
                self.webView.render(self.imgBuffer.buffer_info()[0],
                                    WEB_WIDTH * 4, 4)
                Texture.setTexturesPower2(2)
                textureBuffer = self.guiTex.modifyRamImage()
                textureBuffer.setData(self.imgBuffer.tostring())
                if self.useHalfTexture:
                    self.guiTex.store(self.fullPnmImage)
                    self.leftPnmImage.copySubImage(self.fullPnmImage, 0, 0, 0,
                                                   0, WEB_HALF_WIDTH,
                                                   WEB_HEIGHT)
                    self.rightPnmImage.copySubImage(self.fullPnmImage, 0, 0,
                                                    WEB_HALF_WIDTH, 0,
                                                    WEB_HALF_WIDTH, WEB_HEIGHT)
                    self.leftGuiTex.load(self.leftPnmImage)
                    self.rightGuiTex.load(self.rightPnmImage)
                    self.quad.hide()
                Texture.setTexturesPower2(1)
            GlobalWebcore.update()
        return Task.cont

    def _translateRelativeCoordinates(self, x, y):
        sx = int((x - self.mouseLL[0]) / (self.mouseUR[0] - self.mouseLL[0]) *
                 WEB_WIDTH_PIXELS)
        sy = WEB_HEIGHT_PIXELS - int(
            (y - self.mouseLL[1]) /
            (self.mouseUR[1] - self.mouseLL[1]) * WEB_HEIGHT_PIXELS)
        return (sx, sy)

    def unload(self):
        self.ignoreAll()
        self.webView.destroy()
        self.webView = None
        return

    def onCallback(self, name, args):
        if name == 'requestFPS':
            pass

    def onBeginNavigation(self, url, frameName):
        pass

    def onBeginLoading(self, url, frameName, statusCode, mimeType):
        pass

    def onFinishLoading(self):
        self.notify.debug('finished loading')

    def onReceiveTitle(self, title, frameName):
        pass

    def onChangeTooltip(self, tooltip):
        pass

    def onChangeCursor(self, cursor):
        pass

    def onChangeKeyboardFocus(self, isFocused):
        pass

    def onChangeTargetURL(self, url):
        pass
Пример #54
0
Файл: GXO.py Проект: crempp/psg
    def _initializeFlare(self):
        # Parameters
        self.distance = 130000.0
        self.threshold = 0.3
        self.radius = 0.8
        self.strength = 1.0
        self.suncolor = Vec4(1, 1, 1, 1)
        self.suncardcolor = Vec4(1, 1, 0, 0)

        # Initialize some values
        self.obscured = 0.0

        # flaredata will hold the rendered image
        self.flaredata = PNMImage()
        # flaretexture will store the rendered buffer
        self.flaretexture = Texture()

        # Create a 10x10 texture buffer for the flare
        self.flarebuffer = base.win.makeTextureBuffer("Flare Buffer", 10, 10)
        # Attach the texture to the buffer
        self.flarebuffer.addRenderTexture(self.flaretexture,
                                          GraphicsOutput.RTMCopyRam)
        self.flarebuffer.setSort(-100)

        # Camera that renders the flare buffer
        self.flarecamera = base.makeCamera(self.flarebuffer)
        #self.flarecamera.reparentTo(base.cam)
        #self.flarecamera.setPos(-50,0,0)
        self.ortlens = OrthographicLens()
        self.ortlens.setFilmSize(
            10, 10)  # or whatever is appropriate for your scene
        self.ortlens.setNearFar(1, self.distance)
        self.flarecamera.node().setLens(self.ortlens)
        self.flarecamera.node().setCameraMask(GXMgr.MASK_GXM_HIDDEN)

        # Create a light for the flare
        self.sunlight = self.baseNode.attachNewNode(
            PointLight("Sun:Point Light"))
        self.sunlight.node().setColor(self.suncolor)
        self.sunlight.node().setAttenuation(Vec3(0.1, 0.04, 0.0))

        # Load texture cards
        # Create a nodepath that'll hold the texture cards for the new lens-flare
        self.texcardNP = aspect2d.attachNewNode('Sun:flareNode1')
        self.texcardNP.attachNewNode('Sun:fakeHdr')
        self.texcardNP.attachNewNode('Sun:starburstNode')
        # Load a circle and assign it a color. This will be used to calculate
        # Flare occlusion
        self.starcard = loader.loadModel('../data/models/unitcircle.egg')
        self.starcard.reparentTo(self.baseNode)
        self.starcard.setColor(self.suncardcolor)
        self.starcard.setScale(1)
        #self.starcard.setTransparency(TransparencyAttrib.MAlpha)
        # This is necessary since a billboard always rotates the y-axis to the
        # target but we need the z-axis
        self.starcard.setP(-90)
        self.starcard.setBillboardPointEye(self.flarecamera, 0.0)
        # Don't let the main camera see the star card
        self.starcard.show(GXMgr.MASK_GXM_HIDDEN)
        self.starcard.hide(GXMgr.MASK_GXM_VISIBLE)

        #the models are really just texture cards create with egg-texture-cards
        # from the actual pictures
        self.hdr = loader.loadModel('../data/models/fx_flare.egg')
        self.hdr.reparentTo(self.texcardNP.find('**/Sun:fakeHdr'))

        # Flare specs
        self.starburst_0 = loader.loadModel(
            '../data/models/fx_starburst_01.egg')
        self.starburst_1 = loader.loadModel(
            '../data/models/fx_starburst_02.egg')
        self.starburst_2 = loader.loadModel(
            '../data/models/fx_starburst_03.egg')
        self.starburst_0.setPos(0.5, 0, 0.5)
        self.starburst_1.setPos(0.5, 0, 0.5)
        self.starburst_2.setPos(0.5, 0, 0.5)
        self.starburst_0.setScale(.2)
        self.starburst_1.setScale(.2)
        self.starburst_2.setScale(.2)
        self.starburst_0.reparentTo(
            self.texcardNP.find('**/Sun:starburstNode'))
        self.starburst_1.reparentTo(
            self.texcardNP.find('**/Sun:starburstNode'))
        self.starburst_2.reparentTo(
            self.texcardNP.find('**/Sun:starburstNode'))

        self.texcardNP.setTransparency(TransparencyAttrib.MAlpha)
        # Put the texture cards in the background bin
        self.texcardNP.setBin('background', 0)
        # The texture cards do not affect the depth buffer
        self.texcardNP.setDepthWrite(False)

        #attach a node to the screen middle, used for some math
        self.mid2d = aspect2d.attachNewNode('mid2d')

        #start the task that implements the lens-flare
        taskMgr.add(self._flareTask, 'Sun:flareTask')
Пример #55
0
class HtmlView(DirectObject):
    notify = DirectNotifyGlobal.directNotify.newCategory('HtmlView')
    useHalfTexture = config.GetBool('news-half-texture', 0)

    def __init__(self, parent = aspect2d):
        global GlobalWebcore
        self.parent = parent
        self.mx = 0
        self.my = 0
        self.htmlFile = 'index.html'
        self.transparency = False
        if GlobalWebcore:
            pass
        else:
            GlobalWebcore = AwWebCore(AwWebCore.LOGVERBOSE, True, AwWebCore.PFBGRA)
            GlobalWebcore.setBaseDirectory('.')
            for errResponse in xrange(400, 600):
                GlobalWebcore.setCustomResponsePage(errResponse, 'error.html')

        self.webView = GlobalWebcore.createWebView(WEB_WIDTH, WEB_HEIGHT, self.transparency, False, 70)
        frameName = ''
        inGameNewsUrl = self.getInGameNewsUrl()
        self.imgBuffer = array.array('B')
        for i in xrange(WEB_WIDTH * WEB_HEIGHT):
            self.imgBuffer.append(0)
            self.imgBuffer.append(0)
            self.imgBuffer.append(0)
            self.imgBuffer.append(255)

        if self.useHalfTexture:
            self.leftBuffer = array.array('B')
            for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
                self.leftBuffer.append(0)
                self.leftBuffer.append(0)
                self.leftBuffer.append(0)
                self.leftBuffer.append(255)

            self.rightBuffer = array.array('B')
            for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
                self.rightBuffer.append(0)
                self.rightBuffer.append(0)
                self.rightBuffer.append(0)
                self.rightBuffer.append(255)

        self.setupTexture()
        if self.useHalfTexture:
            self.setupHalfTextures()
        self.accept('mouse1', self.mouseDown, [AwWebView.LEFTMOUSEBTN])
        self.accept('mouse3', self.mouseDown, [AwWebView.RIGHTMOUSEBTN])
        self.accept('mouse1-up', self.mouseUp, [AwWebView.LEFTMOUSEBTN])
        self.accept('mouse3-up', self.mouseUp, [AwWebView.RIGHTMOUSEBTN])

    def getInGameNewsUrl(self):
        result = config.GetString('fallback-news-url', 'http://cdn.toontown.disney.go.com/toontown/en/gamenews/')
        override = config.GetString('in-game-news-url', '')
        if override:
            self.notify.info('got an override url,  using %s for in a game news' % override)
            result = override
        else:
            try:
                launcherUrl = base.launcher.getValue('GAME_IN_GAME_NEWS_URL', '')
                if launcherUrl:
                    result = launcherUrl
                    self.notify.info('got GAME_IN_GAME_NEWS_URL from launcher using %s' % result)
                else:
                    self.notify.info('blank GAME_IN_GAME_NEWS_URL from launcher, using %s' % result)
            except:
                self.notify.warning('got exception getting GAME_IN_GAME_NEWS_URL from launcher, using %s' % result)

        return result

    def setupTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)
        cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
        bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1)
        bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)
        cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))
        card = cm.generate()
        self.quad = NodePath(card)
        self.quad.reparentTo(self.parent)
        self.guiTex = Texture('guiTex')
        self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.guiTex.setMinfilter(Texture.FTLinear)
        self.guiTex.setKeepRamImage(True)
        self.guiTex.makeRamImage()
        self.guiTex.setWrapU(Texture.WMRepeat)
        self.guiTex.setWrapV(Texture.WMRepeat)
        ts = TextureStage('webTS')
        self.quad.setTexture(ts, self.guiTex)
        self.quad.setTexScale(ts, 1.0, -1.0)
        self.quad.setTransparency(0)
        self.quad.setTwoSided(True)
        self.quad.setColor(1.0, 1.0, 1.0, 1.0)
        self.calcMouseLimits()

    def setupHalfTextures(self):
        self.setupLeftTexture()
        self.setupRightTexture()
        self.fullPnmImage = PNMImage(WEB_WIDTH, WEB_HEIGHT, 4)
        self.leftPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
        self.rightPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)

    def setupLeftTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)
        cm.setFrame(-htmlWidth / 2.0, 0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.leftQuad = NodePath(card)
        self.leftQuad.reparentTo(self.parent)
        self.leftGuiTex = Texture('guiTex')
        self.leftGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.leftGuiTex.setKeepRamImage(True)
        self.leftGuiTex.makeRamImage()
        self.leftGuiTex.setWrapU(Texture.WMClamp)
        self.leftGuiTex.setWrapV(Texture.WMClamp)
        ts = TextureStage('leftWebTS')
        self.leftQuad.setTexture(ts, self.leftGuiTex)
        self.leftQuad.setTexScale(ts, 1.0, -1.0)
        self.leftQuad.setTransparency(0)
        self.leftQuad.setTwoSided(True)
        self.leftQuad.setColor(1.0, 1.0, 1.0, 1.0)

    def setupRightTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)
        cm.setFrame(0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.rightQuad = NodePath(card)
        self.rightQuad.reparentTo(self.parent)
        self.rightGuiTex = Texture('guiTex')
        self.rightGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.rightGuiTex.setKeepRamImage(True)
        self.rightGuiTex.makeRamImage()
        self.rightGuiTex.setWrapU(Texture.WMClamp)
        self.rightGuiTex.setWrapV(Texture.WMClamp)
        ts = TextureStage('rightWebTS')
        self.rightQuad.setTexture(ts, self.rightGuiTex)
        self.rightQuad.setTexScale(ts, 1.0, -1.0)
        self.rightQuad.setTransparency(0)
        self.rightQuad.setTwoSided(True)
        self.rightQuad.setColor(1.0, 1.0, 1.0, 1.0)

    def calcMouseLimits(self):
        ll = Point3()
        ur = Point3()
        self.quad.calcTightBounds(ll, ur)
        self.notify.debug('ll=%s ur=%s' % (ll, ur))
        offset = self.quad.getPos(aspect2d)
        self.notify.debug('offset = %s ' % offset)
        ll.setZ(ll.getZ() + offset.getZ())
        ur.setZ(ur.getZ() + offset.getZ())
        self.notify.debug('new LL=%s, UR=%s' % (ll, ur))
        relPointll = self.quad.getRelativePoint(aspect2d, ll)
        self.notify.debug('relPoint = %s' % relPointll)
        self.mouseLL = (aspect2d.getScale()[0] * ll[0], aspect2d.getScale()[2] * ll[2])
        self.mouseUR = (aspect2d.getScale()[0] * ur[0], aspect2d.getScale()[2] * ur[2])
        self.notify.debug('original mouseLL=%s, mouseUR=%s' % (self.mouseLL, self.mouseUR))

    def writeTex(self, filename = 'guiText.png'):
        self.notify.debug('writing texture')
        self.guiTex.generateRamMipmapImages()
        self.guiTex.write(filename)

    def toggleRotation(self):
        if self.interval.isPlaying():
            self.interval.finish()
        else:
            self.interval.loop()

    def mouseDown(self, button):
        messenger.send('wakeup')
        self.webView.injectMouseDown(button)

    def mouseUp(self, button):
        self.webView.injectMouseUp(button)

    def reload(self):
        pass

    def zoomIn(self):
        self.webView.zoomIn()

    def zoomOut(self):
        self.webView.zoomOut()

    def toggleTransparency(self):
        self.transparency = not self.transparency
        self.webView.setTransparent(self.transparency)

    def update(self, task):
        if base.mouseWatcherNode.hasMouse():
            x, y = self._translateRelativeCoordinates(base.mouseWatcherNode.getMouseX(), base.mouseWatcherNode.getMouseY())
            if self.mx - x != 0 or self.my - y != 0:
                self.webView.injectMouseMove(x, y)
                self.mx, self.my = x, y
            if self.webView.isDirty():
                self.webView.render(self.imgBuffer.buffer_info()[0], WEB_WIDTH * 4, 4)
                Texture.setTexturesPower2(2)
                textureBuffer = self.guiTex.modifyRamImage()
                textureBuffer.setData(self.imgBuffer.tostring())
                if self.useHalfTexture:
                    self.guiTex.store(self.fullPnmImage)
                    self.leftPnmImage.copySubImage(self.fullPnmImage, 0, 0, 0, 0, WEB_HALF_WIDTH, WEB_HEIGHT)
                    self.rightPnmImage.copySubImage(self.fullPnmImage, 0, 0, WEB_HALF_WIDTH, 0, WEB_HALF_WIDTH, WEB_HEIGHT)
                    self.leftGuiTex.load(self.leftPnmImage)
                    self.rightGuiTex.load(self.rightPnmImage)
                    self.quad.hide()
                Texture.setTexturesPower2(1)
            GlobalWebcore.update()
        return Task.cont

    def _translateRelativeCoordinates(self, x, y):
        sx = int((x - self.mouseLL[0]) / (self.mouseUR[0] - self.mouseLL[0]) * WEB_WIDTH_PIXELS)
        sy = WEB_HEIGHT_PIXELS - int((y - self.mouseLL[1]) / (self.mouseUR[1] - self.mouseLL[1]) * WEB_HEIGHT_PIXELS)
        return (sx, sy)

    def unload(self):
        self.ignoreAll()
        self.webView.destroy()
        self.webView = None
        return

    def onCallback(self, name, args):
        if name == 'requestFPS':
            pass

    def onBeginNavigation(self, url, frameName):
        pass

    def onBeginLoading(self, url, frameName, statusCode, mimeType):
        pass

    def onFinishLoading(self):
        self.notify.debug('finished loading')

    def onReceiveTitle(self, title, frameName):
        pass

    def onChangeTooltip(self, tooltip):
        pass

    def onChangeCursor(self, cursor):
        pass

    def onChangeKeyboardFocus(self, isFocused):
        pass

    def onChangeTargetURL(self, url):
        pass
Пример #56
0
  # Create the sound
  ballSound = loader.loadSfx("audio/sfx/GUI_rollover.wav")
  balls.append((ballNP, ballGeom, ballSound))

# Add a plane to collide with
cm = CardMaker("ground")
cm.setFrame(-20, 20, -20, 20)
cm.setUvRange((0, 1), (1, 0))
ground = render.attachNewNode(cm.generate())
ground.setPos(0, 0, 0); ground.lookAt(0, 0, -1)
groundGeom = OdePlaneGeom(space, (0, 0, 1, 0))
groundGeom.setCollideBits(BitMask32(0x00000001))
groundGeom.setCategoryBits(BitMask32(0x00000001))

# Add a texture to the ground
groundImage = PNMImage(512, 512)
groundImage.fill(1, 1, 1)
groundBrush = PNMBrush.makeSpot((0, 0, 0, 1), 8, True)
groundPainter = PNMPainter(groundImage)
groundPainter.setPen(groundBrush)
groundTexture = Texture("ground")
ground.setTexture(groundTexture)
groundImgChanged = False

# Set the camera position
base.disableMouse()
# Just to show off panda auto-converts tuples, now:
base.camera.setPos((40, 40, 20))
base.camera.lookAt((0, 0, 0))

# Setup collision event