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
def make(self): TerrainTile.make(self) self.makeSlopeMap() textureMapper = self.terrain.texturer.textureMapper #try to read textureMaps readTexMaps = True texNum = 0 for tex in textureMapper.textures: texNum += 1 fileName = "maps/textures/" + self.name + "+_texture" + str(texNum) + ".png" if not tex.image.read(Filename(fileName)): readTexMaps = False #otherwise calculate textureMaps if not readTexMaps: self.terrain.texturer.textureMapper.calculateTextures(self) #copy textureMaps to this terrainTile and save if necessary texNum = 0 for tex in self.terrain.texturer.textureMapper.textures: texNum += 1 self.textureMaps.append(tex.image) if not readTexMaps: tex.image.write(Filename("maps/textures/" + self.name + "+_texture" + str(texNum) + ".png")) #load textureMaps as actual textures for the shaders use num = 0 for tex in self.textureMaps: num += 1 newTexture = Texture() newTexture.load(tex) ts = TextureStage('alp' + str(num)) self.getRoot().setTexture(ts, newTexture)
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
class PerlinTest(DirectObject): def __init__(self): self.myTexture = Texture() self.imageObject = OnscreenImage(image = self.myTexture, pos = (0, 0, 0)) self.run() self.accept("arrow_up", self.run) 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)
class PerlinTest(DirectObject): def __init__(self): self.myTexture = Texture() self.imageObject = OnscreenImage(image = self.myTexture, pos = (0, 0, 0)) self.run() self.accept("arrow_up", self.run) def run(self): size = 1024 j = random.random() p1 = Perlin.Perlin( persistance = 0.500, smooth = False, seed = j ) p2 = Perlin.Perlin( persistance = 0.000, smooth = False, seed = j ) pb = Perlin.Perlin( persistance = 0.500, smooth = False, seed = random.random() ) myImage = p1.imgNoise2D(size,True) myImage2 = p2.imgNoise2D(size,True) myImage3 = pb.imgNoise2D(size,True) for x in range(size): for y in range(size): gray = (myImage.getGray(x,y) - 0.5) * myImage3.getGray(x,y) gray = gray + (myImage2.getGray(x,y) - 0.5) * (1.0 - myImage3.getGray(x,y)) myImage.setGray(x,y,gray + 0.5) self.myTexture.load(myImage)
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 = x self.my = 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 add_render_texture(output, mode=None, bitplane=None): """ Similar to GraphicsOutput's addRenderTexture. ** Possible mode values ** GraphicsOutput.RTMNone GraphicsOutput.RTMBindOrCopy GraphicsOutput.RTMCopyTexture GraphicsOutput.RTMCopyRam GraphicsOutput.RTMTriggeredCopyTexture GraphicsOutput.RTMTriggeredCopyRam ** Possible bitplane values ** GraphicsOutput.RTPStencil GraphicsOutput.RTPDepthStencil GraphicsOutput.RTPColor GraphicsOutput.RTPAuxRgba0 GraphicsOutput.RTPAuxRgba1 GraphicsOutput.RTPAuxRgba2 GraphicsOutput.RTPAuxRgba3 GraphicsOutput.RTPAuxHrgba0 GraphicsOutput.RTPAuxHrgba1 GraphicsOutput.RTPAuxHrgba2 GraphicsOutput.RTPAuxHrgba3 GraphicsOutput.RTPAuxFloat0 GraphicsOutput.RTPAuxFloat1 GraphicsOutput.RTPAuxFloat2 GraphicsOutput.RTPAuxFloat3 GraphicsOutput.RTPDepth GraphicsOutput.RTPCOUNT """ if mode is None: mode = GraphicsOutput.RTMBindOrCopy elif isinstance(mode, str): mode = getattr(GraphicsOutput, mode) if bitplane is None: bitplane = GraphicsOutput.RTPColor elif isinstance(bitplane, str): bitplane = getattr(GraphicsOutput, bitplane) tex = Texture() tex.setFormat(Texture.FLuminance) # Add the texture to the buffer output.addRenderTexture(tex, mode, bitplane) # Get a handle to the texture assert tex == output.getTexture(), "Texture wasn't created properly." return tex
def __init__(self, scene=base.render, ambient=0.2, hardness=16, fov=40, near=10, far=100): """Create an instance of this class to initiate shadows. Also, a shadow casting 'light' is created when this class is called. The first parameter is the nodepath in the scene where you want to apply your shadows on, by default this is render.""" # Read and store the function parameters self.scene = scene self.__ambient = ambient self.__hardness = hardness # By default, mark every object as textured. self.flagTexturedObject(self.scene) # Create the buffer plus a texture to store the output in buffer = createOffscreenBuffer(-3) depthmap = Texture() buffer.addRenderTexture(depthmap, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPColor) # Set the shadow filter if it is supported if base.win.getGsg().getSupportsShadowFilter(): depthmap.setMinfilter(Texture.FTShadow) depthmap.setMagfilter(Texture.FTShadow) # Make the camera self.light = base.makeCamera(buffer) self.light.node().setScene(self.scene) self.light.node().getLens().setFov(fov) self.light.node().getLens().setNearFar(near, far) # Put a shader on the Light camera. lci = NodePath(PandaNode("lightCameraInitializer")) lci.setShader(loader.loadShader("caster.sha")) self.light.node().setInitialState(lci.getState()) # Put a shader on the Main camera. mci = NodePath(PandaNode("mainCameraInitializer")) mci.setShader(loader.loadShader("softshadow.sha")) base.cam.node().setInitialState(mci.getState()) # Set up the blurring buffers, one that blurs horizontally, the other vertically # blurXBuffer = makeFilterBuffer(buffer, "Blur X", -2, loader.loadShader("blurx.sha")) # blurYBuffer = makeFilterBuffer(blurXBuffer, "Blur Y", -1, loader.loadShader("blury.sha")) # Set the shader inputs self.scene.setShaderInput("light", self.light) # self.scene.setShaderInput("depthmap", blurYBuffer.getTexture()) self.scene.setShaderInput("depthmap", buffer.getTexture()) self.scene.setShaderInput("props", ambient, hardness, 0, 1)
class PandaHandler(DirectObject): def __init__(self): DirectObject.__init__(self) # base.disableMouse() # base.cam.setPos(0, -28, 6) self.testModel = loader.loadModel('panda') self.testModel.reparentTo(render) # print self.testModel.getPos() self.rotateInterval = LerpHprInterval(self.testModel, 3, Point3(360, 0, 0)) self.rotateInterval.loop() self.screenTexture = Texture() self.screenTexture.setMinfilter(Texture.FTLinear) base.win.addRenderTexture(self.screenTexture, GraphicsOutput.RTMCopyRam)
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
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 makeTextureBuffer(name, xSize, ySize, tex = None, toRam = False, fbp = None): """Copied from graphicsOutput.cxx and pythonified.""" if fbp == None: fbp = FrameBufferProperties() fbp.setRgbColor(1) fbp.setDepthBits(1) flags = GraphicsPipe.BFRefuseWindow; if hasattr(GraphicsPipe, "BFSizePower2") and Texture.getTexturesPower2() != ATSNone: flags |= GraphicsPipe.BFSizePower2 if tex != None and tex.getTextureType() == Texture.TTCubeMap: flags |= GraphicsPipe.BFSizeSquare buffer = WindowManager.gsg.getEngine().makeOutput(base.pipe, name, 0, fbp, WindowProperties.size(xSize, ySize), flags, WindowManager.gsg) if WindowManager.gsg == None: WindowManager.gsg = buffer.getGsg() if buffer != None: if toRam: buffer.addRenderTexture(tex, RTMCopyRam); else: buffer.addRenderTexture(tex, RTMBindOrCopy); return buffer return None
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
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 _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.1000000000000001, 1.1000000000000001, -1.1000000000000001, 1.1000000000000001) mask = self.attachNewNode(cm.generate()) mask.setTexture(self.maskTexture, 1) mask.setTransparency(1) return mask
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 __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)
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 __setupPreview(self): """Creates the preview.""" if not self.previewCheck.Value: return if self.preview != None: self.__destroyPreview() self.preview = wx.StaticBitmap(self, style = wx.SUNKEN_BORDER, size = PREVIEW_SIZE) self.sizer.Add(self.preview, 0, wx.ADJUST_MINSIZE | wx.ALIGN_CENTER, 0) cm = CardMaker("preview") cm.setFrame(-1, 1, -1, 1) cm.setUvRange(Point2(0, 0), Point2(1, 1)) self.previewTexture = Texture() self.previewBuffer = WindowManager.windows[0].win.makeTextureBuffer("preview", *PREVIEW_SIZE) self.previewBuffer.setClearColor(Vec4(1, 1, 1, 1)) self.previewCamera = base.makeCamera2d(self.previewBuffer) self.previewPlane = NodePath(cm.generate()) self.previewPlane.setFogOff(1000) self.previewPlane.setLightOff(1000) self.previewCamera.node().setScene(self.previewPlane) self.previewBuffer.addRenderTexture(self.previewTexture, GraphicsOutput.RTMCopyRam) self.previewCamera.node().setActive(texturePainter.texturePainterStatus == TEXTURE_PAINTER_STATUS_ENABLED) self.Layout()
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 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)
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
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
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
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 _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')
class World: def __init__(self, actor, state, lvl): #Setzte die Parameter self.CActor = actor #Spieler erstellen self.CGame = state #FSM - Gamestate erstellen self.mission = lvl #Aktuelle Mission self.mMission = None #Grundeinstellen fuer die Welt base.disableMouse() #Mouse ausmachen self.slowdown = 1 #Schnelligkeitsfaktor 1=Normal self.hud = False file, filename, description = imp.find_module("mission" + str(self.mission)) self.mMission = imp.load_module("mission" + str(self.mission), file, filename, description) #SPIELER - Variablen self.oldactorlevel = self.CActor.getLevel() self.CActor.CActorShip.setX( -165) #Setze den Spieler links im Bildschirm self.CActor.CActorShip.setY(0) self.CActor.nActorShip.reparentTo(render) self.CActor.CActorShip.getWeapon().setWeapon( "laserGun") #Standardwaffe setzen self.maxshield = self.CActor.CActorShip.getShield( ) #Schild speichern um Prozent berechnen zu koennen self.hitted = False #Variable um abzufragen ob man getroffen wurde self.dead = False #Spieler lebt self.lbullets = [] #Spielerbullets self.lbulletsspeed = [] self.lcanon = [] #Spielercanonbullets self.lcanonspeed = [] self.cameraeffectx = 0 #X-Wert der Camera um eine Sinuskurve zu implementieren self.cameraeffectamplitude = 5 #Die Amplitude der Sinuswelle - Maxima self.exppercent = (self.CActor.getExperience() * 100 ) / self.CActor.getMaxExperience() #EXP in Prozent self.oldcash = self.CActor.getMoney() self.secweapon = 3 #Resultattexte, wenn die Mission zu ende ist self.txtresultmission = addText(-0.15, 0.35, "") self.txtresultkills = addText(-0.15, 0.25, "") self.txtresultleft = addText(-0.15, 0.20, "") self.txtresultcash = addText(-0.15, 0.15, "") self.txtresultlevel = addText(-0.15, 0.10, "") self.txtresultmessage = addText(-0.15, 0.0, "") #ALLES FUER MOTION BLUR *********************************************************************** #Eine Texture erstellen, welches in das Hauptfenster kopiert wird self.CTex = Texture() self.CTex.setMinfilter(Texture.FTLinear) base.win.addRenderTexture(self.CTex, GraphicsOutput.RTMTriggeredCopyTexture) #Eine andere 2D Kamera erstellen, welches vor der Hauptkamera gerendert wird self.backcam = base.makeCamera2d(base.win, sort=-10) self.background = NodePath("background") self.backcam.reparentTo(self.background) self.background.setDepthTest(0) self.background.setDepthWrite(0) self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) #Zwei Texturekarten ersten. Eins bevor, eins danach self.bcard = base.win.getTextureCard() self.bcard.reparentTo(self.background) self.bcard.setTransparency(1) self.fcard = base.win.getTextureCard() self.fcard.reparentTo(render2d) self.fcard.setTransparency(1) #********************************************************************************************** #Drops als Liste self.ldrop = [] #Explosionen - oder besser gesagt Splittereffekt als Liste self.lexplosions = [] #Soundklasse erstellen um Zugriff auf die Sound zu haben self.CSound = SoundMng() self.CSound.sndFlyAmbience.play() #GEGNER - Variablen self.destroyedenemy = 0 self.lostenemy = 0 self.lenemys = [] #Gegnerspeicher self.lbulletsenemy = [] #Gegnerbullets self.newwave = False #Boolean,welches eine neue Gegnerwelle angibt #Effekte self.CEffects = Effects() #Effektklasse erstellen #self.CEffects.createSpaceStars("particle/background.ptf") #Hintergrundeffekt erstellen #Die Game-Loop Voreinstellungen self.gameTask = taskMgr.add(self.gameLoop, "gameLoop") self.gameTask.last = 0 self.gameTask.nextbullet = 0 #Timer wann geschossen werden darf, vom Spieler self.gameTask.gotHit = 0 self.gameTask.lnextenemybullet = [ ] #Timer wann geschossen werden darf, unabhaengig von welche Gegner self.gameTask.resultkills = 0 #Timer fuer die Kills, im Resultat self.gameTask.resultleft = 0 #Timer fuer die geflohenen Gegner, im Resultat self.gameTask.introduction = 0 self.gameTask.introdelete = 0 self.gameTask.won = 0 self.resultcounter = 0 #Zeahler der die Nummern der Kills im Result aktualisiert self.resultcounterleft = 0 #Zeahler der die Nummern der geflohenen Gegner im Result aktualisiert self.introcounter = 0 self.ldata = [] self.readytospawn = False self.musicplayed = False self.musicplayed2 = False self.resultplayed = False #2D Kamera erstellen lens = OrthographicLens() lens.setFilmSize(350, 250) base.cam.node().setLens(lens) def gameLoop(self, task): #Clock fuer FPS unabhaengige Bewegung elapsed = globalClock.getDt() if task.time > task.introduction: if (self.mMission.getIntroduction(self.introcounter) == True): self.introcounter += 1 task.introduction = task.time + 0.1 else: task.introdelete = task.introduction + 3 if task.time > task.introdelete: if self.musicplayed == False: self.CSound.sndMusic.play() self.musicplayed = True self.toogleHud() self.mMission.removeIntroduction() if self.mMission.getSituation(task.time) == True: for i in range(3): self.ldata.append(self.mMission.getEnemies(i)) self.createEnemys(self.ldata[len(self.ldata) - 3], self.ldata[len(self.ldata) - 1]) self.spawnEnemys(200, self.ldata[len(self.ldata) - 2]) #Die Position der Gegner aktualisieren for obj in self.lenemys: self.updatePosEnemy(obj, elapsed) if obj.nEnemyShip.isEmpty() == 0: if obj.CEnemyShip.getX() < -180: obj.nEnemyShip.removeNode() self.lostenemy += 1 if obj.CEnemyShip.getX() > 170: obj.nEnemyShip.detachNode() if obj.CEnemyShip.getX() < 170 and obj.CEnemyShip.getX( ) > -150: obj.nEnemyShip.reparentTo(render) if self.destroyedenemy + self.lostenemy == self.mMission.MAX_ENEMYS: if task.won == 0: task.won = task.time + 3 if task.won < task.time and self.musicplayed2 == False: self.CSound.sndMusic.stop() self.musicplayed2 = True task.won = task.time + 3 if task.won < task.time: if self.resultplayed == False: self.CSound.sndResult.play() self.CSound.sndFlyAmbience.stop() self.resultplayed = True for drop in self.ldrop: drop.remove() self.txthp.destroy() self.txtshield.destroy() self.txtlvl.destroy() self.imgHud.destroy() self.imgExp.destroy() self.txtresultmission.setText("Mission: " + str(self.mission) + " Complete") if task.time > task.resultkills: if self.resultcounter < self.destroyedenemy: self.resultcounter += 1 self.txtresultkills.setText("Killed Enemies: " + str(self.resultcounter)) self.CSound.sndTipp.play() task.resultkills = task.time + 0.1 if self.resultcounter == self.destroyedenemy: if task.time > task.resultleft: if self.resultcounterleft < self.lostenemy: self.resultcounterleft += 1 self.txtresultleft.setText( "Left Enemies: " + str(self.resultcounterleft)) task.resultleft = task.time + 0.1 self.CSound.sndTipp.play() if self.resultcounterleft == self.lostenemy: self.txtresultcash.setText( "Geldstand: " + str(self.CActor.getMoney()) + "$ (+" + str(self.CActor.getMoney() - self.oldcash) + "$)") self.txtresultlevel.setText( "Dein Level: " + str(self.CActor.getLevel()) + " (+" + str(self.CActor.getLevel() - self.oldactorlevel) + ")") self.txtresultmessage.setText( "Druecke Enter um fortzufahren") if self.CActor.keyMap["entr"] != 0: self.CActor.CActorShip.setShield( self.maxshield) self.CActor.setHP(self.CActor.getMaxHP()) taskMgr.remove('gameLoop') self.CGame.request("GameMenue", self.CActor, self.CGame) if self.dead == True: render.node().removeAllChildren() taskMgr.remove("gameLoop") self.CGame.request("MainMenue", self.CGame) #Falls nextEnemyBullet-Timer NULL ist, so erstelle fuer jeden Gegner einen eigenen Timer if (self.newwave == True): for i in range(len(self.lenemys)): task.lnextenemybullet.append(i) self.newwave = False #Gegnerfeuer erstellen und mit einem Zufallsalgorythmus schiessen lassen for i in range(len(self.lenemys)): posEnemyX = self.lenemys[i].CEnemyShip.getX() #Erst schiessen lassen, wenn sie im Spielbereich sind if posEnemyX < 170 and posEnemyX > -180 and self.lenemys[ i].nEnemyShip.hasParent() == True: if task.time > task.lnextenemybullet[i]: task.lnextenemybullet[i] = task.time + choice( range(4, 7) + range(4, 7)) self.enemyShot(self.lenemys[i]) self.lenemys[i].CEnemyShip.getWeapon().sndGun.setVolume( 0.5) self.lenemys[i].CEnemyShip.getWeapon().sndGun.play() #Nachdem der Spieler die Schiesstaste gedrueckt hat, wird ein Timer aktiviert der nach eine Zeit #immer wieder aktualisiert wird, damit der Spieler den naechsten Schuss abfeuern kann if (self.CActor.keyMap["arr_up"] != 0 and task.time > task.nextbullet): if self.dead == False: task.nextbullet = task.time + 1.25**(-1.5 * self.CActor.getAgility()) self.playerShot("laserGun") self.CActor.CActorShip.getWeapon().sndGun.play() #Nachdem der Spieler die Schiesstaste gedrueckt hat, wird ein Timer aktiviert der nach eine Zeit #immer wieder aktualisiert wird, damit der Spieler den naechsten Schuss abfeuern kann if (self.CActor.keyMap["arr_right"] != 0 and task.time > task.nextbullet): if self.dead == False: task.nextbullet = task.time + 1 + 1.25**( -1.5 * self.CActor.getAgility()) self.playerShot("canonGun") self.CActor.CActorShip.getWeapon().sndGun.play() #Ein Array, um abgeschossen Patronen festzuhalten: vom Spieler lnewbullet = [] #Funktion um die Bullets zu aktualsieren for i in range(len(self.lbullets)): self.updateBulletPlayer(self.lbullets[i], self.lbulletsspeed[i], elapsed) if self.lbullets[i].isEmpty() == 0: if (self.lbullets[i].getX() < 180): lnewbullet.append(self.lbullets[i]) else: self.lbullets[i].remove() self.lbullets = lnewbullet lnewcanon = [] #Funktion um die Bullets zu aktualsieren for i in range(len(self.lcanon)): self.updateBulletPlayer(self.lcanon[i], self.lcanonspeed[i], elapsed) if self.lcanon[i].isEmpty() == 0: if (self.lcanon[i].getX() < 180): lnewcanon.append(self.lcanon[i]) else: self.lcanon[i].remove() self.lcanon = lnewcanon #Ein Array, um abgeschossen Patronen festzuhalten: vom Gegner lnewenemybullet = [] #Funktion um die Bullets der Gegner zu aktualsieren for obj in self.lbulletsenemy: self.updateBulletEnemy(obj, elapsed) if obj.isEmpty() == 0: if (obj.getX() > -180): lnewenemybullet.append(obj) else: obj.remove() self.lbulletsenemy = lnewenemybullet #Funktion fuer die Kollision mit dem Gegner for obj in self.lbullets: self.enemyHit(obj) for obj in self.lcanon: self.enemyHit(obj) #Funktion fuer die Kollision mit dem Spieler if self.playerHit() == True: self.hitted = True #Funktion fuer die Kollision mit dem Schiff if self.getShipHit() == True: self.hitted = True self.dropHit() #Falls Spieler getroffen wird, so mache ein Cameraeffekt if self.hitted == True: if self.CActor.CActorShip.getShield() > 0: self.cameraeffectamplitude = 5 base.camera.setZ(base.camera.getZ() + self.cameraeffectamplitude * math.sin(self.cameraeffectx)) self.cameraeffectx = self.cameraeffectx + 1 if self.cameraeffectx == 20: self.hitted = False self.cameraeffectx = 0 base.camera.setZ(0) else: if (self.dead == False): self.cameraeffectamplitude = 2 base.camera.setZ(base.camera.getZ() + self.cameraeffectamplitude * math.sin(self.cameraeffectx)) self.cameraeffectx = self.cameraeffectx + 1 else: self.hitted = False for obj in self.ldrop: if obj != None: if obj.isEmpty() == 0: obj.setHpr(obj.getH() - 1, 0, 0) for obj in self.lexplosions: if obj != None: if obj.isEmpty() == 0: posy = obj.getZ() self.updateExplosion( obj, elapsed, -3, choice(range(-11, 11) + range(-11, 11))) if obj.getX() < -180: obj.remove() return Task.cont def updateExplosion(self, obj, dt, x, y): if obj.isEmpty() == 0: newposx = obj.getX() + (self.slowdown * dt * 35 * 3) * x newposy = obj.getZ() + (self.slowdown * dt * 35 * 3) * y obj.setX(newposx) obj.setZ(newposy) def updateBulletPlayer(self, obj, spe, dt): if obj.isEmpty() == 0: newpos = obj.getX() + (self.slowdown * dt * 35 * spe) obj.setX(newpos) def updateBulletEnemy(self, obj, dt): if obj.isEmpty() == 0: newpos = obj.getX() - ( self.slowdown * dt * 35 * self.CEnemy.CEnemyShip.getWeapon().getWeaponSpeed()) obj.setX(newpos) def updatePosEnemy(self, obj, dt): if obj.nEnemyShip.isEmpty() == 0: obj.CEnemyShip.setX(obj.CEnemyShip.getX() - self.slowdown * dt * 15 * obj.CEnemyShip.getSpeed()) obj.CEnemyShip.setY(obj.CEnemyShip.getY() + self.slowdown * dt * 15 * (math.sin(0.1 * obj.CEnemyShip.getX()))) def playerShot(self, gun): bullet = self.CActor.CActorShip.getWeapon().setWeapon(gun) if bullet.isEmpty() == 0: if self.secweapon == 3: bullet.setPos(self.CActor.CActorShip.getX() + 10, 500, self.CActor.CActorShip.getY() + self.secweapon) self.secweapon = -4 else: bullet.setPos(self.CActor.CActorShip.getX() + 10, 500, self.CActor.CActorShip.getY() + self.secweapon) self.secweapon = 3 print self.CActor.CActorShip.getWeapon().getWeapon() if self.CActor.CActorShip.getWeapon().getWeapon() == "laserGun": self.lbullets.append(bullet) self.lbulletsspeed.append( self.CActor.CActorShip.getWeapon().getWeaponSpeed()) elif self.CActor.CActorShip.getWeapon().getWeapon() == "canonGun": self.lcanon.append(bullet) self.lcanonspeed.append( self.CActor.CActorShip.getWeapon().getWeaponSpeed()) del bullet def enemyShot(self, obj): bullet = obj.CEnemyShip.getWeapon().setWeapon("laserGun") if obj.nEnemyShip.isEmpty() == 0: bullet.setPos(obj.nEnemyShip.getPos()) self.lbulletsenemy.append(bullet) del bullet def addDrop(self, pos): drp = self.CEffects.getDrop("models/heal", 19, pos) if (drp == None): return False else: self.ldrop.append(drp) return True def explode(self, pos): expl = self.CEffects.getExplosion(pos) self.lexplosions.append(expl) def enemyHit(self, bullet): for enmy in self.lenemys: if enmy.nEnemyShip.isEmpty() == 0 and bullet.isEmpty() == 0: #Falls Gegner getroffen wird if (bullet.getPos() - enmy.nEnemyShip.getPos()).lengthSquared() < 85: #Bullet loesche bullet.remove() self.explode(enmy.nEnemyShip.getPos()) enmy.CEnemyShip.setShield( enmy.CEnemyShip.getShield() - self.CActor.CActorShip.getWeapon().getWeaponStrength()) self.CSound.sndHit.play() #Falls kein Schild mehr vorhanden -> Loeschen if enmy.CEnemyShip.getShield() <= 0: self.addDrop(enmy.nEnemyShip.getPos()) for i in range(5): self.explode(enmy.nEnemyShip.getPos()) enmy.nEnemyShip.removeNode() self.CSound.sndExplosion.play() self.destroyedenemy += 1 self.CActor.setExperience(self.CActor.getExperience() + (enmy.getExpDrop())) self.exppercent = (self.CActor.getExperience() * 100 ) / self.CActor.getMaxExperience() if self.imgExp.isEmpty() == 0: self.imgExp.setScale( 0.01, 0.2, ((2.0 * self.exppercent) / 100.0)) self.CActor.setMoney(self.CActor.getMoney() + enmy.getCashDrop()) if self.CActor.getLevelUp() == True: self.txtlvl.setText(str(self.CActor.getLevel())) self.CActor.setExperience(self.CActor.getExperience() + (enmy.getExpDrop() / 2)) self.exppercent = (self.CActor.getExperience() * 100 ) / self.CActor.getMaxExperience() self.imgExp.setScale(0.01, 0.2, 0.002) def playerHit(self): for bullet in self.lbulletsenemy: if self.CActor.nActorShip.isEmpty() == 0 and bullet.isEmpty() == 0: #Falls Spieler getroffen wird if ((bullet.getPos() - self.CActor.nActorShip.getPos()).lengthSquared() < 85): #Bullet loeschen bullet.remove() #Funktion aufrufen - Parameter: Schaden if self.actorHurt(self.CEnemy.CEnemyShip.getWeapon( ).getWeaponStrength() + self.CEnemy.getStrength()) == True: return True def getShipHit(self): for enmy in self.lenemys: if enmy.nEnemyShip.isEmpty( ) == 0 and self.CActor.nActorShip.isEmpty() == 0: #Falls das Spielerschiff einen Gegnerschiff trifft if ((enmy.nEnemyShip.getPos() - self.CActor.nActorShip.getPos()).lengthSquared() < 85): for i in range(5): self.explode(enmy.nEnemyShip.getPos()) enmy.nEnemyShip.removeNode() #self.CSound.sndExplosion.play() self.destroyedenemy += 1 self.CActor.setExperience(self.CActor.getExperience() + (enmy.getExpDrop() / 2)) self.exppercent = (self.CActor.getExperience() * 100) / self.CActor.getMaxExperience() if self.CActor.getLevelUp() == True: self.txtlvl.setText(str(self.CActor.getLevel())) self.CActor.setExperience(self.CActor.getExperience() + (enmy.getExpDrop() / 2)) self.exppercent = (self.CActor.getExperience() * 100 ) / self.CActor.getMaxExperience() #Schaden ist gleich der Staerke vom gegnerischen Schiff if self.actorHurt(enmy.getStrength()) == True: return True def createEnemys(self, amount, kind): for i in range(amount): #Gegner erstellen self.CEnemy = Enemy(kind) self.lenemys.append(self.CEnemy) def spawnEnemys(self, start, width): for obj in self.lenemys: if obj.CEnemyShip.getY() > 101 and obj.nEnemyShip.isEmpty() == 0: obj.CEnemyShip.setX( choice(range(start, width) + range(start, width))) obj.CEnemyShip.setY(choice(range(-100, 0) + range(0, 100))) self.newwave = True def dropHit(self): for obj in self.ldrop: if obj.isEmpty() == 0 and self.CActor.nActorShip.isEmpty() == 0: if ((obj.getPos() - self.CActor.nActorShip.getPos()).lengthSquared() < 86): obj.remove() if self.CActor.getHP() < self.CActor.getMaxHP(): self.CActor.setHP(self.CActor.getHP() + 20) self.txthp.setText( str((self.CActor.getHP() * 100) / self.CActor.getMaxHP())) def actorHurt(self, dmg): if (self.CActor.CActorShip.getShield() <= 0): self.txtshield.setText("0") self.CActor.CActorShip.setShield(0) self.CActor.setHP(self.CActor.getHP() - dmg * 20) self.CSound.sndCrit.play() if (self.CActor.getHP() <= 0): #Der Spieler ist tot und hat verloren self.txthp.setText("0") self.dead = True #self.CFilters.setBloom(blend=(0,0,0,1), desat=-0.5, intensity=5.0, size="small") self.slowdown = 1 self.CActor.slowdown = self.slowdown taskMgr.remove("takeSnapShot") self.clickrate = 0 self.fcard.hide() for i in range(5): self.explode(self.CActor.nActorShip.getPos()) self.CActor.nActorShip.detachNode() return True if (self.CActor.getHP() <= 50): self.CSound.sndExplosion.setPlayRate(0.5) self.CSound.sndMusic.setPlayRate(0.5) self.CSound.sndFlyAmbience.setPlayRate(0.5) self.CSound.sndHit.setPlayRate(0.5) self.CActor.CActorShip.getWeapon().sndGun.setPlayRate(0.5) taskMgr.add(self.takeSnapShot, "takeSnapShot") self.chooseEffectGhost() self.slowdown = 0.5 self.CActor.setSlowDown(self.slowdown) #self.CFilters.delBloom() self.explode(self.CActor.nActorShip.getPos()) self.txthp.setText( str((self.CActor.getHP() * 100) / self.CActor.getMaxHP())) return True else: self.CActor.CActorShip.setShield( self.CActor.CActorShip.getShield() - dmg) self.txtshield.setText( str((self.CActor.CActorShip.getShield() * 100) / self.maxshield)) self.explode(self.CActor.nActorShip.getPos()) return True #Screenshots erstellen um MotionBlur Effekt zu erreichen def takeSnapShot(self, task): if (task.time > self.nextclick): self.nextclick += 1.0 / self.clickrate if (self.nextclick < task.time): self.nextclick = task.time base.win.triggerCopy() return Task.cont #MotionBlur Effekt def chooseEffectGhost(self): base.setBackgroundColor(0, 0, 0, 1) self.bcard.hide() self.fcard.show() self.fcard.setColor(1.0, 1.0, 1.0, 0.99) self.fcard.setScale(1.00) self.fcard.setPos(0, 0, 0) self.fcard.setR(0) self.clickrate = 100 self.nextclick = 0 def toogleHud(self): if self.hud == False: #Hudeinstellung ******************************************************************************* self.imgHud = OnscreenImage(image='images/hud.png', pos=(-1.09, 0, -0.01), scale=(0.185, 0.5, 1)) self.imgHud.reparentTo(aspect2d) self.imgHud.setTransparency(TransparencyAttrib.MAlpha) #EXP Leiste self.imgExp = OnscreenImage(image='images/exp.png', pos=(-1.2645, 0, -1), scale=(0.01, 0.2, 0.001)) self.imgExp.reparentTo(aspect2d) #Texte der HUD self.txthp = addText( -1.03, 0.966, str((self.CActor.getHP() * 100) / self.CActor.getMaxHP())) self.txtshield = addText( -1.03, 0.9151, str((self.CActor.CActorShip.getShield() * 100) / self.maxshield)) self.txtlvl = addText(-1.19, 0.80, str(self.CActor.getLevel())) self.hud = True
def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None): """ Causes the scene to be rendered into the supplied textures instead of into the original window. Puts a fullscreen quad into the original window to show the render-to-texture results. Returns the quad. Normally, the caller would then apply a shader to the quad. To elaborate on how this all works: * An offscreen buffer is created. It is set up to mimic the original display region - it is the same size, uses the same clear colors, and contains a DisplayRegion that uses the original camera. * A fullscreen quad and an orthographic camera to render that quad are both created. The original camera is removed from the original window, and in its place, the orthographic quad-camera is installed. * The fullscreen quad is textured with the data from the offscreen buffer. A shader is applied that tints the results pink. * Automatic shader generation NOT enabled. If you have a filter that depends on a render target from the auto-shader, you either need to set an auto-shader attrib on the main camera or scene, or, you need to provide these outputs in your own shader. * All clears are disabled on the original display region. If the display region fills the whole window, then clears are disabled on the original window as well. It is assumed that rendering the full-screen quad eliminates the need to do clears. Hence, the original window which used to contain the actual scene, now contains a pink-tinted quad with a texture of the scene. It is assumed that the user will replace the shader on the quad with a more interesting filter. """ if (textures): colortex = textures.get("color", None) depthtex = textures.get("depth", None) auxtex = textures.get("aux", None) auxtex0 = textures.get("aux0", auxtex) auxtex1 = textures.get("aux1", None) else: auxtex0 = auxtex auxtex1 = None if (colortex == None): colortex = Texture("filter-base-color") colortex.setWrapU(Texture.WMClamp) colortex.setWrapV(Texture.WMClamp) texgroup = (depthtex, colortex, auxtex0, auxtex1) # Choose the size of the offscreen buffer. (winx, winy) = self.getScaledSize(1,1,1) buffer = self.createBuffer("filter-base", winx, winy, texgroup) if (buffer == None): return None cm = CardMaker("filter-base-quad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setTexture(colortex) quad.setColor(Vec4(1,0.5,0.5,1)) cs = NodePath("dummy") cs.setState(self.camstate) # Do we really need to turn on the Shader Generator? #cs.setShaderAuto() if (auxbits): cs.setAttrib(AuxBitplaneAttrib.make(auxbits)) self.camera.node().setInitialState(cs.getState()) quadcamnode = Camera("filter-quad-cam") lens = OrthographicLens() lens.setFilmSize(2, 2) lens.setFilmOffset(0, 0) lens.setNearFar(-1000, 1000) quadcamnode.setLens(lens) quadcam = quad.attachNewNode(quadcamnode) self.region.setCamera(quadcam) self.setStackedClears(buffer, self.rclears, self.wclears) if (auxtex0): buffer.setClearActive(GraphicsOutput.RTPAuxRgba0, 1) buffer.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5, 0.5, 1.0, 0.0)) if (auxtex1): buffer.setClearActive(GraphicsOutput.RTPAuxRgba1, 1) self.region.disableClears() if (self.isFullscreen()): self.win.disableClears() dr = buffer.makeDisplayRegion() dr.disableClears() dr.setCamera(self.camera) dr.setActive(1) self.buffers.append(buffer) self.sizes.append((1, 1, 1)) return quad
def __init__(self, markerImage='marker.jpg', calib_file='test.npz'): ShowBase.__init__(self) base.disableMouse() self.marker = cv2.imread(markerImage) self.marker = cv2.flip(self.marker, 0) self.kp_marker, self.des_marker = getDes(self.marker) if useCamera: self.cap = cv2.VideoCapture(0) ret, frame = self.cap.read() else: ret, frame = True, cv2.imread("sample_0.jpg") if ret: self.frame = frame self.criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) with np.load(calib_file) as calib_File: self.K = calib_File['mtx'] self.D = calib_File['coef'] (h, w) = frame.shape[0:2] print w, h far = 100 near = 0.1 fovx, fovy, f, (cx, cy), a = cv2.calibrationMatrixValues( self.K, (w, h), w, h) print fovx, fovy, f, cx, cy base.camLens.setFilmSize(w, h) base.camLens.setFilmOffset(w * 0.5 - cx, h * 0.5 - cy) base.camLens.setFocalLength(f) base.camLens.setFov(fovx, fovy) base.camLens.setNearFar(near, far) #base.camLens.setCoordinateSystem(4) base.camLens.setCoordinateSystem(4) #base.camLens.setViewVector(Vec3(0,0,1), Vec3(0,1,0)) #self.render.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) self.tex = Texture("detect") #self.buff.getTexture() self.tex.setCompression(Texture.CMOff) self.tex.setup2dTexture(w, h, Texture.TUnsignedByte, Texture.FRgb) self.b = OnscreenImage(parent=render2d, image=self.tex) base.cam.node().getDisplayRegion(0).setSort(20) self.taskMgr.add(self.updateFrameTask, "UpdateCameraFrameTask") self.modelroot = NodePath('ARRootNode') self.modelroot.reparentTo(self.render) ''' self.x = self.loader.loadModel("models/box") self.x.reparentTo(self.modelroot) self.x.setScale(3, 0.1, 0.1) self.x.setPos(0, -0.05, -0.05) self.x.setColor(1,0,0,1,1) self.y = self.loader.loadModel("models/box") self.y.reparentTo(self.modelroot) self.y.setScale(0.1, 3, 0.1) self.y.setPos(-0.05, 0, -0.05) self.y.setColor(0,1,0,1,1) self.z = self.loader.loadModel("models/box") self.z.reparentTo(self.modelroot) self.z.setScale(0.1, 0.1, 3) self.z.setPos(-0.05, -0.05, 0) self.z.setColor(0,0,1,1,1) ''' self.panda = NodePath('PandaRoot') self.panda.reparentTo(self.modelroot) # Load and transform the panda actor. self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"}) self.pandaActor.setScale(0.003, 0.003, 0.003) self.pandaActor.reparentTo(self.panda) self.pandaActor.loop("walk") self.pandaActor.setH(180) #self.pandaMotion = MopathInterval("Panda Path", self.panda, "Interval Name") self.pathCurve = createNurbsCurve() for i in range(0, 30): self.pathCurve.addPoint( (random.uniform(1, 7), random.uniform(1, 7), 0)) ''' self.pathCurve.addPoint((1, 5, 0)) self.pathCurve.addPoint((5, 5, 0)) self.pathCurve.addPoint((5, 1, 0)) self.pathCurve.addPoint((1, 1, 0)) ''' curveNode = self.pathCurve.getNodepath() self.myMopath = Mopath() self.myMopath.loadNodePath(curveNode) self.myMopath.fFaceForward = True myInterval = MopathInterval(self.myMopath, self.panda, duration=100, name="Name") myInterval.loop()
def reconfigure(self, fullrebuild, changed): """ Reconfigure is called whenever any configuration change is made. """ configuration = self.configuration if (fullrebuild): self.cleanup() if (len(configuration) == 0): return auxbits = 0 needtex = {} needtex["color"] = True if (configuration.has_key("CartoonInk")): needtex["aux"] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if (configuration.has_key("AmbientOcclusion")): needtex["depth"] = True needtex["ssao0"] = True needtex["ssao1"] = True needtex["ssao2"] = True needtex["aux"] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if (configuration.has_key("BlurSharpen")): needtex["blur0"] = True needtex["blur1"] = True if (configuration.has_key("Bloom")): needtex["bloom0"] = True needtex["bloom1"] = True needtex["bloom2"] = True needtex["bloom3"] = True auxbits |= AuxBitplaneAttrib.ABOGlow if (configuration.has_key("ViewGlow")): auxbits |= AuxBitplaneAttrib.ABOGlow for tex in needtex: self.textures[tex] = Texture("scene-" + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) needtexpix = True self.finalQuad = self.manager.renderSceneInto( textures=self.textures, auxbits=auxbits) if (self.finalQuad == None): self.cleanup() return False if (configuration.has_key("BlurSharpen")): blur0 = self.textures["blur0"] blur1 = self.textures["blur1"] self.blur.append( self.manager.renderQuadInto(colortex=blur0, div=2)) self.blur.append(self.manager.renderQuadInto(colortex=blur1)) self.blur[0].setShaderInput("src", self.textures["color"]) self.blur[0].setShader(self.loadShader("filter-blurx.sha")) self.blur[1].setShaderInput("src", blur0) self.blur[1].setShader(self.loadShader("filter-blury.sha")) if (configuration.has_key("AmbientOcclusion")): ssao0 = self.textures["ssao0"] ssao1 = self.textures["ssao1"] ssao2 = self.textures["ssao2"] self.ssao.append(self.manager.renderQuadInto(colortex=ssao0)) self.ssao.append( self.manager.renderQuadInto(colortex=ssao1, div=2)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao2)) self.ssao[0].setShaderInput("depth", self.textures["depth"]) self.ssao[0].setShaderInput("normal", self.textures["aux"]) self.ssao[0].setShaderInput( "random", loader.loadTexture("maps/random.rgb")) self.ssao[0].setShader(self.loadShader("filter-ssao.sha")) self.ssao[1].setShaderInput("src", ssao0) self.ssao[1].setShader(self.loadShader("filter-blurx.sha")) self.ssao[2].setShaderInput("src", ssao1) self.ssao[2].setShader(self.loadShader("filter-blury.sha")) if (configuration.has_key("Bloom")): bloomconf = configuration["Bloom"] bloom0 = self.textures["bloom0"] bloom1 = self.textures["bloom1"] bloom2 = self.textures["bloom2"] bloom3 = self.textures["bloom3"] if (bloomconf.size == "large"): scale = 8 downsampler = "filter-down4.sha" elif (bloomconf.size == "medium"): scale = 4 downsampler = "filter-copy.sha" else: scale = 2 downsampler = "filter-copy.sha" self.bloom.append( self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput("src", self.textures["color"]) self.bloom[0].setShader(self.loadShader("filter-bloomi.sha")) self.bloom[1].setShaderInput("src", bloom0) self.bloom[1].setShader(self.loadShader(downsampler)) self.bloom[2].setShaderInput("src", bloom1) self.bloom[2].setShader(self.loadShader("filter-bloomx.sha")) self.bloom[3].setShaderInput("src", bloom2) self.bloom[3].setShader(self.loadShader("filter-bloomy.sha")) text = "//Cg\n" text += "void vshader(float4 vtx_position : POSITION,\n" text += " out float4 l_position : POSITION,\n" text += " uniform float4 texpad_txcolor,\n" text += " uniform float4 texpix_txcolor,\n" text += " out float4 l_texcoordC : TEXCOORD0,\n" if (configuration.has_key("CartoonInk")): text += " uniform float4 texpad_txaux,\n" text += " uniform float4 texpix_txaux,\n" text += " out float4 l_texcoordN : TEXCOORD1,\n" if (configuration.has_key("Bloom")): text += " uniform float4 texpad_txbloom3,\n" text += " out float4 l_texcoordB : TEXCOORD2,\n" if (configuration.has_key("BlurSharpen")): text += " uniform float4 texpad_txblur1,\n" text += " out float4 l_texcoordBS : TEXCOORD3,\n" if (configuration.has_key("AmbientOcclusion")): text += " uniform float4 texpad_txssao2,\n" text += " out float4 l_texcoordAO : TEXCOORD4,\n" text += " uniform float4x4 mat_modelproj)\n" text += "{\n" text += " l_position=mul(mat_modelproj, vtx_position);\n" text += " l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n" if (configuration.has_key("CartoonInk")): text += " l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n" if (configuration.has_key("Bloom")): text += " l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n" if (configuration.has_key("BlurSharpen")): text += " l_texcoordBS=(vtx_position.xzxz * texpad_txblur1) + texpad_txblur1;\n" if (configuration.has_key("AmbientOcclusion")): text += " l_texcoordAO=(vtx_position.xzxz * texpad_txssao2) + texpad_txssao2;\n" if (configuration.has_key("HalfPixelShift")): text += " l_texcoordC+=texpix_txcolor*0.5;\n" if (configuration.has_key("CartoonInk")): text += " l_texcoordN+=texpix_txaux*0.5;\n" text += "}\n" text += "void fshader(\n" text += "float4 l_texcoordC : TEXCOORD0,\n" text += "uniform float4 texpix_txcolor,\n" if (configuration.has_key("CartoonInk")): text += "float4 l_texcoordN : TEXCOORD1,\n" text += "uniform float4 texpix_txaux,\n" if (configuration.has_key("Bloom")): text += "float4 l_texcoordB : TEXCOORD2,\n" if (configuration.has_key("BlurSharpen")): text += "float4 l_texcoordBS : TEXCOORD3,\n" text += "uniform float4 k_blurval,\n" if (configuration.has_key("AmbientOcclusion")): text += "float4 l_texcoordAO : TEXCOORD4,\n" for key in self.textures: text += "uniform sampler2D k_tx" + key + ",\n" if (configuration.has_key("CartoonInk")): text += "uniform float4 k_cartoonseparation,\n" if (configuration.has_key("VolumetricLighting")): text += "uniform float4 k_casterpos,\n" text += "uniform float4 k_vlparams,\n" text += "out float4 o_color : COLOR)\n" text += "{\n" text += " o_color = tex2D(k_txcolor, l_texcoordC.xy);\n" if (configuration.has_key("CartoonInk")): text += CARTOON_BODY if (configuration.has_key("AmbientOcclusion")): text += "o_color *= tex2D(k_txssao2, l_texcoordAO.xy).r;\n" if (configuration.has_key("BlurSharpen")): text += " o_color = lerp(tex2D(k_txblur1, l_texcoordBS.xy), o_color, k_blurval.x);\n" if (configuration.has_key("Bloom")): text += "o_color = saturate(o_color);\n" text += "float4 bloom = 0.5*tex2D(k_txbloom3, l_texcoordB.xy);\n" text += "o_color = 1-((1-bloom)*(1-o_color));\n" if (configuration.has_key("ViewGlow")): text += "o_color.r = o_color.a;\n" if (configuration.has_key("VolumetricLighting")): text += "float decay = 1.0f;\n" text += "float2 curcoord = l_texcoordC.xy;\n" text += "float2 lightdir = curcoord - k_casterpos.xy;\n" text += "lightdir *= k_vlparams.x;\n" text += "half4 sample = tex2D(k_txcolor, curcoord);\n" text += "float3 vlcolor = sample.rgb * sample.a;\n" text += "for (int i = 0; i < %s; i++) {\n" % int( configuration["VolumetricLighting"].numsamples) text += " curcoord -= lightdir;\n" text += " sample = tex2D(k_txcolor, curcoord);\n" text += " sample *= sample.a * decay;//*weight\n" text += " vlcolor += sample.rgb;\n" text += " decay *= k_vlparams.y;\n" text += "}\n" text += "o_color += float4(vlcolor * k_vlparams.z, 1);\n" if (configuration.has_key("Inverted")): text += "o_color = float4(1, 1, 1, 1) - o_color;\n" text += "}\n" self.finalQuad.setShader(Shader.make(text)) for tex in self.textures: self.finalQuad.setShaderInput("tx" + tex, self.textures[tex]) self.task = taskMgr.add(self.update, "common-filters-update") if (changed == "CartoonInk") or fullrebuild: if (configuration.has_key("CartoonInk")): separation = configuration["CartoonInk"] self.finalQuad.setShaderInput( "cartoonseparation", Vec4(separation, 0, separation, 0)) if (changed == "BlurSharpen") or fullrebuild: if (configuration.has_key("BlurSharpen")): blurval = configuration["BlurSharpen"] self.finalQuad.setShaderInput( "blurval", Vec4(blurval, blurval, blurval, blurval)) if (changed == "Bloom") or fullrebuild: if (configuration.has_key("Bloom")): bloomconf = configuration["Bloom"] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput("blend", bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0) self.bloom[0].setShaderInput( "trigger", bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0) self.bloom[0].setShaderInput("desat", bloomconf.desat) self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity) if (changed == "VolumetricLighting") or fullrebuild: if (configuration.has_key("VolumetricLighting")): config = configuration["VolumetricLighting"] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput("vlparams", tcparam, config.decay, config.exposure, 0.0) if (changed == "AmbientOcclusion") or fullrebuild: if (configuration.has_key("AmbientOcclusion")): config = configuration["AmbientOcclusion"] self.ssao[0].setShaderInput( "params1", config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0) self.ssao[0].setShaderInput("params2", config.strength, config.falloff, 0, 0) self.update() return True
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
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)
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)
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)
class MyApp(ShowBase): def __init__(self, markerImage='marker.jpg', calib_file='test.npz'): ShowBase.__init__(self) base.disableMouse() self.marker = cv2.imread(markerImage) self.marker = cv2.flip(self.marker, 0) self.kp_marker, self.des_marker = getDes(self.marker) if useCamera: self.cap = cv2.VideoCapture(0) ret, frame = self.cap.read() else: ret, frame = True, cv2.imread("sample_0.jpg") if ret: self.frame = frame self.criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) with np.load(calib_file) as calib_File: self.K = calib_File['mtx'] self.D = calib_File['coef'] (h, w) = frame.shape[0:2] print w, h far = 100 near = 0.1 fovx, fovy, f, (cx, cy), a = cv2.calibrationMatrixValues( self.K, (w, h), w, h) print fovx, fovy, f, cx, cy base.camLens.setFilmSize(w, h) base.camLens.setFilmOffset(w * 0.5 - cx, h * 0.5 - cy) base.camLens.setFocalLength(f) base.camLens.setFov(fovx, fovy) base.camLens.setNearFar(near, far) #base.camLens.setCoordinateSystem(4) base.camLens.setCoordinateSystem(4) #base.camLens.setViewVector(Vec3(0,0,1), Vec3(0,1,0)) #self.render.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) self.tex = Texture("detect") #self.buff.getTexture() self.tex.setCompression(Texture.CMOff) self.tex.setup2dTexture(w, h, Texture.TUnsignedByte, Texture.FRgb) self.b = OnscreenImage(parent=render2d, image=self.tex) base.cam.node().getDisplayRegion(0).setSort(20) self.taskMgr.add(self.updateFrameTask, "UpdateCameraFrameTask") self.modelroot = NodePath('ARRootNode') self.modelroot.reparentTo(self.render) ''' self.x = self.loader.loadModel("models/box") self.x.reparentTo(self.modelroot) self.x.setScale(3, 0.1, 0.1) self.x.setPos(0, -0.05, -0.05) self.x.setColor(1,0,0,1,1) self.y = self.loader.loadModel("models/box") self.y.reparentTo(self.modelroot) self.y.setScale(0.1, 3, 0.1) self.y.setPos(-0.05, 0, -0.05) self.y.setColor(0,1,0,1,1) self.z = self.loader.loadModel("models/box") self.z.reparentTo(self.modelroot) self.z.setScale(0.1, 0.1, 3) self.z.setPos(-0.05, -0.05, 0) self.z.setColor(0,0,1,1,1) ''' self.panda = NodePath('PandaRoot') self.panda.reparentTo(self.modelroot) # Load and transform the panda actor. self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"}) self.pandaActor.setScale(0.003, 0.003, 0.003) self.pandaActor.reparentTo(self.panda) self.pandaActor.loop("walk") self.pandaActor.setH(180) #self.pandaMotion = MopathInterval("Panda Path", self.panda, "Interval Name") self.pathCurve = createNurbsCurve() for i in range(0, 30): self.pathCurve.addPoint( (random.uniform(1, 7), random.uniform(1, 7), 0)) ''' self.pathCurve.addPoint((1, 5, 0)) self.pathCurve.addPoint((5, 5, 0)) self.pathCurve.addPoint((5, 1, 0)) self.pathCurve.addPoint((1, 1, 0)) ''' curveNode = self.pathCurve.getNodepath() self.myMopath = Mopath() self.myMopath.loadNodePath(curveNode) self.myMopath.fFaceForward = True myInterval = MopathInterval(self.myMopath, self.panda, duration=100, name="Name") myInterval.loop() # This task runs for two seconds, then prints done def updateFrameTask(self, task): if useCamera: ret, frame = self.cap.read() else: ret, frame = True, self.frame if ret: frame = cv2.flip(frame, 0) kp_frame, des_frame = getDes(frame) matches = getMatches(self.des_marker, des_frame) if not matches or len(matches) < 5: return task.cont pattern_points = [self.kp_marker[pt.trainIdx].pt for pt in matches] pattern_points = np.array([(x / 50.0, y / 50.0, 0) for x, y in pattern_points], dtype=np.float32) image_points = np.array( [kp_frame[pt.queryIdx].pt for pt in matches], dtype=np.float32) #ret, rvecs, tvecs = cv2.solvePnP(pattern_points, image_points, self.K, None) rvecs, tvecs, inliers = cv2.solvePnPRansac(pattern_points, image_points, self.K, None) #print "Tadam!",rvecs, tvecs #img_pts, jac = cv2.projectPoints(axis, rvecs, tvecs, camera_matrix, dist_coefs) #draw_lines(image, img_pts) T = tvecs.ravel() R = rvecs.ravel() RotM, _ = cv2.Rodrigues(R) RotM = RotM.T RotM = Mat3( RotM[0, 0], RotM[0, 1], RotM[0, 2], RotM[1, 0], RotM[1, 1], RotM[1, 2], # RotM[2,0],RotM[2,1],RotM[2,2]) -RotM[2, 0], -RotM[2, 1], -RotM[2, 2]) self.modelroot.setMat(Mat4(RotM, Vec3(T[0], T[1], T[2]))) self.tex.setRamImage(frame) self.b.setImage(image=self.tex, parent=render2d) self.camera.setPos(0, 0, 0) self.camera.setHpr(0, 0, 0) self.camera.setScale(1, 1, 1) return task.cont
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
class Effect: baseWidth = 0 baseHeight = 0 effectWidth = 1 effectHeight = 1 effectTargetMS = 143 noSampling = False tex = None loadedFormat = None # Animation variables internalFrameIndex = 1 startIndex = 1 endIndex = 1 loopEffect = False # XML variables tree = None frames = None colors = None tweens = None compositeFrames = None # Nodes consumedNodesList = None # Accessible object (nodePath) effectCameraNodePath = None effectCardNodePath = None # Constant value; Unit comparison for card size; basis is from cure, which is [140x110] cardDimensionBasis = [-5.0, 5.0, 0.0, 10.0, 140.0, 110.0] pixelScaleX = cardDimensionBasis[4]/(cardDimensionBasis[1]-cardDimensionBasis[0]) pixelScaleZ = cardDimensionBasis[5]/(cardDimensionBasis[3]-cardDimensionBasis[2]) effectIsCentered = True effectAdjustment = [0, 0, 0] def __init__(self, effectFileName, parent=None, loop=False, effectIsCentered=True, effectAdjustment=[0, 0, 0]): self.effectAdjustment = effectAdjustment self.loopEffect = loop self.effectIsCentered = effectIsCentered self.loadedFormat = None if effectFileName != None: effectFileNameSplit = effectFileName.split('.') self.loadedFormat = effectFileNameSplit[len(effectFileNameSplit)-2] # Get value at penultimate index if self.loadedFormat == effectFileNameSplit[0]: self.loadedFormat = None # Get rid of bad format name. pass # Load texture; supply alpha channel if it doesn't exist. p = transparencyKey(effectFileName) self.tex = Texture() self.tex.setup2dTexture(p.getXSize(), p.getYSize(), Texture.TUnsignedByte, Texture.FRgba) self.tex.load(p) if self.loadedFormat != None: try: self.tree = etree.parse("./"+GAME+"/effects/"+self.loadedFormat+"/sprite.xml") except IOError: self.loadedFormat = None pass if self.loadedFormat != None: root = self.tree.getroot() self.frames = root.find('.//frames') self.colors = root.find('.//colors') self.tweens = root.find('.//motion-tweens') self.compositeFrames = root.find('.//composite-frames') self.baseWidth = 0 if root.attrib.get("base-width") == None else float(root.attrib.get("base-width")) self.baseHeight = 0 if root.attrib.get("base-height") == None else float(root.attrib.get("base-height")) self.effectWidth = 1 if root.attrib.get("frame-width") == None else float(root.attrib.get("frame-width")) self.effectHeight = 1 if root.attrib.get("frame-height") == None else float(root.attrib.get("frame-height")) self.effectTargetMS = 143 if root.attrib.get("target-ms") == None else float(root.attrib.get("target-ms")) self.startIndex = 1 if root.attrib.get("target-start") == None else int(root.attrib.get("target-start")) self.endIndex = 1 if root.attrib.get("target-end") == None else int(root.attrib.get("target-end")) self.noSampling = False if root.attrib.get("no-sampling") == None else bool(root.attrib.get("no-sampling")) if self.noSampling==True: self.tex.setMagfilter(Texture.FTNearest) self.tex.setMinfilter(Texture.FTNearest) cm = CardMaker('card-'+effectFileName) cardDeltaX = self.effectWidth / self.pixelScaleX cardDeltaZ = self.effectHeight / self.pixelScaleZ if self.effectIsCentered == True: cm.setFrame(0, 0, 0, 0) deltaX = (cardDeltaX/2.0) - (-cardDeltaX/2.0) deltaY = 0 deltaZ = (cardDeltaZ/2.0) - (-cardDeltaZ/2.0) #occluder = OccluderNode('effect-parent-occluder', Point3((-cardDeltaX/2.0), 0, (-cardDeltaZ/2.0)), Point3((-cardDeltaX/2.0), 0, (cardDeltaZ/2.0)), Point3((cardDeltaX/2.0), 0, (cardDeltaZ/2.0)), Point3((cardDeltaX/2.0), 0, (-cardDeltaZ/2.0))) else: cm.setFrame(0, 0, 0, 0) deltaX = (cardDeltaX/2.0) - (-cardDeltaX/2.0) deltaY = 0 deltaZ = cardDeltaZ - 0 #occluder = OccluderNode('effect-parent-occluder', Point3((-cardDeltaX/2.0), 0, 0), Point3((-cardDeltaX/2.0), 0, cardDeltaZ), Point3((cardDeltaX/2.0), 0, cardDeltaZ), Point3((cardDeltaX/2.0), 0, 0)) self.effectCardNodePath = render.attachNewNode(cm.generate()) self.effectCardNodePath.setBillboardPointEye() self.effectCardNodePath.reparentTo(parent) #occluder_nodepath = self.effectCardNodePath.attachNewNode(occluder) #self.effectCardNodePath.setOccluder(occluder_nodepath) emptyNode = NodePath('effect-parent-translator') emptyNode.reparentTo(self.effectCardNodePath) if effectIsCentered == True: emptyNode.setPos(-deltaX/2.0+self.effectAdjustment[0], 0+self.effectAdjustment[1], deltaZ/2.0+self.effectAdjustment[2]) else: emptyNode.setPos(-deltaX/2.0+self.effectAdjustment[0], 0+self.effectAdjustment[1], deltaZ+self.effectAdjustment[2]) #emptyNode.place() emptyNode.setSx(float(deltaX)/self.effectWidth) emptyNode.setSz(float(deltaZ)/self.effectHeight) self.effectCameraNodePath = emptyNode if parent != None: self.effectCardNodePath.reparentTo(parent) else: self.effectCardNodePath.reparentTo(render) #self.effectCardNodePath.place() self.effectCardNodePath.setBin("fixed", 40) self.effectCardNodePath.setDepthTest(False) self.effectCardNodePath.setDepthWrite(False) pass def getSequence(self): sequence = Sequence() for x in range(self.startIndex, self.endIndex, 1): sequence.append(Func(self.pandaRender)) sequence.append(Func(self.advanceFrame)) sequence.append(Wait(self.effectTargetMS * 0.001)) sequence.append(Func(self.clearNodesForDrawing)) sequence.append(Func(self.advanceFrame)) sequence.append(Wait(self.effectTargetMS * 0.001)) return sequence pass def hasEffectFinished(self): if self.internalFrameIndex > self.endIndex and self.loopEffect == False: return True else: return False pass def advanceFrame(self): if self.internalFrameIndex < self.endIndex: self.internalFrameIndex += 1 elif self.internalFrameIndex == self.endIndex and self.loopEffect == True: self.internalFrameIndex = self.startIndex else: self.internalFrameIndex = self.endIndex + 1 self.clearNodesForDrawing() pass def clearNodesForDrawing(self): if False: self.effectCameraNodePath.analyze() if self.consumedNodesList != None and self.consumedNodesList != []: for consumedNode in self.consumedNodesList: consumedNode.removeNode() self.consumedNodesList = [] pass def pandaRender(self): frameList = [] for node in self.compositeFrames.getiterator('composite-frame'): if node.tag == "composite-frame" and node.attrib.get("id") == str(self.internalFrameIndex): for frameCallNode in node: for frameNode in self.frames.getiterator('frame'): if frameNode.tag == "frame" and frameNode.attrib.get("id") == frameCallNode.attrib.get("id"): offsetX = 0 if frameCallNode.attrib.get("offset-x") == None else float(frameCallNode.attrib.get("offset-x")) offsetY = 0 if frameCallNode.attrib.get("offset-y") == None else float(frameCallNode.attrib.get("offset-y")) tweenId = frameCallNode.attrib.get("tween") frameInTween = 0 if frameCallNode.attrib.get("frame-in-tween") == None else int(frameCallNode.attrib.get("frame-in-tween")) addWidth = 0 if frameNode.attrib.get("w") == None else float(frameNode.attrib.get("w")) addHeight = 0 if frameNode.attrib.get("h") == None else float(frameNode.attrib.get("h")) sInPixels = 0 if frameNode.attrib.get("s") == None else float(frameNode.attrib.get("s")) tInPixels = 0 if frameNode.attrib.get("t") == None else float(frameNode.attrib.get("t")) swInPixels = sInPixels + addWidth thInPixels = tInPixels + addHeight s = (sInPixels / self.baseWidth) t = 1 - (tInPixels / self.baseHeight) # Complemented to deal with loading image upside down. S = (swInPixels / self.baseWidth) T = 1 - (thInPixels / self.baseHeight) # Complemented to deal with loading image upside down. blend = "overwrite" if frameCallNode.attrib.get("blend") == None else frameCallNode.attrib.get("blend") scaleX = 1 if frameCallNode.attrib.get("scale-x") == None else float(frameCallNode.attrib.get("scale-x")) scaleY = 1 if frameCallNode.attrib.get("scale-y") == None else float(frameCallNode.attrib.get("scale-y")) color = Color(1,1,1,1) tweenHasColor = False frameCallHasColor = False frameCallColorName = frameCallNode.attrib.get("color-name") if frameCallColorName != None: # Get color at frame call as first resort. frameCallHasColor = True for colorNode in self.colors.getiterator('color'): if colorNode.tag == 'color' and colorNode.attrib.get("name") == frameCallColorName: R = 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r")) G = 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g")) B = 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b")) A = 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a")) color = Color(R, G, B, A) break # leave for loop when we find the correct color pass if tweenId != None and tweenId != "0": # Get color at tween frame as second resort. thisTween = None frameLength = 1 advancementFunction = "linear" foundTween = False pointList = [] colorList = [] for tweenNode in self.tweens.getiterator('motion-tween'): if tweenNode.tag == "motion-tween" and tweenNode.attrib.get("id") == tweenId: foundTween = True frameLength = 1 if tweenNode.attrib.get("length-in-frames") == None else tweenNode.attrib.get("length-in-frames") advancementFunction = "linear" if tweenNode.attrib.get("advancement-function") == None else tweenNode.attrib.get("advancement-function") for pointOrColorNode in tweenNode.getiterator(): if pointOrColorNode.tag == "point": pX = 0 if pointOrColorNode.attrib.get("x") == None else float(pointOrColorNode.attrib.get("x")) pY = 0 if pointOrColorNode.attrib.get("y") == None else float(pointOrColorNode.attrib.get("y")) pointList.append(Point(pX, pY, 0)) elif pointOrColorNode.tag == "color-state": colorName = "white" if pointOrColorNode.attrib.get("name") == None else pointOrColorNode.attrib.get("name") for colorNode in self.colors.getiterator('color'): if colorNode.tag == 'color' and colorNode.attrib.get("name") == colorName: R = 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r")) G = 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g")) B = 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b")) A = 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a")) colorList.append(Color(R, G, B, A)) break # leave for loop when we find the correct color reference pass # Run through all child nodes of selected tween break # Exit after finding correct tween pass if foundTween: thisTween = Tween(frameLength, advancementFunction, pointList, colorList) offset = thisTween.XYFromFrame(frameInTween); offsetFromTweenX = int(offset.X); offsetFromTweenY = int(offset.Y); offsetX += int(offset.X); offsetY += int(offset.Y); if thisTween.hasColorComponent(): tweenHasColor = True; if frameCallHasColor == False: color = thisTween.colorFromFrame(frameInTween); pass if frameNode.attrib.get("color-name") != None and frameCallHasColor == False and tweenHasColor == False: # Get color at frame definition as last resort. for colorNode in colors.getiterator('color'): if colorNode.tag == 'color' and colorNode.attrib.get("name") == frameNode.attrib.get("color-name"): R = 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r")) G = 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g")) B = 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b")) A = 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a")) color = Color(R, G, B, A) break # leave for loop when we find the correct color pass rotationZ = 0 if frameCallNode.attrib.get("rotation-z") == None else float(frameCallNode.attrib.get("rotation-z")) frameList.append(Frame(Bound(offsetX, offsetY, addWidth, addHeight), s, t, S, T, blend, scaleX, scaleY, color, rotationZ)) pass break # Leave once we've found the appropriate frame # Prepare tracking list of consumed nodes. self.clearNodesForDrawing() # Make an identifier to tack onto primitive names in Panda3d's scene graph. frameIndexForName = 1 # Loop through loaded frames that make up composite frame. for loadedFrame in frameList: # For debugging purposes, print the object. if False: loadedFrame.printAsString() # Set up place to store primitive 3d object; note: requires vertex data made by GeomVertexData squareMadeByTriangleStrips = GeomTristrips(Geom.UHDynamic) # Set up place to hold 3d data and for the following coordinates: # square's points (V3: x, y, z), # the colors at each point of the square (c4: r, g, b, a), and # for the UV texture coordinates at each point of the square (t2: S, T). vertexData = GeomVertexData('square-'+str(frameIndexForName), GeomVertexFormat.getV3c4t2(), Geom.UHDynamic) vertex = GeomVertexWriter(vertexData, 'vertex') color = GeomVertexWriter(vertexData, 'color') texcoord = GeomVertexWriter(vertexData, 'texcoord') # Add the square's data # Upper-Left corner of square vertex.addData3f(-loadedFrame.bound.Width / 2.0, 0, -loadedFrame.bound.Height / 2.0) color.addData4f(loadedFrame.color.R,loadedFrame.color.G,loadedFrame.color.B,loadedFrame.color.A) texcoord.addData2f(loadedFrame.s, loadedFrame.T) # Upper-Right corner of square vertex.addData3f(loadedFrame.bound.Width / 2.0, 0, -loadedFrame.bound.Height / 2.0) color.addData4f(loadedFrame.color.R,loadedFrame.color.G,loadedFrame.color.B,loadedFrame.color.A) texcoord.addData2f(loadedFrame.S, loadedFrame.T) # Lower-Left corner of square vertex.addData3f(-loadedFrame.bound.Width / 2.0, 0, loadedFrame.bound.Height / 2.0) color.addData4f(loadedFrame.color.R,loadedFrame.color.G,loadedFrame.color.B,loadedFrame.color.A) texcoord.addData2f(loadedFrame.s, loadedFrame.t) # Lower-Right corner of square vertex.addData3f(loadedFrame.bound.Width / 2.0, 0, loadedFrame.bound.Height / 2.0) color.addData4f(loadedFrame.color.R,loadedFrame.color.G,loadedFrame.color.B,loadedFrame.color.A) texcoord.addData2f(loadedFrame.S, loadedFrame.t) # Pass data to primitive squareMadeByTriangleStrips.addNextVertices(4) squareMadeByTriangleStrips.closePrimitive() square = Geom(vertexData) square.addPrimitive(squareMadeByTriangleStrips) # Pass primtive to drawing node drawPrimitiveNode=GeomNode('square-'+str(frameIndexForName)) drawPrimitiveNode.addGeom(square) # Pass node to scene (effect camera) nodePath = self.effectCameraNodePath.attachNewNode(drawPrimitiveNode) # Linear dodge: if loadedFrame.blendMode == "darken": nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOneMinusFbufferColor, ColorBlendAttrib.OOneMinusIncomingColor)) pass elif loadedFrame.blendMode == "multiply": nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OFbufferColor, ColorBlendAttrib.OZero)) pass elif loadedFrame.blendMode == "color-burn": nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OZero, ColorBlendAttrib.OOneMinusIncomingColor)) pass elif loadedFrame.blendMode == "linear-burn": nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OZero, ColorBlendAttrib.OIncomingColor)) pass elif loadedFrame.blendMode == "lighten": nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MMax, ColorBlendAttrib.OIncomingColor, ColorBlendAttrib.OFbufferColor)) pass elif loadedFrame.blendMode == "color-dodge": nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOne)) pass elif loadedFrame.blendMode == "linear-dodge": nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOneMinusIncomingColor)) pass else: # Overwrite: nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingAlpha, ColorBlendAttrib.OOneMinusIncomingAlpha)) pass nodePath.setDepthTest(False) # Apply texture nodePath.setTexture(self.tex) # Apply translation, then rotation, then scaling to node. nodePath.setPos((loadedFrame.bound.X + loadedFrame.bound.Width / 2.0, 1, -loadedFrame.bound.Y - loadedFrame.bound.Height / 2.0)) nodePath.setR(loadedFrame.rotationZ) nodePath.setScale(loadedFrame.scaleX, 1, loadedFrame.scaleY) nodePath.setTwoSided(True) self.consumedNodesList.append(nodePath) frameIndexForName = frameIndexForName + 1 # Loop continues on through each frame called in the composite frame. pass
def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None): """ Causes the scene to be rendered into the supplied textures instead of into the original window. Puts a fullscreen quad into the original window to show the render-to-texture results. Returns the quad. Normally, the caller would then apply a shader to the quad. To elaborate on how this all works: * An offscreen buffer is created. It is set up to mimic the original display region - it is the same size, uses the same clear colors, and contains a DisplayRegion that uses the original camera. * A fullscreen quad and an orthographic camera to render that quad are both created. The original camera is removed from the original window, and in its place, the orthographic quad-camera is installed. * The fullscreen quad is textured with the data from the offscreen buffer. A shader is applied that tints the results pink. * Automatic shader generation NOT enabled. If you have a filter that depends on a render target from the auto-shader, you either need to set an auto-shader attrib on the main camera or scene, or, you need to provide these outputs in your own shader. * All clears are disabled on the original display region. If the display region fills the whole window, then clears are disabled on the original window as well. It is assumed that rendering the full-screen quad eliminates the need to do clears. Hence, the original window which used to contain the actual scene, now contains a pink-tinted quad with a texture of the scene. It is assumed that the user will replace the shader on the quad with a more interesting filter. """ if (textures): colortex = textures.get("color", None) depthtex = textures.get("depth", None) auxtex = textures.get("aux", None) if (colortex == None): colortex = Texture("filter-base-color") colortex.setWrapU(Texture.WMClamp) colortex.setWrapV(Texture.WMClamp) texgroup = (depthtex, colortex, auxtex, None) # Choose the size of the offscreen buffer. (winx, winy) = self.getScaledSize(1,1,1) buffer = self.createBuffer("filter-base", winx, winy, texgroup) if (buffer == None): return None cm = CardMaker("filter-base-quad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setTexture(colortex) quad.setColor(Vec4(1,0.5,0.5,1)) cs = NodePath("dummy") cs.setState(self.camstate) # Do we really need to turn on the Shader Generator? #cs.setShaderAuto() if (auxbits): cs.setAttrib(AuxBitplaneAttrib.make(auxbits)) self.camera.node().setInitialState(cs.getState()) quadcamnode = Camera("filter-quad-cam") lens = OrthographicLens() lens.setFilmSize(2, 2) lens.setFilmOffset(0, 0) lens.setNearFar(-1000, 1000) quadcamnode.setLens(lens) quadcam = quad.attachNewNode(quadcamnode) self.region.setCamera(quadcam) dr = buffer.getDisplayRegion(0) self.setStackedClears(dr, self.rclears, self.wclears) if (auxtex): dr.setClearActive(GraphicsOutput.RTPAuxRgba0, 1) dr.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5,0.5,1.0,0.0)) self.region.disableClears() if (self.isFullscreen()): self.win.disableClears() dr.setCamera(self.camera) dr.setActive(1) self.buffers.append(buffer) self.sizes.append((1, 1, 1)) return quad
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)
def __init__(self, actor, state, lvl): #Setzte die Parameter self.CActor = actor #Spieler erstellen self.CGame = state #FSM - Gamestate erstellen self.mission = lvl #Aktuelle Mission self.mMission = None #Grundeinstellen fuer die Welt base.disableMouse() #Mouse ausmachen self.slowdown = 1 #Schnelligkeitsfaktor 1=Normal self.hud = False file, filename, description = imp.find_module("mission" + str(self.mission)) self.mMission = imp.load_module("mission" + str(self.mission), file, filename, description) #SPIELER - Variablen self.oldactorlevel = self.CActor.getLevel() self.CActor.CActorShip.setX( -165) #Setze den Spieler links im Bildschirm self.CActor.CActorShip.setY(0) self.CActor.nActorShip.reparentTo(render) self.CActor.CActorShip.getWeapon().setWeapon( "laserGun") #Standardwaffe setzen self.maxshield = self.CActor.CActorShip.getShield( ) #Schild speichern um Prozent berechnen zu koennen self.hitted = False #Variable um abzufragen ob man getroffen wurde self.dead = False #Spieler lebt self.lbullets = [] #Spielerbullets self.lbulletsspeed = [] self.lcanon = [] #Spielercanonbullets self.lcanonspeed = [] self.cameraeffectx = 0 #X-Wert der Camera um eine Sinuskurve zu implementieren self.cameraeffectamplitude = 5 #Die Amplitude der Sinuswelle - Maxima self.exppercent = (self.CActor.getExperience() * 100 ) / self.CActor.getMaxExperience() #EXP in Prozent self.oldcash = self.CActor.getMoney() self.secweapon = 3 #Resultattexte, wenn die Mission zu ende ist self.txtresultmission = addText(-0.15, 0.35, "") self.txtresultkills = addText(-0.15, 0.25, "") self.txtresultleft = addText(-0.15, 0.20, "") self.txtresultcash = addText(-0.15, 0.15, "") self.txtresultlevel = addText(-0.15, 0.10, "") self.txtresultmessage = addText(-0.15, 0.0, "") #ALLES FUER MOTION BLUR *********************************************************************** #Eine Texture erstellen, welches in das Hauptfenster kopiert wird self.CTex = Texture() self.CTex.setMinfilter(Texture.FTLinear) base.win.addRenderTexture(self.CTex, GraphicsOutput.RTMTriggeredCopyTexture) #Eine andere 2D Kamera erstellen, welches vor der Hauptkamera gerendert wird self.backcam = base.makeCamera2d(base.win, sort=-10) self.background = NodePath("background") self.backcam.reparentTo(self.background) self.background.setDepthTest(0) self.background.setDepthWrite(0) self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) #Zwei Texturekarten ersten. Eins bevor, eins danach self.bcard = base.win.getTextureCard() self.bcard.reparentTo(self.background) self.bcard.setTransparency(1) self.fcard = base.win.getTextureCard() self.fcard.reparentTo(render2d) self.fcard.setTransparency(1) #********************************************************************************************** #Drops als Liste self.ldrop = [] #Explosionen - oder besser gesagt Splittereffekt als Liste self.lexplosions = [] #Soundklasse erstellen um Zugriff auf die Sound zu haben self.CSound = SoundMng() self.CSound.sndFlyAmbience.play() #GEGNER - Variablen self.destroyedenemy = 0 self.lostenemy = 0 self.lenemys = [] #Gegnerspeicher self.lbulletsenemy = [] #Gegnerbullets self.newwave = False #Boolean,welches eine neue Gegnerwelle angibt #Effekte self.CEffects = Effects() #Effektklasse erstellen #self.CEffects.createSpaceStars("particle/background.ptf") #Hintergrundeffekt erstellen #Die Game-Loop Voreinstellungen self.gameTask = taskMgr.add(self.gameLoop, "gameLoop") self.gameTask.last = 0 self.gameTask.nextbullet = 0 #Timer wann geschossen werden darf, vom Spieler self.gameTask.gotHit = 0 self.gameTask.lnextenemybullet = [ ] #Timer wann geschossen werden darf, unabhaengig von welche Gegner self.gameTask.resultkills = 0 #Timer fuer die Kills, im Resultat self.gameTask.resultleft = 0 #Timer fuer die geflohenen Gegner, im Resultat self.gameTask.introduction = 0 self.gameTask.introdelete = 0 self.gameTask.won = 0 self.resultcounter = 0 #Zeahler der die Nummern der Kills im Result aktualisiert self.resultcounterleft = 0 #Zeahler der die Nummern der geflohenen Gegner im Result aktualisiert self.introcounter = 0 self.ldata = [] self.readytospawn = False self.musicplayed = False self.musicplayed2 = False self.resultplayed = False #2D Kamera erstellen lens = OrthographicLens() lens.setFilmSize(350, 250) base.cam.node().setLens(lens)
def loadFlatQuad(self, fullFilename): """Load the flat jpg into a quad.""" assert self.notify.debugStateCall(self) #Texture.setTexturesPower2(AutoTextureScale.ATSUp) #Texture.setTexturesPower2(2) 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) # 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() quad = NodePath(card) #quad.reparentTo(self.parent) 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.setKeepRamImage(True) #guiTex.makeRamImage() guiTex.setWrapU(Texture.WMClamp) guiTex.setWrapV(Texture.WMClamp) ts = TextureStage('webTS') quad.setTexture(ts, guiTex) #quad.setTexScale(ts, 1.0, -1.0) quad.setTransparency(0) quad.setTwoSided(True) quad.setColor(1.0, 1.0, 1.0, 1.0) result= quad else: # if we have an error loading the file, return None to signify an error result = None #Texture.setTexturesPower2(AutoTextureScale.ATSDown) Texture.setTexturesPower2(1) return result
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)
def __init__(self): self.myTexture = Texture() self.imageObject = OnscreenImage(image = self.myTexture, pos = (0, 0, 0)) self.run() self.accept("arrow_up", self.run)
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)
def __init__(self, effectFileName, parent=None, loop=False, effectIsCentered=True, effectAdjustment=[0, 0, 0]): self.effectAdjustment = effectAdjustment self.loopEffect = loop self.effectIsCentered = effectIsCentered self.loadedFormat = None if effectFileName != None: effectFileNameSplit = effectFileName.split('.') self.loadedFormat = effectFileNameSplit[len(effectFileNameSplit)-2] # Get value at penultimate index if self.loadedFormat == effectFileNameSplit[0]: self.loadedFormat = None # Get rid of bad format name. pass # Load texture; supply alpha channel if it doesn't exist. p = transparencyKey(effectFileName) self.tex = Texture() self.tex.setup2dTexture(p.getXSize(), p.getYSize(), Texture.TUnsignedByte, Texture.FRgba) self.tex.load(p) if self.loadedFormat != None: try: self.tree = etree.parse("./"+GAME+"/effects/"+self.loadedFormat+"/sprite.xml") except IOError: self.loadedFormat = None pass if self.loadedFormat != None: root = self.tree.getroot() self.frames = root.find('.//frames') self.colors = root.find('.//colors') self.tweens = root.find('.//motion-tweens') self.compositeFrames = root.find('.//composite-frames') self.baseWidth = 0 if root.attrib.get("base-width") == None else float(root.attrib.get("base-width")) self.baseHeight = 0 if root.attrib.get("base-height") == None else float(root.attrib.get("base-height")) self.effectWidth = 1 if root.attrib.get("frame-width") == None else float(root.attrib.get("frame-width")) self.effectHeight = 1 if root.attrib.get("frame-height") == None else float(root.attrib.get("frame-height")) self.effectTargetMS = 143 if root.attrib.get("target-ms") == None else float(root.attrib.get("target-ms")) self.startIndex = 1 if root.attrib.get("target-start") == None else int(root.attrib.get("target-start")) self.endIndex = 1 if root.attrib.get("target-end") == None else int(root.attrib.get("target-end")) self.noSampling = False if root.attrib.get("no-sampling") == None else bool(root.attrib.get("no-sampling")) if self.noSampling==True: self.tex.setMagfilter(Texture.FTNearest) self.tex.setMinfilter(Texture.FTNearest) cm = CardMaker('card-'+effectFileName) cardDeltaX = self.effectWidth / self.pixelScaleX cardDeltaZ = self.effectHeight / self.pixelScaleZ if self.effectIsCentered == True: cm.setFrame(0, 0, 0, 0) deltaX = (cardDeltaX/2.0) - (-cardDeltaX/2.0) deltaY = 0 deltaZ = (cardDeltaZ/2.0) - (-cardDeltaZ/2.0) #occluder = OccluderNode('effect-parent-occluder', Point3((-cardDeltaX/2.0), 0, (-cardDeltaZ/2.0)), Point3((-cardDeltaX/2.0), 0, (cardDeltaZ/2.0)), Point3((cardDeltaX/2.0), 0, (cardDeltaZ/2.0)), Point3((cardDeltaX/2.0), 0, (-cardDeltaZ/2.0))) else: cm.setFrame(0, 0, 0, 0) deltaX = (cardDeltaX/2.0) - (-cardDeltaX/2.0) deltaY = 0 deltaZ = cardDeltaZ - 0 #occluder = OccluderNode('effect-parent-occluder', Point3((-cardDeltaX/2.0), 0, 0), Point3((-cardDeltaX/2.0), 0, cardDeltaZ), Point3((cardDeltaX/2.0), 0, cardDeltaZ), Point3((cardDeltaX/2.0), 0, 0)) self.effectCardNodePath = render.attachNewNode(cm.generate()) self.effectCardNodePath.setBillboardPointEye() self.effectCardNodePath.reparentTo(parent) #occluder_nodepath = self.effectCardNodePath.attachNewNode(occluder) #self.effectCardNodePath.setOccluder(occluder_nodepath) emptyNode = NodePath('effect-parent-translator') emptyNode.reparentTo(self.effectCardNodePath) if effectIsCentered == True: emptyNode.setPos(-deltaX/2.0+self.effectAdjustment[0], 0+self.effectAdjustment[1], deltaZ/2.0+self.effectAdjustment[2]) else: emptyNode.setPos(-deltaX/2.0+self.effectAdjustment[0], 0+self.effectAdjustment[1], deltaZ+self.effectAdjustment[2]) #emptyNode.place() emptyNode.setSx(float(deltaX)/self.effectWidth) emptyNode.setSz(float(deltaZ)/self.effectHeight) self.effectCameraNodePath = emptyNode if parent != None: self.effectCardNodePath.reparentTo(parent) else: self.effectCardNodePath.reparentTo(render) #self.effectCardNodePath.place() self.effectCardNodePath.setBin("fixed", 40) self.effectCardNodePath.setDepthTest(False) self.effectCardNodePath.setDepthWrite(False) pass
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
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
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
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')
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
class Effect: baseWidth = 0 baseHeight = 0 effectWidth = 1 effectHeight = 1 effectTargetMS = 143 noSampling = False tex = None loadedFormat = None # Animation variables internalFrameIndex = 1 startIndex = 1 endIndex = 1 loopEffect = False # XML variables tree = None frames = None colors = None tweens = None compositeFrames = None # Nodes consumedNodesList = None # Accessible object (nodePath) effectCameraNodePath = None effectCardNodePath = None # Constant value; Unit comparison for card size; basis is from cure, which is [140x110] cardDimensionBasis = [-5.0, 5.0, 0.0, 10.0, 140.0, 110.0] pixelScaleX = cardDimensionBasis[4] / (cardDimensionBasis[1] - cardDimensionBasis[0]) pixelScaleZ = cardDimensionBasis[5] / (cardDimensionBasis[3] - cardDimensionBasis[2]) effectIsCentered = True effectAdjustment = [0, 0, 0] def __init__(self, effectFileName, parent=None, loop=False, effectIsCentered=True, effectAdjustment=[0, 0, 0]): self.effectAdjustment = effectAdjustment self.loopEffect = loop self.effectIsCentered = effectIsCentered self.loadedFormat = None if effectFileName != None: effectFileNameSplit = effectFileName.split(".") self.loadedFormat = effectFileNameSplit[len(effectFileNameSplit) - 2] # Get value at penultimate index if self.loadedFormat == effectFileNameSplit[0]: self.loadedFormat = None # Get rid of bad format name. pass # Load texture; supply alpha channel if it doesn't exist. p = transparencyKey(effectFileName) self.tex = Texture() self.tex.setup2dTexture(p.getXSize(), p.getYSize(), Texture.TUnsignedByte, Texture.FRgba) self.tex.load(p) if self.loadedFormat != None: try: self.tree = etree.parse("./" + GAME + "/effects/" + self.loadedFormat + "/sprite.xml") except IOError: self.loadedFormat = None pass if self.loadedFormat != None: root = self.tree.getroot() self.frames = root.find(".//frames") self.colors = root.find(".//colors") self.tweens = root.find(".//motion-tweens") self.compositeFrames = root.find(".//composite-frames") self.baseWidth = 0 if root.attrib.get("base-width") == None else float(root.attrib.get("base-width")) self.baseHeight = 0 if root.attrib.get("base-height") == None else float(root.attrib.get("base-height")) self.effectWidth = 1 if root.attrib.get("frame-width") == None else float(root.attrib.get("frame-width")) self.effectHeight = 1 if root.attrib.get("frame-height") == None else float(root.attrib.get("frame-height")) self.effectTargetMS = 143 if root.attrib.get("target-ms") == None else float(root.attrib.get("target-ms")) self.startIndex = 1 if root.attrib.get("target-start") == None else int(root.attrib.get("target-start")) self.endIndex = 1 if root.attrib.get("target-end") == None else int(root.attrib.get("target-end")) self.noSampling = False if root.attrib.get("no-sampling") == None else bool(root.attrib.get("no-sampling")) if self.noSampling == True: self.tex.setMagfilter(Texture.FTNearest) self.tex.setMinfilter(Texture.FTNearest) cm = CardMaker("card-" + effectFileName) cardDeltaX = self.effectWidth / self.pixelScaleX cardDeltaZ = self.effectHeight / self.pixelScaleZ if self.effectIsCentered == True: cm.setFrame(0, 0, 0, 0) deltaX = (cardDeltaX / 2.0) - (-cardDeltaX / 2.0) deltaY = 0 deltaZ = (cardDeltaZ / 2.0) - (-cardDeltaZ / 2.0) # occluder = OccluderNode('effect-parent-occluder', Point3((-cardDeltaX/2.0), 0, (-cardDeltaZ/2.0)), Point3((-cardDeltaX/2.0), 0, (cardDeltaZ/2.0)), Point3((cardDeltaX/2.0), 0, (cardDeltaZ/2.0)), Point3((cardDeltaX/2.0), 0, (-cardDeltaZ/2.0))) else: cm.setFrame(0, 0, 0, 0) deltaX = (cardDeltaX / 2.0) - (-cardDeltaX / 2.0) deltaY = 0 deltaZ = cardDeltaZ - 0 # occluder = OccluderNode('effect-parent-occluder', Point3((-cardDeltaX/2.0), 0, 0), Point3((-cardDeltaX/2.0), 0, cardDeltaZ), Point3((cardDeltaX/2.0), 0, cardDeltaZ), Point3((cardDeltaX/2.0), 0, 0)) self.effectCardNodePath = render.attachNewNode(cm.generate()) self.effectCardNodePath.setBillboardPointEye() self.effectCardNodePath.reparentTo(parent) # occluder_nodepath = self.effectCardNodePath.attachNewNode(occluder) # self.effectCardNodePath.setOccluder(occluder_nodepath) emptyNode = NodePath("effect-parent-translator") emptyNode.reparentTo(self.effectCardNodePath) if effectIsCentered == True: emptyNode.setPos( -deltaX / 2.0 + self.effectAdjustment[0], 0 + self.effectAdjustment[1], deltaZ / 2.0 + self.effectAdjustment[2], ) else: emptyNode.setPos( -deltaX / 2.0 + self.effectAdjustment[0], 0 + self.effectAdjustment[1], deltaZ + self.effectAdjustment[2], ) # emptyNode.place() emptyNode.setSx(float(deltaX) / self.effectWidth) emptyNode.setSz(float(deltaZ) / self.effectHeight) self.effectCameraNodePath = emptyNode if parent != None: self.effectCardNodePath.reparentTo(parent) else: self.effectCardNodePath.reparentTo(render) # self.effectCardNodePath.place() self.effectCardNodePath.setBin("fixed", 40) self.effectCardNodePath.setDepthTest(False) self.effectCardNodePath.setDepthWrite(False) pass def getSequence(self): sequence = Sequence() for x in range(self.startIndex, self.endIndex, 1): sequence.append(Func(self.pandaRender)) sequence.append(Func(self.advanceFrame)) sequence.append(Wait(self.effectTargetMS * 0.001)) sequence.append(Func(self.clearNodesForDrawing)) sequence.append(Func(self.advanceFrame)) sequence.append(Wait(self.effectTargetMS * 0.001)) return sequence pass def hasEffectFinished(self): if self.internalFrameIndex > self.endIndex and self.loopEffect == False: return True else: return False pass def advanceFrame(self): if self.internalFrameIndex < self.endIndex: self.internalFrameIndex += 1 elif self.internalFrameIndex == self.endIndex and self.loopEffect == True: self.internalFrameIndex = self.startIndex else: self.internalFrameIndex = self.endIndex + 1 self.clearNodesForDrawing() pass def clearNodesForDrawing(self): if False: self.effectCameraNodePath.analyze() if self.consumedNodesList != None and self.consumedNodesList != []: for consumedNode in self.consumedNodesList: consumedNode.removeNode() self.consumedNodesList = [] pass def pandaRender(self): frameList = [] for node in self.compositeFrames.getiterator("composite-frame"): if node.tag == "composite-frame" and node.attrib.get("id") == str(self.internalFrameIndex): for frameCallNode in node: for frameNode in self.frames.getiterator("frame"): if frameNode.tag == "frame" and frameNode.attrib.get("id") == frameCallNode.attrib.get("id"): offsetX = ( 0 if frameCallNode.attrib.get("offset-x") == None else float(frameCallNode.attrib.get("offset-x")) ) offsetY = ( 0 if frameCallNode.attrib.get("offset-y") == None else float(frameCallNode.attrib.get("offset-y")) ) tweenId = frameCallNode.attrib.get("tween") frameInTween = ( 0 if frameCallNode.attrib.get("frame-in-tween") == None else int(frameCallNode.attrib.get("frame-in-tween")) ) addWidth = 0 if frameNode.attrib.get("w") == None else float(frameNode.attrib.get("w")) addHeight = 0 if frameNode.attrib.get("h") == None else float(frameNode.attrib.get("h")) sInPixels = 0 if frameNode.attrib.get("s") == None else float(frameNode.attrib.get("s")) tInPixels = 0 if frameNode.attrib.get("t") == None else float(frameNode.attrib.get("t")) swInPixels = sInPixels + addWidth thInPixels = tInPixels + addHeight s = sInPixels / self.baseWidth t = 1 - ( tInPixels / self.baseHeight ) # Complemented to deal with loading image upside down. S = swInPixels / self.baseWidth T = 1 - ( thInPixels / self.baseHeight ) # Complemented to deal with loading image upside down. blend = ( "overwrite" if frameCallNode.attrib.get("blend") == None else frameCallNode.attrib.get("blend") ) scaleX = ( 1 if frameCallNode.attrib.get("scale-x") == None else float(frameCallNode.attrib.get("scale-x")) ) scaleY = ( 1 if frameCallNode.attrib.get("scale-y") == None else float(frameCallNode.attrib.get("scale-y")) ) color = Color(1, 1, 1, 1) tweenHasColor = False frameCallHasColor = False frameCallColorName = frameCallNode.attrib.get("color-name") if frameCallColorName != None: # Get color at frame call as first resort. frameCallHasColor = True for colorNode in self.colors.getiterator("color"): if colorNode.tag == "color" and colorNode.attrib.get("name") == frameCallColorName: R = 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r")) G = 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g")) B = 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b")) A = 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a")) color = Color(R, G, B, A) break # leave for loop when we find the correct color pass if tweenId != None and tweenId != "0": # Get color at tween frame as second resort. thisTween = None frameLength = 1 advancementFunction = "linear" foundTween = False pointList = [] colorList = [] for tweenNode in self.tweens.getiterator("motion-tween"): if tweenNode.tag == "motion-tween" and tweenNode.attrib.get("id") == tweenId: foundTween = True frameLength = ( 1 if tweenNode.attrib.get("length-in-frames") == None else tweenNode.attrib.get("length-in-frames") ) advancementFunction = ( "linear" if tweenNode.attrib.get("advancement-function") == None else tweenNode.attrib.get("advancement-function") ) for pointOrColorNode in tweenNode.getiterator(): if pointOrColorNode.tag == "point": pX = ( 0 if pointOrColorNode.attrib.get("x") == None else float(pointOrColorNode.attrib.get("x")) ) pY = ( 0 if pointOrColorNode.attrib.get("y") == None else float(pointOrColorNode.attrib.get("y")) ) pointList.append(Point(pX, pY, 0)) elif pointOrColorNode.tag == "color-state": colorName = ( "white" if pointOrColorNode.attrib.get("name") == None else pointOrColorNode.attrib.get("name") ) for colorNode in self.colors.getiterator("color"): if ( colorNode.tag == "color" and colorNode.attrib.get("name") == colorName ): R = ( 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r")) ) G = ( 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g")) ) B = ( 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b")) ) A = ( 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a")) ) colorList.append(Color(R, G, B, A)) break # leave for loop when we find the correct color reference pass # Run through all child nodes of selected tween break # Exit after finding correct tween pass if foundTween: thisTween = Tween(frameLength, advancementFunction, pointList, colorList) offset = thisTween.XYFromFrame(frameInTween) offsetFromTweenX = int(offset.X) offsetFromTweenY = int(offset.Y) offsetX += int(offset.X) offsetY += int(offset.Y) if thisTween.hasColorComponent(): tweenHasColor = True if frameCallHasColor == False: color = thisTween.colorFromFrame(frameInTween) pass if ( frameNode.attrib.get("color-name") != None and frameCallHasColor == False and tweenHasColor == False ): # Get color at frame definition as last resort. for colorNode in colors.getiterator("color"): if colorNode.tag == "color" and colorNode.attrib.get( "name" ) == frameNode.attrib.get("color-name"): R = 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r")) G = 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g")) B = 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b")) A = 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a")) color = Color(R, G, B, A) break # leave for loop when we find the correct color pass rotationZ = ( 0 if frameCallNode.attrib.get("rotation-z") == None else float(frameCallNode.attrib.get("rotation-z")) ) frameList.append( Frame( Bound(offsetX, offsetY, addWidth, addHeight), s, t, S, T, blend, scaleX, scaleY, color, rotationZ, ) ) pass break # Leave once we've found the appropriate frame # Prepare tracking list of consumed nodes. self.clearNodesForDrawing() # Make an identifier to tack onto primitive names in Panda3d's scene graph. frameIndexForName = 1 # Loop through loaded frames that make up composite frame. for loadedFrame in frameList: # For debugging purposes, print the object. if False: loadedFrame.printAsString() # Set up place to store primitive 3d object; note: requires vertex data made by GeomVertexData squareMadeByTriangleStrips = GeomTristrips(Geom.UHDynamic) # Set up place to hold 3d data and for the following coordinates: # square's points (V3: x, y, z), # the colors at each point of the square (c4: r, g, b, a), and # for the UV texture coordinates at each point of the square (t2: S, T). vertexData = GeomVertexData( "square-" + str(frameIndexForName), GeomVertexFormat.getV3c4t2(), Geom.UHDynamic ) vertex = GeomVertexWriter(vertexData, "vertex") color = GeomVertexWriter(vertexData, "color") texcoord = GeomVertexWriter(vertexData, "texcoord") # Add the square's data # Upper-Left corner of square vertex.addData3f(-loadedFrame.bound.Width / 2.0, 0, -loadedFrame.bound.Height / 2.0) color.addData4f(loadedFrame.color.R, loadedFrame.color.G, loadedFrame.color.B, loadedFrame.color.A) texcoord.addData2f(loadedFrame.s, loadedFrame.T) # Upper-Right corner of square vertex.addData3f(loadedFrame.bound.Width / 2.0, 0, -loadedFrame.bound.Height / 2.0) color.addData4f(loadedFrame.color.R, loadedFrame.color.G, loadedFrame.color.B, loadedFrame.color.A) texcoord.addData2f(loadedFrame.S, loadedFrame.T) # Lower-Left corner of square vertex.addData3f(-loadedFrame.bound.Width / 2.0, 0, loadedFrame.bound.Height / 2.0) color.addData4f(loadedFrame.color.R, loadedFrame.color.G, loadedFrame.color.B, loadedFrame.color.A) texcoord.addData2f(loadedFrame.s, loadedFrame.t) # Lower-Right corner of square vertex.addData3f(loadedFrame.bound.Width / 2.0, 0, loadedFrame.bound.Height / 2.0) color.addData4f(loadedFrame.color.R, loadedFrame.color.G, loadedFrame.color.B, loadedFrame.color.A) texcoord.addData2f(loadedFrame.S, loadedFrame.t) # Pass data to primitive squareMadeByTriangleStrips.addNextVertices(4) squareMadeByTriangleStrips.closePrimitive() square = Geom(vertexData) square.addPrimitive(squareMadeByTriangleStrips) # Pass primtive to drawing node drawPrimitiveNode = GeomNode("square-" + str(frameIndexForName)) drawPrimitiveNode.addGeom(square) # Pass node to scene (effect camera) nodePath = self.effectCameraNodePath.attachNewNode(drawPrimitiveNode) # Linear dodge: if loadedFrame.blendMode == "darken": nodePath.setAttrib( ColorBlendAttrib.make( ColorBlendAttrib.MAdd, ColorBlendAttrib.OOneMinusFbufferColor, ColorBlendAttrib.OOneMinusIncomingColor, ) ) pass elif loadedFrame.blendMode == "multiply": nodePath.setAttrib( ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OFbufferColor, ColorBlendAttrib.OZero) ) pass elif loadedFrame.blendMode == "color-burn": nodePath.setAttrib( ColorBlendAttrib.make( ColorBlendAttrib.MAdd, ColorBlendAttrib.OZero, ColorBlendAttrib.OOneMinusIncomingColor ) ) pass elif loadedFrame.blendMode == "linear-burn": nodePath.setAttrib( ColorBlendAttrib.make( ColorBlendAttrib.MAdd, ColorBlendAttrib.OZero, ColorBlendAttrib.OIncomingColor ) ) pass elif loadedFrame.blendMode == "lighten": nodePath.setAttrib( ColorBlendAttrib.make( ColorBlendAttrib.MMax, ColorBlendAttrib.OIncomingColor, ColorBlendAttrib.OFbufferColor ) ) pass elif loadedFrame.blendMode == "color-dodge": nodePath.setAttrib( ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOne) ) pass elif loadedFrame.blendMode == "linear-dodge": nodePath.setAttrib( ColorBlendAttrib.make( ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOneMinusIncomingColor ) ) pass else: # Overwrite: nodePath.setAttrib( ColorBlendAttrib.make( ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingAlpha, ColorBlendAttrib.OOneMinusIncomingAlpha ) ) pass nodePath.setDepthTest(False) # Apply texture nodePath.setTexture(self.tex) # Apply translation, then rotation, then scaling to node. nodePath.setPos( ( loadedFrame.bound.X + loadedFrame.bound.Width / 2.0, 1, -loadedFrame.bound.Y - loadedFrame.bound.Height / 2.0, ) ) nodePath.setR(loadedFrame.rotationZ) nodePath.setScale(loadedFrame.scaleX, 1, loadedFrame.scaleY) nodePath.setTwoSided(True) self.consumedNodesList.append(nodePath) frameIndexForName = frameIndexForName + 1 # Loop continues on through each frame called in the composite frame. pass
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 __init__(self, effectFileName, parent=None, loop=False, effectIsCentered=True, effectAdjustment=[0, 0, 0]): self.effectAdjustment = effectAdjustment self.loopEffect = loop self.effectIsCentered = effectIsCentered self.loadedFormat = None if effectFileName != None: effectFileNameSplit = effectFileName.split(".") self.loadedFormat = effectFileNameSplit[len(effectFileNameSplit) - 2] # Get value at penultimate index if self.loadedFormat == effectFileNameSplit[0]: self.loadedFormat = None # Get rid of bad format name. pass # Load texture; supply alpha channel if it doesn't exist. p = transparencyKey(effectFileName) self.tex = Texture() self.tex.setup2dTexture(p.getXSize(), p.getYSize(), Texture.TUnsignedByte, Texture.FRgba) self.tex.load(p) if self.loadedFormat != None: try: self.tree = etree.parse("./" + GAME + "/effects/" + self.loadedFormat + "/sprite.xml") except IOError: self.loadedFormat = None pass if self.loadedFormat != None: root = self.tree.getroot() self.frames = root.find(".//frames") self.colors = root.find(".//colors") self.tweens = root.find(".//motion-tweens") self.compositeFrames = root.find(".//composite-frames") self.baseWidth = 0 if root.attrib.get("base-width") == None else float(root.attrib.get("base-width")) self.baseHeight = 0 if root.attrib.get("base-height") == None else float(root.attrib.get("base-height")) self.effectWidth = 1 if root.attrib.get("frame-width") == None else float(root.attrib.get("frame-width")) self.effectHeight = 1 if root.attrib.get("frame-height") == None else float(root.attrib.get("frame-height")) self.effectTargetMS = 143 if root.attrib.get("target-ms") == None else float(root.attrib.get("target-ms")) self.startIndex = 1 if root.attrib.get("target-start") == None else int(root.attrib.get("target-start")) self.endIndex = 1 if root.attrib.get("target-end") == None else int(root.attrib.get("target-end")) self.noSampling = False if root.attrib.get("no-sampling") == None else bool(root.attrib.get("no-sampling")) if self.noSampling == True: self.tex.setMagfilter(Texture.FTNearest) self.tex.setMinfilter(Texture.FTNearest) cm = CardMaker("card-" + effectFileName) cardDeltaX = self.effectWidth / self.pixelScaleX cardDeltaZ = self.effectHeight / self.pixelScaleZ if self.effectIsCentered == True: cm.setFrame(0, 0, 0, 0) deltaX = (cardDeltaX / 2.0) - (-cardDeltaX / 2.0) deltaY = 0 deltaZ = (cardDeltaZ / 2.0) - (-cardDeltaZ / 2.0) # occluder = OccluderNode('effect-parent-occluder', Point3((-cardDeltaX/2.0), 0, (-cardDeltaZ/2.0)), Point3((-cardDeltaX/2.0), 0, (cardDeltaZ/2.0)), Point3((cardDeltaX/2.0), 0, (cardDeltaZ/2.0)), Point3((cardDeltaX/2.0), 0, (-cardDeltaZ/2.0))) else: cm.setFrame(0, 0, 0, 0) deltaX = (cardDeltaX / 2.0) - (-cardDeltaX / 2.0) deltaY = 0 deltaZ = cardDeltaZ - 0 # occluder = OccluderNode('effect-parent-occluder', Point3((-cardDeltaX/2.0), 0, 0), Point3((-cardDeltaX/2.0), 0, cardDeltaZ), Point3((cardDeltaX/2.0), 0, cardDeltaZ), Point3((cardDeltaX/2.0), 0, 0)) self.effectCardNodePath = render.attachNewNode(cm.generate()) self.effectCardNodePath.setBillboardPointEye() self.effectCardNodePath.reparentTo(parent) # occluder_nodepath = self.effectCardNodePath.attachNewNode(occluder) # self.effectCardNodePath.setOccluder(occluder_nodepath) emptyNode = NodePath("effect-parent-translator") emptyNode.reparentTo(self.effectCardNodePath) if effectIsCentered == True: emptyNode.setPos( -deltaX / 2.0 + self.effectAdjustment[0], 0 + self.effectAdjustment[1], deltaZ / 2.0 + self.effectAdjustment[2], ) else: emptyNode.setPos( -deltaX / 2.0 + self.effectAdjustment[0], 0 + self.effectAdjustment[1], deltaZ + self.effectAdjustment[2], ) # emptyNode.place() emptyNode.setSx(float(deltaX) / self.effectWidth) emptyNode.setSz(float(deltaZ) / self.effectHeight) self.effectCameraNodePath = emptyNode if parent != None: self.effectCardNodePath.reparentTo(parent) else: self.effectCardNodePath.reparentTo(render) # self.effectCardNodePath.place() self.effectCardNodePath.setBin("fixed", 40) self.effectCardNodePath.setDepthTest(False) self.effectCardNodePath.setDepthWrite(False) pass
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
def reconfigure(self, fullrebuild, changed): """ Reconfigure is called whenever any configuration change is made. """ configuration = self.configuration if (fullrebuild): self.cleanup() if (len(configuration) == 0): return auxbits = 0 needtex = set(["color"]) needtexcoord = set(["color"]) if ("CartoonInk" in configuration): needtex.add("aux") auxbits |= AuxBitplaneAttrib.ABOAuxNormal needtexcoord.add("aux") if ("AmbientOcclusion" in configuration): needtex.add("depth") needtex.add("ssao0") needtex.add("ssao1") needtex.add("ssao2") needtex.add("aux") auxbits |= AuxBitplaneAttrib.ABOAuxNormal needtexcoord.add("ssao2") if ("BlurSharpen" in configuration): needtex.add("blur0") needtex.add("blur1") needtexcoord.add("blur1") if ("Bloom" in configuration): needtex.add("bloom0") needtex.add("bloom1") needtex.add("bloom2") needtex.add("bloom3") auxbits |= AuxBitplaneAttrib.ABOGlow needtexcoord.add("bloom3") if ("ViewGlow" in configuration): auxbits |= AuxBitplaneAttrib.ABOGlow if ("VolumetricLighting" in configuration): needtex[configuration["VolumetricLighting"].source] = True for tex in needtex: self.textures[tex] = Texture("scene-" + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) self.finalQuad = self.manager.renderSceneInto( textures=self.textures, auxbits=auxbits) if (self.finalQuad == None): self.cleanup() return False if ("BlurSharpen" in configuration): blur0 = self.textures["blur0"] blur1 = self.textures["blur1"] self.blur.append( self.manager.renderQuadInto(colortex=blur0, div=2)) self.blur.append(self.manager.renderQuadInto(colortex=blur1)) self.blur[0].setShaderInput("src", self.textures["color"]) self.blur[0].setShader(self.loadShader("filter-blurx.sha")) self.blur[1].setShaderInput("src", blur0) self.blur[1].setShader(self.loadShader("filter-blury.sha")) if ("AmbientOcclusion" in configuration): ssao0 = self.textures["ssao0"] ssao1 = self.textures["ssao1"] ssao2 = self.textures["ssao2"] self.ssao.append(self.manager.renderQuadInto(colortex=ssao0)) self.ssao.append( self.manager.renderQuadInto(colortex=ssao1, div=2)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao2)) self.ssao[0].setShaderInput("depth", self.textures["depth"]) self.ssao[0].setShaderInput("normal", self.textures["aux"]) self.ssao[0].setShaderInput( "random", loader.loadTexture("maps/random.rgb")) self.ssao[0].setShader( Shader.make(SSAO_BODY % configuration["AmbientOcclusion"].numsamples)) self.ssao[1].setShaderInput("src", ssao0) self.ssao[1].setShader(self.loadShader("filter-blurx.sha")) self.ssao[2].setShaderInput("src", ssao1) self.ssao[2].setShader(self.loadShader("filter-blury.sha")) if ("Bloom" in configuration): bloomconf = configuration["Bloom"] bloom0 = self.textures["bloom0"] bloom1 = self.textures["bloom1"] bloom2 = self.textures["bloom2"] bloom3 = self.textures["bloom3"] if (bloomconf.size == "large"): scale = 8 downsampler = "filter-down4.sha" elif (bloomconf.size == "medium"): scale = 4 downsampler = "filter-copy.sha" else: scale = 2 downsampler = "filter-copy.sha" self.bloom.append( self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput("src", self.textures["color"]) self.bloom[0].setShader(self.loadShader("filter-bloomi.sha")) self.bloom[1].setShaderInput("src", bloom0) self.bloom[1].setShader(self.loadShader(downsampler)) self.bloom[2].setShaderInput("src", bloom1) self.bloom[2].setShader(self.loadShader("filter-bloomx.sha")) self.bloom[3].setShaderInput("src", bloom2) self.bloom[3].setShader(self.loadShader("filter-bloomy.sha")) texcoords = {} texcoordPadding = {} for tex in needtexcoord: if self.textures[tex].getAutoTextureScale() != ATSNone or \ "HalfPixelShift" in configuration: texcoords[tex] = "l_texcoord_" + tex texcoordPadding["l_texcoord_" + tex] = tex else: # Share unpadded texture coordinates. texcoords[tex] = "l_texcoord" texcoordPadding["l_texcoord"] = None texcoordSets = list(enumerate(texcoordPadding.keys())) text = "//Cg\n" text += "void vshader(float4 vtx_position : POSITION,\n" text += " out float4 l_position : POSITION,\n" for texcoord, padTex in texcoordPadding.items(): if padTex is not None: text += " uniform float4 texpad_tx%s,\n" % (padTex) if ("HalfPixelShift" in configuration): text += " uniform float4 texpix_tx%s,\n" % (padTex) for i, name in texcoordSets: text += " out float2 %s : TEXCOORD%d,\n" % (name, i) text += " uniform float4x4 mat_modelproj)\n" text += "{\n" text += " l_position = mul(mat_modelproj, vtx_position);\n" for texcoord, padTex in texcoordPadding.items(): if padTex is None: text += " %s = vtx_position.xz * float2(0.5, 0.5) + float2(0.5, 0.5);\n" % ( texcoord) else: text += " %s = (vtx_position.xz * texpad_tx%s.xy) + texpad_tx%s.xy;\n" % ( texcoord, padTex, padTex) if ("HalfPixelShift" in configuration): text += " %s += texpix_tx%s.xy * 0.5;\n" % (texcoord, padTex) text += "}\n" text += "void fshader(\n" for i, name in texcoordSets: text += " float2 %s : TEXCOORD%d,\n" % (name, i) for key in self.textures: text += " uniform sampler2D k_tx" + key + ",\n" if ("CartoonInk" in configuration): text += " uniform float4 k_cartoonseparation,\n" text += " uniform float4 k_cartooncolor,\n" text += " uniform float4 texpix_txaux,\n" if ("BlurSharpen" in configuration): text += " uniform float4 k_blurval,\n" if ("VolumetricLighting" in configuration): text += " uniform float4 k_casterpos,\n" text += " uniform float4 k_vlparams,\n" text += " out float4 o_color : COLOR)\n" text += "{\n" text += " o_color = tex2D(k_txcolor, %s);\n" % ( texcoords["color"]) if ("CartoonInk" in configuration): text += CARTOON_BODY % {"texcoord": texcoords["aux"]} if ("AmbientOcclusion" in configuration): text += " o_color *= tex2D(k_txssao2, %s).r;\n" % ( texcoords["ssao2"]) if ("BlurSharpen" in configuration): text += " o_color = lerp(tex2D(k_txblur1, %s), o_color, k_blurval.x);\n" % ( texcoords["blur1"]) if ("Bloom" in configuration): text += " o_color = saturate(o_color);\n" text += " float4 bloom = 0.5 * tex2D(k_txbloom3, %s);\n" % ( texcoords["bloom3"]) text += " o_color = 1-((1-bloom)*(1-o_color));\n" if ("ViewGlow" in configuration): text += " o_color.r = o_color.a;\n" if ("VolumetricLighting" in configuration): text += " float decay = 1.0f;\n" text += " float2 curcoord = %s;\n" % (texcoords["color"]) text += " float2 lightdir = curcoord - k_casterpos.xy;\n" text += " lightdir *= k_vlparams.x;\n" text += " half4 sample = tex2D(k_txcolor, curcoord);\n" text += " float3 vlcolor = sample.rgb * sample.a;\n" text += " for (int i = 0; i < %s; i++) {\n" % (int( configuration["VolumetricLighting"].numsamples)) text += " curcoord -= lightdir;\n" text += " sample = tex2D(k_tx%s, curcoord);\n" % ( configuration["VolumetricLighting"].source) text += " sample *= sample.a * decay;//*weight\n" text += " vlcolor += sample.rgb;\n" text += " decay *= k_vlparams.y;\n" text += " }\n" text += " o_color += float4(vlcolor * k_vlparams.z, 1);\n" if ("GammaAdjust" in configuration): gamma = configuration["GammaAdjust"] if gamma == 0.5: text += " o_color.rgb = sqrt(o_color.rgb);\n" elif gamma == 2.0: text += " o_color.rgb *= o_color.rgb;\n" elif gamma != 1.0: text += " o_color.rgb = pow(o_color.rgb, %ff);\n" % ( gamma) if ("Inverted" in configuration): text += " o_color = float4(1, 1, 1, 1) - o_color;\n" text += "}\n" self.finalQuad.setShader(Shader.make(text)) for tex in self.textures: self.finalQuad.setShaderInput("tx" + tex, self.textures[tex]) self.task = taskMgr.add(self.update, "common-filters-update") if (changed == "CartoonInk") or fullrebuild: if ("CartoonInk" in configuration): c = configuration["CartoonInk"] self.finalQuad.setShaderInput( "cartoonseparation", Vec4(c.separation, 0, c.separation, 0)) self.finalQuad.setShaderInput("cartooncolor", c.color) if (changed == "BlurSharpen") or fullrebuild: if ("BlurSharpen" in configuration): blurval = configuration["BlurSharpen"] self.finalQuad.setShaderInput( "blurval", Vec4(blurval, blurval, blurval, blurval)) if (changed == "Bloom") or fullrebuild: if ("Bloom" in configuration): bloomconf = configuration["Bloom"] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput("blend", bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0) self.bloom[0].setShaderInput( "trigger", bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0) self.bloom[0].setShaderInput("desat", bloomconf.desat) self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity) if (changed == "VolumetricLighting") or fullrebuild: if ("VolumetricLighting" in configuration): config = configuration["VolumetricLighting"] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput("vlparams", tcparam, config.decay, config.exposure, 0.0) if (changed == "AmbientOcclusion") or fullrebuild: if ("AmbientOcclusion" in configuration): config = configuration["AmbientOcclusion"] self.ssao[0].setShaderInput( "params1", config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0) self.ssao[0].setShaderInput("params2", config.strength, config.falloff, 0, 0) self.update() return True
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
class PerlinTest(DirectObject): 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) def run(self): for a in range(self.size): self.myList[a] = [0.5] * (self.size) self.startTime = time() taskMgr.add(self.noiseTaskVerySmart, "perlinNoiseTask") def noiseTask(self, Task=None): numLines = 8 if Task == None: y = 0 else: y = Task.frame * numLines for yNum in range(0, numLines): for x in range(0, self.size): i = self.p.noise2D(float(x) / self.size, float(y + yNum) / self.size) self.myImage.setGray(x, y + yNum, (i + 1.0) / 2) self.myTexture.load(self.myImage) if Task != None: if self.size >= y + numLines: return Task.cont else: self.myTexture.load(self.myImage) print time() - self.startTime return Task.done def noiseTaskSmart(self, Task=None): if Task == None: o = 0 else: o = Task.frame p = Perlin.Perlin(numberOfOctaves=1, smooth=False, seed=0) freq = 2 ** o for x in range(0, freq + 1): for y in range(0, freq + 1): self.i[x][y] = p.intNoise2D(x * freq, y * freq) for y in range(0, self.size): for x in range(0, self.size): intX = (x * freq) / self.size fraX = (float(x) * freq) / self.size - intX intY = (y * freq) / self.size i1 = p.linearInterpolate(self.i[intX][intY], self.i[intX + 1][intY], fraX) i2 = p.linearInterpolate(self.i[intX][intY + 1], self.i[intX + 1][intY + 1], fraX) interNoise = p.linearInterpolate(i1, i2, (float(y) * freq) / self.size - intY) self.myList[x][y] += interNoise * (0.75 ** o) / 2 self.myImage.setGray(x, y, self.myList[x][y]) self.myTexture.load(self.myImage) if Task != None: if freq < self.size: return Task.cont else: print time() - self.startTime return Task.done 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 reconfigure(self, fullrebuild, changed): configuration = self.configuration if fullrebuild: self.cleanup() if len(configuration) == 0: return None auxbits = 0 needtex = {} needtex['color'] = True if configuration.has_key('CartoonInk'): needtex['aux'] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if configuration.has_key('AmbientOcclusion'): needtex['depth'] = True needtex['ssao0'] = True needtex['ssao1'] = True needtex['ssao2'] = True needtex['aux'] = True auxbits |= AuxBitplaneAttrib.ABOAuxNormal if configuration.has_key('BlurSharpen'): needtex['blur0'] = True needtex['blur1'] = True if configuration.has_key('Bloom'): needtex['bloom0'] = True needtex['bloom1'] = True needtex['bloom2'] = True needtex['bloom3'] = True auxbits |= AuxBitplaneAttrib.ABOGlow if configuration.has_key('ViewGlow'): auxbits |= AuxBitplaneAttrib.ABOGlow for tex in needtex: self.textures[tex] = Texture('scene-' + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) needtexpix = True self.finalQuad = self.manager.renderSceneInto( textures=self.textures, auxbits=auxbits) if self.finalQuad == None: self.cleanup() return False if configuration.has_key('BlurSharpen'): blur0 = self.textures['blur0'] blur1 = self.textures['blur1'] self.blur.append( self.manager.renderQuadInto(colortex=blur0, div=2)) self.blur.append(self.manager.renderQuadInto(colortex=blur1)) self.blur[0].setShaderInput('src', self.textures['color']) self.blur[0].setShader(self.loadShader('filter-blurx.sha')) self.blur[1].setShaderInput('src', blur0) self.blur[1].setShader(self.loadShader('filter-blury.sha')) if configuration.has_key('AmbientOcclusion'): ssao0 = self.textures['ssao0'] ssao1 = self.textures['ssao1'] ssao2 = self.textures['ssao2'] self.ssao.append(self.manager.renderQuadInto(colortex=ssao0)) self.ssao.append( self.manager.renderQuadInto(colortex=ssao1, div=2)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao2)) self.ssao[0].setShaderInput('depth', self.textures['depth']) self.ssao[0].setShaderInput('normal', self.textures['aux']) self.ssao[0].setShaderInput( 'random', loader.loadTexture('maps/random.rgb')) self.ssao[0].setShader(self.loadShader('filter-ssao.sha')) self.ssao[1].setShaderInput('src', ssao0) self.ssao[1].setShader(self.loadShader('filter-blurx.sha')) self.ssao[2].setShaderInput('src', ssao1) self.ssao[2].setShader(self.loadShader('filter-blury.sha')) if configuration.has_key('Bloom'): bloomconf = configuration['Bloom'] bloom0 = self.textures['bloom0'] bloom1 = self.textures['bloom1'] bloom2 = self.textures['bloom2'] bloom3 = self.textures['bloom3'] if bloomconf.size == 'large': scale = 8 downsampler = 'filter-down4.sha' elif bloomconf.size == 'medium': scale = 4 downsampler = 'filter-copy.sha' else: scale = 2 downsampler = 'filter-copy.sha' self.bloom.append( self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput('src', self.textures['color']) self.bloom[0].setShader(self.loadShader('filter-bloomi.sha')) self.bloom[1].setShaderInput('src', bloom0) self.bloom[1].setShader(self.loadShader(downsampler)) self.bloom[2].setShaderInput('src', bloom1) self.bloom[2].setShader(self.loadShader('filter-bloomx.sha')) self.bloom[3].setShaderInput('src', bloom2) self.bloom[3].setShader(self.loadShader('filter-bloomy.sha')) text = '//Cg\n' text += 'void vshader(float4 vtx_position : POSITION,\n' text += ' out float4 l_position : POSITION,\n' text += ' uniform float4 texpad_txcolor,\n' text += ' uniform float4 texpix_txcolor,\n' text += ' out float4 l_texcoordC : TEXCOORD0,\n' if configuration.has_key('CartoonInk'): text += ' uniform float4 texpad_txaux,\n' text += ' uniform float4 texpix_txaux,\n' text += ' out float4 l_texcoordN : TEXCOORD1,\n' if configuration.has_key('Bloom'): text += ' uniform float4 texpad_txbloom3,\n' text += ' out float4 l_texcoordB : TEXCOORD2,\n' if configuration.has_key('BlurSharpen'): text += ' uniform float4 texpad_txblur1,\n' text += ' out float4 l_texcoordBS : TEXCOORD3,\n' if configuration.has_key('AmbientOcclusion'): text += ' uniform float4 texpad_txssao2,\n' text += ' out float4 l_texcoordAO : TEXCOORD4,\n' text += ' uniform float4x4 mat_modelproj)\n' text += '{\n' text += ' l_position=mul(mat_modelproj, vtx_position);\n' text += ' l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n' if configuration.has_key('CartoonInk'): text += ' l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n' if configuration.has_key('Bloom'): text += ' l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n' if configuration.has_key('BlurSharpen'): text += ' l_texcoordBS=(vtx_position.xzxz * texpad_txblur1) + texpad_txblur1;\n' if configuration.has_key('AmbientOcclusion'): text += ' l_texcoordAO=(vtx_position.xzxz * texpad_txssao2) + texpad_txssao2;\n' if configuration.has_key('HalfPixelShift'): text += ' l_texcoordC+=texpix_txcolor*0.5;\n' if configuration.has_key('CartoonInk'): text += ' l_texcoordN+=texpix_txaux*0.5;\n' text += '}\n' text += 'void fshader(\n' text += 'float4 l_texcoordC : TEXCOORD0,\n' text += 'uniform float4 texpix_txcolor,\n' if configuration.has_key('CartoonInk'): text += 'float4 l_texcoordN : TEXCOORD1,\n' text += 'uniform float4 texpix_txaux,\n' if configuration.has_key('Bloom'): text += 'float4 l_texcoordB : TEXCOORD2,\n' if configuration.has_key('BlurSharpen'): text += 'float4 l_texcoordBS : TEXCOORD3,\n' text += 'uniform float4 k_blurval,\n' if configuration.has_key('AmbientOcclusion'): text += 'float4 l_texcoordAO : TEXCOORD4,\n' for key in self.textures: text += 'uniform sampler2D k_tx' + key + ',\n' if configuration.has_key('CartoonInk'): text += 'uniform float4 k_cartoonseparation,\n' if configuration.has_key('VolumetricLighting'): text += 'uniform float4 k_casterpos,\n' text += 'uniform float4 k_vlparams,\n' text += 'out float4 o_color : COLOR)\n' text += '{\n' text += ' o_color = tex2D(k_txcolor, l_texcoordC.xy);\n' if configuration.has_key('CartoonInk'): text += CARTOON_BODY if configuration.has_key('AmbientOcclusion'): text += 'o_color *= tex2D(k_txssao2, l_texcoordAO.xy).r;\n' if configuration.has_key('BlurSharpen'): text += ' o_color = lerp(tex2D(k_txblur1, l_texcoordBS.xy), o_color, k_blurval.x);\n' if configuration.has_key('Bloom'): text += 'o_color = saturate(o_color);\n' text += 'float4 bloom = 0.5*tex2D(k_txbloom3, l_texcoordB.xy);\n' text += 'o_color = 1-((1-bloom)*(1-o_color));\n' if configuration.has_key('ViewGlow'): text += 'o_color.r = o_color.a;\n' if configuration.has_key('VolumetricLighting'): text += 'float decay = 1.0f;\n' text += 'float2 curcoord = l_texcoordC.xy;\n' text += 'float2 lightdir = curcoord - k_casterpos.xy;\n' text += 'lightdir *= k_vlparams.y;\n' text += 'half4 sample = tex2D(k_txcolor, curcoord);\n' text += 'float3 vlcolor = sample.rgb * sample.a;\n' text += 'for (int i = 0; i < k_vlparams.x; i++) {\n' text += ' curcoord -= lightdir;\n' text += ' sample = tex2D(k_txcolor, curcoord);\n' text += ' sample *= sample.a * decay;//*weight\n' text += ' vlcolor += sample.rgb;\n' text += ' decay *= k_vlparams.z;\n' text += '}\n' text += 'o_color += float4(vlcolor * k_vlparams.w, 1);\n' if configuration.has_key('Inverted'): text += 'o_color = float4(1, 1, 1, 1) - o_color;\n' text += '}\n' self.finalQuad.setShader(Shader.make(text)) for tex in self.textures: self.finalQuad.setShaderInput('tx' + tex, self.textures[tex]) self.task = taskMgr.add(self.update, 'common-filters-update') if changed == 'CartoonInk' or fullrebuild: if configuration.has_key('CartoonInk'): separation = configuration['CartoonInk'] self.finalQuad.setShaderInput( 'cartoonseparation', Vec4(separation, 0, separation, 0)) if changed == 'BlurSharpen' or fullrebuild: if configuration.has_key('BlurSharpen'): blurval = configuration['BlurSharpen'] self.finalQuad.setShaderInput( 'blurval', Vec4(blurval, blurval, blurval, blurval)) if changed == 'Bloom' or fullrebuild: if configuration.has_key('Bloom'): bloomconf = configuration['Bloom'] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput('blend', bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0) self.bloom[0].setShaderInput( 'trigger', bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0) self.bloom[0].setShaderInput('desat', bloomconf.desat) self.bloom[3].setShaderInput('intensity', intensity, intensity, intensity, intensity) if changed == 'VolumetricLighting' or fullrebuild: if configuration.has_key('VolumetricLighting'): config = configuration['VolumetricLighting'] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput('vlparams', config.numsamples, tcparam, config.decay, config.exposure) if changed == 'AmbientOcclusion' or fullrebuild: if configuration.has_key('AmbientOcclusion'): config = configuration['AmbientOcclusion'] self.ssao[0].setShaderInput( 'params1', config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0) self.ssao[0].setShaderInput('params2', config.strength, config.falloff, 0, 0) self.update() return True
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 def onCollision(entry): global groundImgChanged geom1 = entry.getGeom1() geom2 = entry.getGeom2() body1 = entry.getBody1()