def makeTextureMap(self): '''Citymania function that generates and sets the 4 channel texture map''' self.colorTextures = [] for terrain in self.terrains: terrain.getRoot().clearTexture() heightmap = terrain.heightfield() colormap = PNMImage(heightmap.getXSize() - 1, heightmap.getYSize() - 1) colormap.addAlpha() slopemap = terrain.makeSlopeImage() for x in range(0, colormap.getXSize()): for y in range(0, colormap.getYSize()): # Else if statements used to make sure one channel is used per pixel # Also for some optimization # Snow. We do things funky here as alpha will be 1 already. if heightmap.getGrayVal(x, y) < 200: colormap.setAlpha(x, y, 0) else: colormap.setAlpha(x, y, 1) # Beach. Estimations from http://www.simtropolis.com/omnibus/index.cfm/Main.SimCity_4.Custom_Content.Custom_Terrains_and_Using_USGS_Data if heightmap.getGrayVal(x, y) < 62: colormap.setBlue(x, y, 1) # Rock elif slopemap.getGrayVal(x, y) > 170: colormap.setRed(x, y, 1) else: colormap.setGreen(x, y, 1) colorTexture = Texture() colorTexture.load(colormap) colorTS = TextureStage('color') colorTS.setSort(0) colorTS.setPriority(1) self.colorTextures.append((colorTexture, colorTS))
def __map_Topography(self, planet, model, pts=[]): height_map = PNMImage() height_map_path = "{}/maps/{}".format(planet.path, planet.height_map) height_map.read(Filename(height_map_path)) _hu_size = height_map.getXSize()-1 _hv_size = height_map.getYSize()-1 radius = planet.radius bottom = radius + planet.height_min elev_range = planet.height_max - planet.height_min _has_sea = "sea_level" in planet.__dict__ if _has_sea: sea_level = planet.sea_level + planet.radius if not pts: pts = model.read("vertex") for pt in pts: u, v = self.__get_Pt_Uv(pt, _hu_size, _hv_size) height_val = height_map.getGray(u, v) ## watch when extending w colours. height = bottom + elev_range*height_val ratio = height / radius pt *= ratio # If planet has sea then raise vert to sea level. if _has_sea: len_pt = pt.length() if len_pt <= sea_level: ratio = sea_level/len_pt pt *= ratio model.modify("vertex", pts)
def __map_Topography(self, planet, model, pts=[]): height_map = PNMImage() height_map_path = "{}/maps/{}".format(planet.path, planet.height_map) height_map.read(Filename(height_map_path)) _hu_size = height_map.getXSize() - 1 _hv_size = height_map.getYSize() - 1 radius = planet.radius bottom = radius + planet.height_min elev_range = planet.height_max - planet.height_min _has_sea = "sea_level" in planet.__dict__ if _has_sea: sea_level = planet.sea_level + planet.radius if not pts: pts = model.read("vertex") for pt in pts: u, v = self.__get_Pt_Uv(pt, _hu_size, _hv_size) height_val = height_map.getGray( u, v) ## watch when extending w colours. height = bottom + elev_range * height_val ratio = height / radius pt *= ratio # If planet has sea then raise vert to sea level. if _has_sea: len_pt = pt.length() if len_pt <= sea_level: ratio = sea_level / len_pt pt *= ratio model.modify("vertex", pts)
def __init__(self, filename): vfs = VirtualFileSystem.getGlobalPtr() #self.material = BSPMaterial.getFromFile(filename) self.material = TexturePool.loadTexture(filename) self.filename = filename if self.material: #.hasKeyvalue("$basetexture"): # baseTexturePath = self.material.getKeyvalue("$basetexture") if True: #vfs.exists(baseTexturePath): #imageData = bytes(VirtualFileSystem.getGlobalPtr().readFile(baseTexturePath, True)) pimage = PNMImage() self.material.store(pimage, 0, 0) ss = StringStream() pimage.write(ss, "tmp.png") imageData = bytes(ss) byteArray = QtCore.QByteArray.fromRawData(imageData) image = QtGui.QImage.fromData(byteArray) self.pixmap = QtGui.QPixmap.fromImage(image) self.icon = QtGui.QIcon(self.pixmap) self.size = LVector2i(pimage.getXSize(), pimage.getYSize()) print(pimage, self.size) else: self.size = LVector2i(64, 64) self.icon = None self.pixmap = None else: self.size = LVector2i(64, 64) self.icon = None self.pixmap = None
def makeTextureMap(self): '''Citymania function that generates and sets the 4 channel texture map''' self.colorTextures = [] for terrain in self.terrains: terrain.getRoot().clearTexture() heightmap = terrain.heightfield() colormap = PNMImage(heightmap.getXSize()-1, heightmap.getYSize()-1) colormap.addAlpha() slopemap = terrain.makeSlopeImage() for x in range(0, colormap.getXSize()): for y in range(0, colormap.getYSize()): # Else if statements used to make sure one channel is used per pixel # Also for some optimization # Snow. We do things funky here as alpha will be 1 already. if heightmap.getGrayVal(x, y) < 200: colormap.setAlpha(x, y, 0) else: colormap.setAlpha(x, y, 1) # Beach. Estimations from http://www.simtropolis.com/omnibus/index.cfm/Main.SimCity_4.Custom_Content.Custom_Terrains_and_Using_USGS_Data if heightmap.getGrayVal(x,y) < 62: colormap.setBlue(x, y, 1) # Rock elif slopemap.getGrayVal(x, y) > 170: colormap.setRed(x, y, 1) else: colormap.setGreen(x, y, 1) colorTexture = Texture() colorTexture.load(colormap) colorTS = TextureStage('color') colorTS.setSort(0) colorTS.setPriority(1) self.colorTextures.append((colorTexture, colorTS))
def feedback(self, screenshot, reward, isEnd): resized = PNMImage(80, 60) resized.unfilteredStretchFrom(screenshot) width = resized.getXSize() height = resized.getYSize() green = \ map(lambda i: int(resized.getGreen(i % width, i / width) * 256) % 256, \ range(0, width * height)) data = struct.pack('IIffIII%sB' % len(green), 0xdeadbeef, self.historyFrameCounter, reward, self.velocity, isEnd, width, height, *green) with self.lock: self.bufferFeedback = data if isEnd: self.signalPlayerReady.clear() self.signalGameFeedback.set() # Make sure last frame of an episode is processed. if isEnd: while True: if not self.signalPlayerReady.wait(1): continue break
def setHeightfield(self, heightfield): '''Loads the heighmap image. Currently only accepts PNMIMage TODO: str path, FileName''' if type(heightfield) is str: heightfield = PNMImage(heightfield) self.heightfield = heightfield self.xsize = heightfield.getXSize() self.ysize = heightfield.getYSize()
def terrainFromHeightMap(self, main): self.parentNodePath = NodePath("FloorNodePath") self.parentNodePath.setPos(0, 0, -2) self.parentNodePath.setScale(5, 5, 0.75) # Heightfield (static) height = 8.0 img = PNMImage(Filename('models/elevation.png')) xdim = img.getXSize() ydim = img.getYSize() shape = BulletHeightfieldShape(img, height, ZUp) shape.setUseDiamondSubdivision(True) self.rigidNode = BulletRigidBodyNode('Heightfield') self.rigidNode.notifyCollisions(False) self.rigidNodePath = self.parentNodePath.attachNewNode(self.rigidNode) self.rigidNodePath.node().addShape(shape) self.rigidNodePath.setPos(0, 0, 0) self.rigidNodePath.setCollideMask(BitMask32.allOn()) self.rigidNodePath.node().notifyCollisions(False) main.world.attachRigidBody(self.rigidNodePath.node()) self.hf = self.rigidNodePath.node() # To enable/disable debug visualisation self.terrain = GeoMipTerrain('terrain') self.terrain.setHeightfield(img) self.terrain.setBlockSize(32) self.terrain.setNear(50) self.terrain.setFar(100) self.terrain.setFocalPoint(base.camera) rootNP = self.terrain.getRoot() rootNP.reparentTo(self.parentNodePath) rootNP.setSz(8.0) offset = img.getXSize() / 2.0 - 0.5 rootNP.setPos(-offset, -offset, -height / 2.0) self.terrain.generate() # Apply texture diffuseTexture = loader.loadTexture(Filename('models/diffuseMap.jpg')) diffuseTexture.setWrapU(Texture.WMRepeat) diffuseTexture.setWrapV(Texture.WMRepeat) rootNP.setTexture(diffuseTexture) # Normal map texStage = TextureStage('texStageNormal') texStage.setMode(TextureStage.MNormal) normalTexture = loader.loadTexture(Filename('models/normalMap.jpg')) rootNP.setTexture(texStage, normalTexture) # Glow map texStage = TextureStage('texStageNormal') texStage.setMode(TextureStage.MGlow) glowTexture = loader.loadTexture(Filename('models/glowMap.jpg')) rootNP.setTexture(texStage, glowTexture)
def createGround(self, terrainData): """Create ground using a heightmap""" # Create heightfield for physics heightRange = terrainData["heightRange"] # Image needs to have dimensions that are a power of 2 + 1 heightMap = PNMImage(self.basePath + terrainData["elevation"]) xdim = heightMap.getXSize() ydim = heightMap.getYSize() shape = BulletHeightfieldShape(heightMap, heightRange, ZUp) shape.setUseDiamondSubdivision(True) np = self.outsideWorldRender.attachNewNode(BulletRigidBodyNode("terrain")) np.node().addShape(shape) np.setPos(0, 0, 0) self.physicsWorld.attachRigidBody(np.node()) # Create graphical terrain from same height map terrain = GeoMipTerrain("terrain") terrain.setHeightfield(heightMap) terrain.setBlockSize(32) terrain.setBruteforce(True) rootNP = terrain.getRoot() rootNP.reparentTo(self.worldRender) rootNP.setSz(heightRange) offset = xdim / 2.0 - 0.5 rootNP.setPos(-offset, -offset, -heightRange / 2.0) terrain.generate() # Apply texture diffuse = self.loader.loadTexture(Filename(self.basePath + terrainData["texture"])) diffuse.setWrapU(Texture.WMRepeat) diffuse.setWrapV(Texture.WMRepeat) rootNP.setTexture(diffuse) textureSize = 6.0 ts = TextureStage.getDefault() rootNP.setTexScale(ts, xdim / textureSize, ydim / textureSize) # Create planes around area to prevent player flying off the edge # Levels can define barriers around them but it's probably a good # idea to leave this here just in case sides = ( (Vec3(1, 0, 0), -xdim / 2.0), (Vec3(-1, 0, 0), -xdim / 2.0), (Vec3(0, 1, 0), -ydim / 2.0), (Vec3(0, -1, 0), -ydim / 2.0), ) for sideNum, side in enumerate(sides): normal, offset = side sideShape = BulletPlaneShape(normal, offset) sideNode = BulletRigidBodyNode("side%d" % sideNum) sideNode.addShape(sideShape) self.physicsWorld.attachRigidBody(sideNode)
def paintAvatar(self, entry): """ Paints onto an avatar. Returns true on success, false on failure (because there are no avatar pixels under the mouse, for instance). """ # First, we have to render the avatar in its false-color # image, to determine which part of its texture is under the # mouse. if not self.avbuf: return False #mpos = base.mouseWatcherNode.getMouse() mpos = entry.getSurfacePoint(self.player) ppos = entry.getSurfacePoint(render) self.player.showThrough(BitMask32.bit(1)) self.avbuf.setActive(True) base.graphicsEngine.renderFrame() self.player.show(BitMask32.bit(1)) self.avbuf.setActive(False) # Now we have the rendered image in self.avbufTex. if not self.avbufTex.hasRamImage(): print "Weird, no image in avbufTex." return False p = PNMImage() self.avbufTex.store(p) ix = int((1 + mpos.getX()) * p.getXSize() * 0.5) iy = int((1 - mpos.getY()) * p.getYSize() * 0.5) x = 1 if ix >= 0 and ix < p.getXSize() and iy >= 0 and iy < p.getYSize(): s = p.getBlue(ix, iy) t = p.getGreen(ix, iy) x = p.getRed(ix, iy) if x > 0.5: # Off the avatar. return False # At point (s, t) on the avatar's map. self.__paint(s, t) return True
def loadSpriteImages(self,file_path,cols,rows,flipx = False,flipy = False): """ Loads an image file containing individual animation frames and returns then in a list of PNMImages inputs: - file_path - cols - rows - flipx - flipy Output: - tuple ( bool , list[PNMImage] ) """ # Make a filepath image_file = Filename(file_path) if image_file .empty(): raise IOError("File not found") return (False, []) # Instead of loading it outright, check with the PNMImageHeader if we can open # the file. img_head = PNMImageHeader() if not img_head.readHeader(image_file ): raise IOError("PNMImageHeader could not read file %s. Try using absolute filepaths"%(file_path)) return (False, []) # Load the image with a PNMImage full_image = PNMImage(img_head.getXSize(),img_head.getYSize()) full_image.alphaFill(0) full_image.read(image_file) if flipx or flipy: full_image.flip(flipx,flipy,False) w = int(full_image.getXSize()/cols) h = int(full_image.getYSize()/rows) images = [] counter = 0 for i in range(0,cols): for j in range(0,rows): sub_img = PNMImage(w,h) sub_img.addAlpha() sub_img.alphaFill(0) sub_img.fill(1,1,1) sub_img.copySubImage(full_image ,0 ,0 ,i*w ,j*h ,w ,h) images.append(sub_img) return (True, images)
def transparencyKey(filename): image = PNMImage(GAME+'/textures/effects/'+filename) image.addAlpha() backgroundColor = None for y in range(image.getYSize()): for x in range(image.getXSize()): if backgroundColor == None: backgroundColor = Color(image.getRedVal(x, y), image.getGreenVal(x, y), image.getGreenVal(x, y), 0) if image.getRedVal(x, y) == backgroundColor.R and \ image.getGreenVal(x, y) == backgroundColor.G and \ image.getGreenVal(x, y) == backgroundColor.B: # Transparent image.setAlpha(x, y, 0.0) else: # Opaque image.setAlpha(x, y, 1.0) return image
def __map_Colours(self, planet, model, rec, pts=[]): col_map_path = planet.colour_map.replace(".", "_low.") col_map_fn = Filename("{}/maps/{}".format(planet.path, col_map_path)) col_map = PNMImage() col_map.read(col_map_fn) _cu_size = col_map.getXSize() - 1 _cv_size = col_map.getYSize() - 1 cols = [] if not pts: pts = model.read("vertex") for pt in pts: u, v = self.__get_Pt_Uv(pt, _cu_size, _cv_size) r = col_map.getRed(u, v) g = col_map.getGreen(u, v) b = col_map.getBlue(u, v) pt_col = (r, g, b, 1) cols.append(pt_col) model.modify("color", cols)
def __map_Colours(self, planet, model, rec, pts=[]): col_map_path = planet.colour_map.replace(".","_low.") col_map_fn = Filename("{}/maps/{}".format(planet.path, col_map_path)) col_map = PNMImage() col_map.read(col_map_fn) _cu_size = col_map.getXSize()-1 _cv_size = col_map.getYSize()-1 cols = [] if not pts: pts = model.read("vertex") for pt in pts: u, v = self.__get_Pt_Uv(pt, _cu_size, _cv_size) r = col_map.getRed(u, v) g = col_map.getGreen(u, v) b = col_map.getBlue(u, v) pt_col = (r, g, b, 1) cols.append(pt_col) model.modify("color", cols)
def __loadSpritePair__(sprite_details): image_file = sprite_details.im_file img_head = PNMImageHeader() if not img_head.readHeader(image_file ): logging.error( "PNMImageHeader could not read file %s. Try using absolute filepaths"%(image_file)) return (None,None) # Load the right side image as a PNMImage right_img = PNMImage(img_head.getXSize(),img_head.getYSize()) right_img.alphaFill(0) right_img.read(image_file) # Flip to get the left side image left_img = PNMImage(right_img.getXSize(),right_img.getYSize()) left_img.copyFrom(right_img) left_img.flip(True ,False,False) images = [(right_img,False),(left_img,True)] sprites = [] for entry in images: img = entry[0] flip = entry[1] sprite = Sprite() sprite.setXSize(img.getXSize()) sprite.setYSize(img.getYSize()) sprite.setZSize(1) sprite.axisx = -sprite_details.axisx if (not flip ) else sprite_details.axisx sprite.axisy = sprite_details.axisy sprite.group = sprite_details.group_no sprite.no = sprite_details.image_no sprite.load(img) sprite.setWrapU(Texture.WM_border_color) # gets rid of odd black edges around image sprite.setWrapV(Texture.WM_border_color) sprite.setBorderColor(LColor(0,0,0,0)) sprites.append(sprite) return (sprites[0],sprites[1])
def addImage(self, image): """ Adds an image to the icon. Returns False on failure, True on success. Only one image per size can be loaded, and the image size must be square. """ if not isinstance(image, PNMImage): fn = image if not isinstance(fn, Filename): fn = Filename.fromOsSpecific(fn) image = PNMImage() if not image.read(fn): Icon.notify.warning("Image '%s' could not be read" % fn.getBasename()) return False if image.getXSize() != image.getYSize(): Icon.notify.warning("Ignoring image without square size") return False self.images[image.getXSize()] = image return True
def generateWorld(self, heightmap, tiles, cities, container): self.heightmap = heightmap self.terrain = PagedGeoMipTerrain("surface") #self.terrain = GeoMipTerrain("surface") self.terrain.setHeightfield(self.heightmap) #self.terrain.setFocalPoint(base.camera) self.terrain.setBruteforce(True) self.terrain.setBlockSize(64) self.terrain.generate() root = self.terrain.getRoot() root.reparentTo(render) #root.setSz(100) self.terrain.setSz(100) messenger.send('makePickable', [root]) if self.heightmap.getXSize() > self.heightmap.getYSize(): self.size = self.heightmap.getXSize() - 1 else: self.size = self.heightmap.getYSize() - 1 self.xsize = self.heightmap.getXSize() - 1 self.ysize = self.heightmap.getYSize() - 1 # Set multi texture # Source http://www.panda3d.org/phpbb2/viewtopic.php?t=4536 self.generateSurfaceTextures() self.generateWaterMap() self.generateOwnerTexture(tiles, cities) #self.terrain.makeTextureMap() colormap = PNMImage(heightmap.getXSize() - 1, heightmap.getYSize() - 1) colormap.addAlpha() slopemap = self.terrain.makeSlopeImage() for x in range(0, colormap.getXSize()): for y in range(0, colormap.getYSize()): # Else if statements used to make sure one channel is used per pixel # Also for some optimization # Snow. We do things funky here as alpha will be 1 already. if heightmap.getGrayVal(x, y) < 200: colormap.setAlpha(x, y, 0) else: colormap.setAlpha(x, y, 1) # Beach. Estimations from http://www.simtropolis.com/omnibus/index.cfm/Main.SimCity_4.Custom_Content.Custom_Terrains_and_Using_USGS_Data if heightmap.getGrayVal(x, y) < 62: colormap.setBlue(x, y, 1) # Rock elif slopemap.getGrayVal(x, y) > 170: colormap.setRed(x, y, 1) else: colormap.setGreen(x, y, 1) self.colorTexture = Texture() self.colorTexture.load(colormap) self.colorTS = TextureStage('color') self.colorTS.setSort(0) self.colorTS.setPriority(1) self.setSurfaceTextures() self.generateWater(2) taskMgr.add(self.updateTerrain, "updateTerrain") print "Done with terrain generation" messenger.send("finishedTerrainGen", [[self.xsize, self.ysize]]) self.terrain.getRoot().analyze() self.accept("h", self.switchWater)
class ColorPicker(NodePath): def __init__(self, parent, minSat, maxSat, minVal, maxVal, callback, pos=(0, 0, 0)): NodePath.__init__(self, 'colorPicker') self.reparentTo(parent) self.setPos(pos) self.minSat = minSat self.maxSat = maxSat self.minVal = minVal self.maxVal = maxVal self.callback = callback self.lastColor = None self.image = PNMImage(int((self.maxSat - self.minSat) * 100), int((self.maxVal - self.minVal) * 100)) self.slider = DirectSlider(self, relief=None, image='phase_3/maps/color_picker_hue.jpg', scale=0.3, pos=(0.2, 0, 0), image_scale=(0.1, 1.0, 1.0), pageSize=5, orientation=DGG.VERTICAL, command=self.__chooseHue) self.button = DirectButton(self, relief=None, image=None, scale=0.3, pos=(-0.2, 0, 0), frameColor=(1, 1, 1, 0.1), pressEffect=0) self.button.bind(DGG.B1PRESS, self.__startPick) self.button.bind(DGG.B1RELEASE, self.__stopPick) self.__chooseHue() def uniqueName(self, name): return 'ColorPicker-%s-%s' % (id(self), name) def removeNode(self): NodePath.removeNode(self) self.destroy() def destroy(self): if not self.slider: return self.__stopPick() self.slider.destroy() self.button.destroy() self.slider = None self.button = None self.image = None def __calcRelative(self, value, baseMin, baseMax, limitMin, limitMax): return ((limitMax - limitMin) * (value - baseMin) / (baseMax - baseMin)) + limitMin def __chooseHue(self): for x in xrange(self.image.getXSize()): for y in xrange(self.image.getYSize()): self.image.setXel( x, y, colorsys.hsv_to_rgb(self.slider['value'], (x / 100.0) + self.minSat, (y / 100.0) + self.minVal)) texture = Texture() texture.load(self.image) self.button['image'] = texture def __pickColor(self, task): x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() win_w, win_h = base.win.getSize() if win_w < win_h: y *= 1. * win_h / win_w else: x *= 1. * win_w / win_h x -= self.button.getX(aspect2d) y -= self.button.getZ(aspect2d) image_scale = self.button['image_scale'] x = (.5 + x / (2. * self.button.getSx(aspect2d) * image_scale[0])) y = (.5 + y / -(2. * self.button.getSz(aspect2d) * image_scale[2])) if not (0.0 <= x <= 1.0 and 0.0 <= y <= 1.0): return task.cont x = self.__calcRelative(x, 0.0, 1.0, self.minSat, self.maxSat) y = self.__calcRelative(y, 0.0, 1.0, self.minVal, self.maxVal) rgb = colorsys.hsv_to_rgb(self.slider['value'], x, y) + (1, ) rgb = tuple([float('%.2f' % x) for x in rgb]) if self.lastColor != rgb: self.callback(rgb) self.lastColor = rgb return task.cont def __startPick(self, extra=None): self.__stopPick() taskMgr.add(self.__pickColor, self.uniqueName('colorDragTask')) def __stopPick(self, extra=None): taskMgr.remove(self.uniqueName('colorDragTask'))
def __init__(self, image_path, name=None,\ rows=1, cols=1, scale=1.0,\ twoSided=True, alpha=TRANS_ALPHA,\ repeatX=1, repeatY=1,\ anchorX=ALIGN_LEFT, 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. """ 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() self.frames = [] for rowIdx in range(self.rows): for colIdx in range(self.cols): self.frames.append(Sprite2d.Cell(colIdx, rowIdx)) # 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 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.card = self.node.attachNewNode(card.generate()) # 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)
class PlayerBase(DirectObject): def __init__(self): # Player Model setup self.player = Actor("Player", {"Run":"Player-Run", "Sidestep":"Player-Sidestep", "Idle":"Player-Idle"}) self.player.setBlend(frameBlend = True) self.player.setPos(0, 0, 0) self.player.pose("Idle", 0) self.player.reparentTo(render) self.player.hide() self.footstep = base.audio3d.loadSfx('footstep.ogg') self.footstep.setLoop(True) base.audio3d.attachSoundToObject(self.footstep, self.player) # Create a brush to paint on the texture splat = PNMImage("../data/Splat.png") self.colorBrush = PNMBrush.makeImage(splat, 6, 6, 1) CamMask = BitMask32.bit(0) AvBufMask = BitMask32.bit(1) self.avbuf = None if base.win: self.avbufTex = Texture('avbuf') self.avbuf = base.win.makeTextureBuffer('avbuf', 256, 256, self.avbufTex, True) cam = Camera('avbuf') cam.setLens(base.camNode.getLens()) self.avbufCam = base.cam.attachNewNode(cam) dr = self.avbuf.makeDisplayRegion() dr.setCamera(self.avbufCam) self.avbuf.setActive(False) self.avbuf.setClearColor((1, 0, 0, 1)) cam.setCameraMask(AvBufMask) base.camNode.setCameraMask(CamMask) # avbuf renders everything it sees with the gradient texture. tex = loader.loadTexture('gradient.png') np = NodePath('np') np.setTexture(tex, 100) np.setColor((1, 1, 1, 1), 100) np.setColorScaleOff(100) np.setTransparency(TransparencyAttrib.MNone, 100) np.setLightOff(100) cam.setInitialState(np.getState()) #render.hide(AvBufMask) # Setup a texture stage to paint on the player self.paintTs = TextureStage('paintTs') self.paintTs.setMode(TextureStage.MDecal) self.paintTs.setSort(10) self.paintTs.setPriority(10) self.tex = Texture('paint_av_%s'%id(self)) # Setup a PNMImage that will hold the paintable texture of the player self.imageSizeX = 64 self.imageSizeY = 64 self.p = PNMImage(self.imageSizeX, self.imageSizeY, 4) self.p.fill(1) self.p.alphaFill(0) self.tex.load(self.p) self.tex.setWrapU(self.tex.WMClamp) self.tex.setWrapV(self.tex.WMClamp) # Apply the paintable texture to the avatar self.player.setTexture(self.paintTs, self.tex) # team self.playerTeam = "" # A lable that will display the players team self.lblTeam = DirectLabel( scale = 1, pos = (0, 0, 3), frameColor = (0, 0, 0, 0), text = "TEAM", text_align = TextNode.ACenter, text_fg = (0,0,0,1)) self.lblTeam.reparentTo(self.player) self.lblTeam.setBillboardPointEye() # basic player values self.maxHits = 3 self.currentHits = 0 self.isOut = False self.TorsorControl = self.player.controlJoint(None,"modelRoot","Torsor") # setup the collision detection # wall and object collision self.playerSphere = CollisionSphere(0, 0, 1, 1) self.playerCollision = self.player.attachNewNode(CollisionNode("playerCollision%d"%id(self))) self.playerCollision.node().addSolid(self.playerSphere) base.pusher.addCollider(self.playerCollision, self.player) base.cTrav.addCollider(self.playerCollision, base.pusher) # foot (walk) collision self.playerFootRay = self.player.attachNewNode(CollisionNode("playerFootCollision%d"%id(self))) self.playerFootRay.node().addSolid(CollisionRay(0, 0, 2, 0, 0, -1)) self.playerFootRay.node().setIntoCollideMask(0) self.lifter = CollisionHandlerFloor() self.lifter.addCollider(self.playerFootRay, self.player) base.cTrav.addCollider(self.playerFootRay, self.lifter) # Player weapon setup self.gunAttach = self.player.exposeJoint(None, "modelRoot", "WeaponSlot_R") self.color = LPoint3f(1, 1, 1) self.gun = Gun(id(self)) self.gun.reparentTo(self.gunAttach) self.gun.hide() self.gun.setColor(self.color) self.hud = None # Player controls setup self.keyMap = {"left":0, "right":0, "forward":0, "backward":0} # screen sizes self.winXhalf = base.win.getXSize() / 2 self.winYhalf = base.win.getYSize() / 2 self.mouseSpeedX = 0.1 self.mouseSpeedY = 0.1 # AI controllable variables self.AIP = 0.0 self.AIH = 0.0 self.movespeed = 5.0 self.userControlled = False self.accept("Bulet-hit-playerCollision%d" % id(self), self.hit) self.accept("window-event", self.recalcAspectRatio) def runBase(self): self.player.show() self.gun.show() taskMgr.add(self.move, "moveTask%d"%id(self), priority=-4) def stopBase(self): taskMgr.remove("moveTask%d"%id(self)) self.ignoreAll() self.gun.remove() self.footstep.stop() base.audio3d.detachSound(self.footstep) self.player.delete() def setKey(self, key, value): self.keyMap[key] = value def setPos(self, pos): self.player.setPos(pos) def setColor(self, color=LPoint3f(0,0,0)): self.color = color self.gun.setColor(color) c = (color[0], color[1], color[2], 1.0) self.lblTeam["text_fg"] = c def setTeam(self, team): self.playerTeam = team self.lblTeam["text"] = team def shoot(self, shotVec=None): self.gun.shoot(shotVec) if self.hud != None: self.hud.updateAmmo(self.gun.maxAmmunition, self.gun.ammunition) def reload(self): self.gun.reload() if self.hud != None: self.hud.updateAmmo(self.gun.maxAmmunition, self.gun.ammunition) def recalcAspectRatio(self, window): self.winXhalf = window.getXSize() / 2 self.winYhalf = window.getYSize() / 2 def hit(self, entry, color): self.currentHits += 1 # Create a brush to paint on the texture splat = PNMImage("../data/Splat.png") splat = splat * LColorf(color[0], color[1], color[2], 1.0) self.colorBrush = PNMBrush.makeImage(splat, 6, 6, 1) self.paintAvatar(entry) if self.currentHits >= self.maxHits: base.messenger.send("GameOver-player%d" % id(self)) self.isOut = True def __paint(self, s, t): """ Paints a point on the avatar at texture coordinates (s, t). """ x = (s * self.p.getXSize()) y = ((1.0 - t) * self.p.getYSize()) # Draw in color directly on the avatar p1 = PNMPainter(self.p) p1.setPen(self.colorBrush) p1.drawPoint(x, y) self.tex.load(self.p) self.tex.setWrapU(self.tex.WMClamp) self.tex.setWrapV(self.tex.WMClamp) self.paintDirty = True def paintAvatar(self, entry): """ Paints onto an avatar. Returns true on success, false on failure (because there are no avatar pixels under the mouse, for instance). """ # First, we have to render the avatar in its false-color # image, to determine which part of its texture is under the # mouse. if not self.avbuf: return False #mpos = base.mouseWatcherNode.getMouse() mpos = entry.getSurfacePoint(self.player) ppos = entry.getSurfacePoint(render) self.player.showThrough(BitMask32.bit(1)) self.avbuf.setActive(True) base.graphicsEngine.renderFrame() self.player.show(BitMask32.bit(1)) self.avbuf.setActive(False) # Now we have the rendered image in self.avbufTex. if not self.avbufTex.hasRamImage(): print "Weird, no image in avbufTex." return False p = PNMImage() self.avbufTex.store(p) ix = int((1 + mpos.getX()) * p.getXSize() * 0.5) iy = int((1 - mpos.getY()) * p.getYSize() * 0.5) x = 1 if ix >= 0 and ix < p.getXSize() and iy >= 0 and iy < p.getYSize(): s = p.getBlue(ix, iy) t = p.getGreen(ix, iy) x = p.getRed(ix, iy) if x > 0.5: # Off the avatar. return False # At point (s, t) on the avatar's map. self.__paint(s, t) return True def move(self, task): if self is None: return task.done if self.userControlled: if not base.mouseWatcherNode.hasMouse(): return task.cont self.pointer = base.win.getPointer(0) mouseX = self.pointer.getX() mouseY = self.pointer.getY() if base.win.movePointer(0, self.winXhalf, self.winYhalf): p = self.TorsorControl.getP() + (mouseY - self.winYhalf) * self.mouseSpeedY if p <-80: p = -80 elif p > 90: p = 90 self.TorsorControl.setP(p) h = self.player.getH() - (mouseX - self.winXhalf) * self.mouseSpeedX if h <-360: h = 360 elif h > 360: h = -360 self.player.setH(h) else: self.TorsorControl.setP(self.AIP) self.player.setH(self.AIH) forward = self.keyMap["forward"] != 0 backward = self.keyMap["backward"] != 0 if self.keyMap["left"] != 0: if self.player.getCurrentAnim() != "Sidestep" and not (forward or backward): self.player.loop("Sidestep") self.player.setPlayRate(5, "Sidestep") self.player.setX(self.player, self.movespeed * globalClock.getDt()) elif self.keyMap["right"] != 0: if self.player.getCurrentAnim() != "Sidestep" and not (forward or backward): self.player.loop("Sidestep") self.player.setPlayRate(5, "Sidestep") self.player.setX(self.player, -self.movespeed * globalClock.getDt()) else: self.player.stop("Sidestep") if forward: if self.player.getCurrentAnim() != "Run": self.player.loop("Run") self.player.setPlayRate(5, "Run") self.player.setY(self.player, -self.movespeed * globalClock.getDt()) elif backward: if self.player.getCurrentAnim() != "Run": self.player.loop("Run") self.player.setPlayRate(-5, "Run") self.player.setY(self.player, self.movespeed * globalClock.getDt()) else: self.player.stop("Run") if not (self.keyMap["left"] or self.keyMap["right"] or self.keyMap["forward"] or self.keyMap["backward"] or self.player.getCurrentAnim() == "Idle"): self.player.loop("Idle") self.footstep.stop() else: self.footstep.play() return task.cont
def generateWorld(self, heightmap, tiles, cities, container): self.heightmap = heightmap self.terrain = PagedGeoMipTerrain("surface") #self.terrain = GeoMipTerrain("surface") self.terrain.setHeightfield(self.heightmap) #self.terrain.setFocalPoint(base.camera) self.terrain.setBruteforce(True) self.terrain.setBlockSize(64) self.terrain.generate() root = self.terrain.getRoot() root.reparentTo(render) #root.setSz(100) self.terrain.setSz(100) messenger.send('makePickable', [root]) if self.heightmap.getXSize() > self.heightmap.getYSize(): self.size = self.heightmap.getXSize()-1 else: self.size = self.heightmap.getYSize()-1 self.xsize = self.heightmap.getXSize()-1 self.ysize = self.heightmap.getYSize()-1 # Set multi texture # Source http://www.panda3d.org/phpbb2/viewtopic.php?t=4536 self.generateSurfaceTextures() self.generateWaterMap() self.generateOwnerTexture(tiles, cities) #self.terrain.makeTextureMap() colormap = PNMImage(heightmap.getXSize()-1, heightmap.getYSize()-1) colormap.addAlpha() slopemap = self.terrain.makeSlopeImage() for x in range(0, colormap.getXSize()): for y in range(0, colormap.getYSize()): # Else if statements used to make sure one channel is used per pixel # Also for some optimization # Snow. We do things funky here as alpha will be 1 already. if heightmap.getGrayVal(x, y) < 200: colormap.setAlpha(x, y, 0) else: colormap.setAlpha(x, y, 1) # Beach. Estimations from http://www.simtropolis.com/omnibus/index.cfm/Main.SimCity_4.Custom_Content.Custom_Terrains_and_Using_USGS_Data if heightmap.getGrayVal(x,y) < 62: colormap.setBlue(x, y, 1) # Rock elif slopemap.getGrayVal(x, y) > 170: colormap.setRed(x, y, 1) else: colormap.setGreen(x, y, 1) self.colorTexture = Texture() self.colorTexture.load(colormap) self.colorTS = TextureStage('color') self.colorTS.setSort(0) self.colorTS.setPriority(1) self.setSurfaceTextures() self.generateWater(2) taskMgr.add(self.updateTerrain, "updateTerrain") print "Done with terrain generation" messenger.send("finishedTerrainGen", [[self.xsize, self.ysize]]) self.terrain.getRoot().analyze() self.accept("h", self.switchWater)