def __init__(self, scale=1, value=0, r=10, g=0, b=0): NodePath.__init__(self, 'healthbar') self.value = value self.scale = scale self.range = 1.0 self.buff = 0 cmbg = CardMaker('bg') cmbg.setFrame(- scale, scale, -0.1 * scale, 0.1 * scale) self.bg = self.attachNewNode(cmbg.generate()) self.bg.setColor(0.2, 0.2, 0.2, 1) self.bg.setPos(0,0,5.8) cmfg = CardMaker('fg') cmfg.setFrame(- scale, scale, -0.1 * scale, 0.1 * scale) self.fg = self.bg.attachNewNode(cmfg.generate()) self.fg.setColor(r, g, b, 1) self.fg.setPos(0,-0.1,0) self.fg.setBillboardPointWorld() self.bg.setBillboardPointWorld() self.fg.clearShader() self.bg.clearShader() self.setValue(0)
class FirstTry(visual): def setup(self): self.tex1 = MovieTexture('videos/saturn5_apollo_launch.mp4') assert self.tex1.read('videos/saturn5_apollo_launch.mp4') self.tex2 = MovieTexture('videos/boards_eye_view.mp4') assert self.tex2.read('videos/boards_eye_view.mp4') self.cm1 = CardMaker('saturn') self.cm1.setFrameFullscreenQuad() self.cm1.setUvRange(self.tex1) self.card1 = NodePath(self.cm1.generate()) self.card1.reparentTo(self.path) self.card1.setPos(0,0,10) self.card1.setP(50) self.cm2 = CardMaker('board') self.cm2.setFrameFullscreenQuad() self.cm2.setUvRange(self.tex2) self.card2 = NodePath(self.cm2.generate()) self.card2.reparentTo(self.path) self.card2.setPos(0,0,-10) self.card2.setP(-50) self.card1.setTexture(self.tex1) self.card1.setTexScale(TextureStage.getDefault(), self.tex1.getTexScale()) self.card2.setTexture(self.tex2) self.card2.setTexScale(TextureStage.getDefault(), self.tex2.getTexScale()) self.card1.setScale(10) self.card2.setScale(10) def getBeat(self): pass
def iterate(self): cm = CardMaker('CardMaker-GameOver') tex = loadTexture('gameover.png') cm.setFrame(-1, 1, -1, 1) bg = self.node.attachNewNode(cm.generate()) bg.setColor(0, 0, 0) bg.setPos(0, 0, 0) cm.setFrame(-0.4, 0.4, -0.2, 0.2) self.text = self.node.attachNewNode(cm.generate()) self.text.setPos(0, 0, 0) self.text.setTexture(tex)
def register(self, render, camera, keys): State.register(self, render, camera, keys) cm = CardMaker('CardMaker-Title') tex = loadTexture('titlescreen.png') cm.setFrame(-1, 1, -1, 1) self.bg = self.node.attachNewNode(cm.generate()) self.bg.setPos(0, 0, 0) self.bg.setTexture(tex) menuActions = {'up': (Menu.previousOpt, self.menu), 'down': (Menu.nextOpt, self.menu), 'action': (self.selectOption, None) } self.menu.registerKeys(keys, menuActions) self.title = OnscreenText(text="", mayChange = True , style=2, fg=(1,1,1,1), pos=(0, 0.75), scale = 0.2) # is this used?? self.text = {} id=0 for opt in self.menu.options: self.text[opt] = OnscreenText(text=opt, mayChange = True , style=2, fg=(1,1,1,1), pos=(0, -0.3 - 0.15*id), scale = .1) id+=1 self.title.reparentTo(self.node) for opt in self.text.keys(): self.text[opt].reparentTo(self.node) State.register(self, render, camera, keys)
def __init__(self, battleGraphics, matrixContainer): self.battleGraphics = battleGraphics self.matrixContainer = matrixContainer self.curtex = loader.loadTexture(GAME+'/textures/cursor.png') self.curtex.setMagfilter(Texture.FTNearest) self.curtex.setMinfilter(Texture.FTNearest) self.x = False self.y = False self.z = False self.cursor = loader.loadModel(GAME+'/models/slopes/flat') self.cursor.reparentTo( self.matrixContainer ) self.cursor.setScale(3.7) self.cursor.setTransparency(TransparencyAttrib.MAlpha) self.cursor.setColor( 1, 1, 1, 1 ) self.cursor.setTexture(self.curtex) pointertex = loader.loadTexture(GAME+'/textures/pointer.png') pointertex.setMagfilter(Texture.FTNearest) pointertex.setMinfilter(Texture.FTNearest) cm = CardMaker('card') cm.setFrame(-2, 2, -2, 2) self.pointer = render.attachNewNode(cm.generate()) self.pointer.setTexture(pointertex) self.pointer.setTransparency(True) self.pointer.setBillboardPointEye() self.pointer.reparentTo(render) self.pointer.setScale(256.0/240.0)
def playVideo(self, video): # check if it is loadable try: # load the video texture self.tex = MovieTexture("MovieTexture") #print video self.tex.read(video) # Set up a fullscreen card to set the video texture on it. cm = CardMaker("Movie Card") cm.setFrameFullscreenQuad() cm.setUvRange(self.tex) self.card = NodePath(cm.generate()) self.card.reparentTo(base.render2d) self.card.setTexture(self.tex) self.card.setTexScale(TextureStage.getDefault(), self.tex.getTexScale()) # load the video self.sound = loader.loadSfx(video) # Synchronize the video to the sound. self.tex.synchronizeTo(self.sound) # play the video and audio self.sound.play() # start the task which checks if the video is finished taskMgr.add(self.isVideoFinish, "task_isVideoFinised") except: logging.error("Failed to load video: %s %s", video, sys.exc_info()) self.stopVideo() base.messenger.send(self.vidFinEvt)
def add_ground(self): cm = CardMaker("ground") cm.setFrame(-1, 1, -1, 1) ground = render.attachNewNode(cm.generate()) ground.setColor(0.5, 0.7, 0.8) ground.lookAt(0, 0, -1) groundGeom = OdePlaneGeom(self.space, Vec4(0, 0, 1, 0))
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()
class MatPlotLibDemo(ShowBase): def __init__(self): ShowBase.__init__(self) base.setFrameRateMeter(True) m = loader.loadModel("models/smiley") m.reparent_to(render) m.set_pos(0, 5, 0) x_size, y_size = 640, 480 xy_ratio = float(y_size) / float(x_size) self.plot = Plot(x_size, y_size) self.input_img = PNMImage(x_size, y_size) self.input_tex = Texture() self.input_tex.load(self.input_img) self.card = CardMaker('pygame_card') self.card.setUvRange(Point2(0, 1), # ll Point2(1, 1), # lr Point2(1, 0), # ur Point2(0, 0)) # ul self.screen = render.attach_new_node(self.card.generate()) self.screen.set_scale(1, 1, xy_ratio) self.screen.set_pos(-0.5, 2, -0.5 * xy_ratio) self.screen.setTexture(self.input_tex) # FIXME: Apparently mpl's print_to_buffer() doesn't write # alpha values properly. self.screen.setTransparency(TransparencyAttrib.MAlpha) taskMgr.add(self.update, "update plot") def update(self, task): self.input_tex.set_ram_image_as(self.plot.draw(), "RGBA") return task.cont
def genArrow(self, pos, hpr, id): factory = CardMaker('factory') factory.setFrame(-.5, 0.5, -.5, 0.5) arrowNode = factory.generate() arrowRoot = NodePath('root') baseArrow = NodePath(arrowNode) baseArrow.setTransparency(1) baseArrow.setTexture(self.boostArrowTexture) baseArrow.reparentTo(arrowRoot) arrow2 = baseArrow.copyTo(baseArrow) arrow2.setPos(0, 0, 1) arrow3 = arrow2.copyTo(arrow2) arrowRoot.setPos(*pos) arrowRoot.setHpr(*hpr) baseArrow.setHpr(0, -90, 0) baseArrow.setScale(24) arrowRoot.reparentTo(self.geom) trigger = 'boostArrow' + str(id) cs = CollisionTube(Point3(0.6, -6, 0), Point3(0.6, 54, 0), 4.8) cs.setTangible(0) triggerEvent = 'imIn-' + trigger cn = CollisionNode(trigger) cn.addSolid(cs) cn.setIntoCollideMask(BitMask32(32768)) cn.setFromCollideMask(BitMask32(32768)) cnp = NodePath(cn) cnp.reparentTo(arrowRoot) self.accept(triggerEvent, self.hitBoostArrow) arrowVec = arrow2.getPos(self.geom) - baseArrow.getPos(self.geom) arrowVec.normalize() idStr = str(id) cnp.setTag('boostId', idStr) self.boostDir[idStr] = arrowVec base.arrows.append(arrowRoot)
def setupBackgroundImage(self): image_file = Filename(TestGameBase.__BACKGROUND_IMAGE_PATH__) # check if image can be loaded img_head = PNMImageHeader() if not img_head.readHeader(image_file ): raise IOError("PNMImageHeader could not read file %s. Try using absolute filepaths"%(image_file.c_str())) sys.exit() # Load the image with a PNMImage w = img_head.getXSize() h = img_head.getYSize() img = PNMImage(w,h) #img.alphaFill(0) img.read(image_file) texture = Texture() texture.setXSize(w) texture.setYSize(h) texture.setZSize(1) texture.load(img) texture.setWrapU(Texture.WM_border_color) # gets rid of odd black edges around image texture.setWrapV(Texture.WM_border_color) texture.setBorderColor(LColor(0,0,0,0)) # creating CardMaker to hold the texture cm = CardMaker('background') cm.setFrame(-0.5*w,0.5*w,-0.5*h,0.5*h) # This configuration places the image's topleft corner at the origin (left, right, bottom, top) background_np = NodePath(cm.generate()) background_np.setTexture(texture) background_np.reparentTo(self.render) background_np.setPos(TestGameBase.__BACKGROUND_POSITION__) background_np.setScale(TestGameBase.__BACKGROUND_SCALE__)
def renderQuadInto(self, xsize, ysize, colortex=None, cmode = GraphicsOutput.RTMBindOrCopy, auxtex = None): buffer = self.createBuffer("filter-stage", xsize, ysize, colortex, cmode, auxtex) if (buffer == None): return None cm = CardMaker("filter-stage-quad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setColor(Vec4(1,0.5,0.5,1)) 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) buffer.getDisplayRegion(0).setCamera(quadcam) buffer.getDisplayRegion(0).setActive(1) return quad, buffer
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 register(self, render, camera, keys): State.register(self, render, camera, keys) cm = CardMaker('CardMaker-Pause') cm.setFrame(0.5, -0.5, 0.5, -0.5) cm.setColor(0,0,0, 0.1) self.bg = self.node.attachNewNode(cm.generate()) self.bg.setPos(0, 0, 0) menuActions = {'up': (Menu.previousOpt, self.menu), 'down': (Menu.nextOpt, self.menu), 'action': (self.selectOption, None), 'cancel': (self.selectOption, 0) } self.menu.registerKeys(keys, menuActions) self.title = OnscreenText(text="Game Paused", mayChange = True , style=1, fg=(1,1,1,1), pos=(0,0.35), scale = .1) self.text = {} id=0 for opt in self.menu.options: self.text[opt] = OnscreenText(text=opt, mayChange = True , style=1, fg=(1,1,1,1), pos=(0,0.1 - 0.1*id), scale = .06) id+=1 self.title.reparentTo(self.node) for opt in self.text.keys(): self.text[opt].reparentTo(self.node)
def __createAnimationSequence__(self,name,sprite_images,sprites_time,is_left = False): """ Creates the sequence node that plays these images """ seq = SpriteSequencePlayer(name) for i in range(0,len(sprite_images)): txtr = sprite_images[i] w = txtr.getXSize() h = txtr.getYSize() # creating CardMaker to hold the texture cm = CardMaker(name + str(i)) cm.setFrame(0,w,-h,0 ) # This configuration places the image's topleft corner at the origin card = NodePath(cm.generate()) card.setTexture(txtr) seq.addChild(card.node(),i) seq.addFrame(card.node(),i,sprites_time[i]) # offseting image xoffset = float(txtr.axisx + (-w if is_left else 0)) yoffset = float(txtr.axisy) card.setPos(Vec3(xoffset,0,yoffset)) AnimationActor.LOGGER.debug("Animation %s Sprite [%i] image size %s and offset %s."%( name,i, str((w,h)), str((txtr.axisx,txtr.axisy)) ) ) return seq
def __init__(self, world, attach, name = '', position = Vec3(0,0,0), orientation = Vec3(0,0,0), size = (32, 32)): cm=CardMaker('') cm.setFrame(0,1,0,1) floor = render.attachNewNode(PandaNode("floor")) tex = loader.loadTexture('media/'+'ground.png') tex.setMagfilter(Texture.FTNearest) tex.setMinfilter(Texture.FTNearest) for y in range(size[0]): for x in range(size[1]): nn = floor.attachNewNode(cm.generate()) nn.setP(-90) nn.setPos((x), (y), 0) floor.setTexture(tex) floor.flattenStrong() myMaterial = Material() myMaterial.setShininess(0) #Make this material shiny myMaterial.setAmbient(VBase4(0.5,.5,.5,1)) #Make this material blue myMaterial.setDiffuse(VBase4(.5,.5,.5,1)) nn.setMaterial(myMaterial) shape = BulletPlaneShape(Vec3(0, 0, 1), 0) StaticWorldObject.__init__(self, world, attach, name, position, shape, orientation) ##Mass must be zero. self._nodePath.node().setFriction(1)
def __initSceneGraph(self): self.point_path = self.host_planet.point_path.attachNewNode("unit_center_node") self.model_path = self.point_path.attachNewNode("unit_node") self.model_path.reparentTo(self.point_path) self.model_path.setPos(Vec3(0,6,0)) self.model_path.setPythonTag('pyUnit', self) rad = 1 cnode = CollisionNode("coll_sphere_node") cnode.addSolid(CollisionBox(Point3(-rad,-rad,-rad),Point3(rad,rad,rad))) cnode.setIntoCollideMask(BitMask32.bit(1)) cnode.setTag('unit', str(id(self))) self.cnode_path = self.model_path.attachNewNode(cnode) #self.cnode_path.show() tex = loader.loadTexture("models/billboards/flare.png") cm = CardMaker('quad') cm.setFrameFullscreenQuad() self.quad_path = self.model_path.attachNewNode(cm.generate()) self.quad_path.setTexture(tex) self.quad_path.setTransparency(TransparencyAttrib.MAlpha) self.quad_path.setBillboardPointEye() self.quad_path.setColor(self.player.color)
def draw_image(self, image, box, identifier="", parameters=None): cm = CardMaker(identifier) tex = self.get_loader().loadTexture(image.value) if box.mode == "pixels": parent2d = self.get_parent_pixel2d() elif box.mode == "standard": parent2d = self.get_parent_render2d() elif box.mode == "aspect": parent2d = self.get_parent_aspect2d() node = NodePath(cm.generate()) node.setTexture(tex) if parameters is not None: if hasattr(parameters, "transparency") and parameters.transparency == True: node.setTransparency(TransparencyAttrib.MAlpha) node.setPos(box.x, 0, box.y + box.sizey) node.setScale(box.sizex, 1, -box.sizey) node.setBin("fixed", self.get_next_sortid()) node.setDepthTest(False) node.setDepthWrite(False) node.reparentTo(parent2d) return (node, image, box, parameters)
def __init__(self): ShowBase.__init__(self) cm = CardMaker('grass') cm.setFrame(-1, 1, -1, 1) grass1 = render.attachNewNode(cm.generate()) grass2 = render.attachNewNode(cm.generate()) grass1.setTexture(loader.loadTexture("data/env/grass1.png"), 1) grass2.setTexture(loader.loadTexture("data/env/grass2.png"), 1) grass1.setTransparency(True) grass2.setTransparency(True) grass1.setBillboardPointEye() grass2.setBillboardPointEye() grass1.setHpr(0, -40, 0) grass2.setHpr(0, -40, 0) grass1.setPos(0, 1, -0.4) grass2.setPos(0, 1, -0.3) self.taskMgr.add(self.panCameraTask, "PanCameraTask")
def makeCube(geom, x, y, z, scale=1.0, texpos=None, colors=False): """ Function that adds six cards to a GeomNode to form a cube geom: GeomNode to add cards to x, y, z: Position offset scale: Optional, Scale factor, cube is 1x1x1 by default texpos: Optional, Dictionary of tuples with texture co-ordinates Tuple has Point2 for top-left and Point2 for bottom-right Faces are "front", "back", "left", "right", "top", "bottom" colors: Optional, if True set different color for each face for debugging (see cardcolors) """ cardmaker = CardMaker("cardmaker") mycards = deepcopy(CARDS) for k, i in mycards.iteritems(): points = i for j in points: j += Point3(x, y, z) j *= scale cardmaker.setFrame(*points) if texpos: cardmaker.setUvRange(*texpos[k]) if colors: cardmaker.setColor(*CARDCOLORS[k]) geom.addGeomsFrom(cardmaker.generate())
def constructModel(self): self.obstacles = [] self.blocks = [] self.liftables = [] if self.nodePath != None: self.nodePath.removeNode() self.cards = [] self.nodePath = NodePath("Map") #the ground cm = CardMaker('CardMaker') cm.setFrame(-2,2,-2,2) card = self.nodePath.attachNewNode(cm.generate()) card.setTexture(tex) for y in range(self.height): for x in range(self.width): # TO DO: MUDAR NOME a = {"block": self.blocks, "obstacle": self.obstacles, "tree": self.obstacles, "bush" : self.obstacles, "liftable": self.liftables} tType = self.tileType(Map.COLLISION, (x,y)) if tType != 'free': a[tType].append(self.makeObject(tType, x,y))
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 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 _addCard(self,texture): tex = loader.loadTexture(MAIN_DIR+"/../assets/models/bamboo/"+texture) cm = CardMaker('card') ratio = float(tex.getXSize())/tex.getYSize() cm.setFrame(-0.5*ratio,0.5*ratio,-0.5,0.5) card = self.menuNP.attachNewNode(cm.generate()) card.setTexture(tex) return card
class TextureCard(visual): def setup(self): self.path.removeNode() self.path = self.render.attachNewNode("texturequad") self.path.setTransparency(TransparencyAttrib.MAlpha, 1) self.tex1 = self.loader.loadTexture("mandala1_transparent.png") self.tex2 = self.loader.loadTexture("dark1_transparent.png") self.tex3 = self.loader.loadTexture("dark2_transparent.png") self.tex4 = self.loader.loadTexture("truchet_transparent.png") self.plane = CardMaker("plane") self.card = self.path.attachNewNode(self.plane.generate()) self.cardNode = self.path.attachNewNode("texturecards") self.cards1 = [] for i in range(0, 100): self.cards1.append(self.cardNode.attachNewNode(self.plane.generate())) coords = range(-50,50) i = 0 for card in self.cards1: card.setPos(coords[i], 0, 0) i = i + 1 self.cardNode.detachNode() self.path.setTexture(self.tex1) self.path.setTwoSided(1) def effect1(self): self.path.setTexture(self.tex1) def effect2(self): self.path.setTexture(self.tex2) def effect3(self): self.path.setTexture(self.tex3) def effect4(self): self.path.setTexture(self.tex4) def effect5(self): self.cardNode.reparentTo(self.path)
def __init__(self, charid, sprite, camhandler, callback, cancelcallback): self.charid = charid self.sprite = sprite self.camhandler = camhandler self.callback = callback self.cancelcallback = cancelcallback self.initdir = self.sprite.realdir self.hidir = None # Textures self.readytex = loader.loadTexture(GAME+'/textures/gui/direction.png') self.readytex.setMagfilter(Texture.FTNearest) self.readytex.setMinfilter(Texture.FTNearest) self.hovertex = loader.loadTexture(GAME+'/textures/gui/direction_hover.png') self.hovertex.setMagfilter(Texture.FTNearest) self.hovertex.setMinfilter(Texture.FTNearest) # Sounds self.hover_snd = base.loader.loadSfx(GAME+'/sounds/hover.ogg') self.clicked_snd = base.loader.loadSfx(GAME+'/sounds/clicked.ogg') self.cancel_snd = base.loader.loadSfx(GAME+'/sounds/cancel.ogg') # Buttons list self.directionbuttons = [] # Buttons container self.directionRoot = sprite.node.attachNewNode( "directionRoot" ) directionsdata = [ { 'direction': '1', 'pos': ( 1.45, 0.0, 5) }, { 'direction': '2', 'pos': ( 0.0, 1.45, 5) }, { 'direction': '3', 'pos': (-1.45, 0.0, 5) }, { 'direction': '4', 'pos': ( 0.0,-1.45, 5) } ] for directiondata in directionsdata: cm = CardMaker('card') cm.setFrame(-.5, .5, -.5, .5) card = render.attachNewNode(cm.generate()) card.setTexture(self.readytex) card.setTransparency(True) card.setBillboardPointEye() card.reparentTo(self.directionRoot) card.setPos(directiondata['pos']) card.setScale(256.0/240.0) self.directionbuttons.append(card) if int(directiondata['direction']) == int(self.initdir): self.hidir = directiondata['direction'] card.setTexture(self.hovertex) self.accept("b", self.onCircleClicked) self.accept("space", self.onCrossClicked) self.accept("arrow_up", lambda: self.onArrowClicked('up')) self.accept("arrow_down", lambda: self.onArrowClicked('down')) self.accept("arrow_left", lambda: self.onArrowClicked('left')) self.accept("arrow_right", lambda: self.onArrowClicked('right'))
def _makeSquare(self): c = CardMaker("square") c.setFrame(-0.5, 0.5, -0.5, 0.5) self.square = NodePath(c.generate()) self.square.setShaderInput("font", self.fontTex) self.square.setShader(self.fontShader) self.square.setAttrib( TransparencyAttrib.make(TransparencyAttrib.MAlpha), 100) self.square.reparentTo(Globals.base.aspect2d) return self.square
def _create_components(self): """ Internal method to init the widgets components """ card_maker = CardMaker("PixelInspector") card_maker.set_frame(-200, 200, -150, 150) self._zoomer = self._node.attach_new_node(card_maker.generate()) # Defer the further loading Globals.base.taskMgr.doMethodLater( 1.0, self._late_init, "PixelInspectorLateInit") Globals.base.accept("q", self.show) Globals.base.accept("q-up", self.hide)
def loadImageAsPlane(self, filepath, yresolution = 600): tex = loader.loadTexture(filepath) # @UndefinedVariable tex.setBorderColor(Vec4(0,0,0,0)) tex.setWrapU(Texture.WMBorderColor) tex.setWrapV(Texture.WMBorderColor) cm = CardMaker(filepath + ' card') cm.setFrame(-tex.getOrigFileXSize(), tex.getOrigFileXSize(), -tex.getOrigFileYSize(), tex.getOrigFileYSize()) card = NodePath(cm.generate()) card.setTexture(tex) card.setScale(card.getScale()/ yresolution) card.flattenLight() # apply scale return card
class CardQuad(visual): def setup(self): self.path.removeNode() self.path = self.render.attachNewNode("Card Quad") self.plane = CardMaker("plane") self.plane.setFrame(-10,10,-10,10) self.left = self.path.attachNewNode(self.plane.generate()) self.right = self.path.attachNewNode(self.plane.generate()) self.up = self.path.attachNewNode(self.plane.generate()) self.down = self.path.attachNewNode(self.plane.generate()) self.front = self.path.attachNewNode(self.plane.generate()) self.back = self.path.attachNewNode(self.plane.generate()) self.left.setX(-10) self.right.setX(10) self.up.setZ(10) self.down.setZ(-10) self.left.setH(270) self.right.setH(90) self.up.setP(270) self.down.setP(90) self.front.setY(-10) self.back.setY(10) self.back.setH(180) self.tex = self.loader.loadTexture("indian_ornament_texture.png") self.path.setTexture(self.tex) self.path.setTransparency(TransparencyAttrib.MAlpha, 1) self.path.setTwoSided(1)
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) # Load the environment model. self.setup_environment() #self.scene = self.loader.loadModel("models/environment") # Reparent the model to render. #self.scene.reparentTo(self.render) # Apply scale and position transforms on the model. #self.scene.setScale(0.25, 0.25, 0.25) #self.scene.setPos(-8, 42, 0) # Needed for camera image self.dr = self.camNode.getDisplayRegion(0) # Needed for camera depth image winprops = WindowProperties.size(self.win.getXSize(), self.win.getYSize()) fbprops = FrameBufferProperties() fbprops.setDepthBits(1) self.depthBuffer = self.graphicsEngine.makeOutput( self.pipe, "depth buffer", -2, fbprops, winprops, GraphicsPipe.BFRefuseWindow, self.win.getGsg(), self.win) self.depthTex = Texture() self.depthTex.setFormat(Texture.FDepthComponent) self.depthBuffer.addRenderTexture(self.depthTex, GraphicsOutput.RTMCopyRam, GraphicsOutput.RTPDepth) lens = self.cam.node().getLens() lens.setFov(90.0, 90.0) # the near and far clipping distances can be changed if desired # lens.setNear(5.0) # lens.setFar(500.0) self.depthCam = self.makeCamera(self.depthBuffer, lens=lens, scene=self.render) self.depthCam.reparentTo(self.cam) # TODO: Scene is rendered twice: once for rgb and once for depth image. # How can both images be obtained in one rendering pass? self.render.setAntialias(AntialiasAttrib.MAuto) def setup_environment(self): # encapsulate some stuff # set up ambient lighting self.alight = AmbientLight('alight') self.alight.setColor(VBase4(0.1, 0.1, 0.1, 1)) self.alnp = self.render.attachNewNode(self.alight) self.render.setLight(self.alnp) # set up a point light self.plight = PointLight('plight') self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1)) self.plnp = self.render.attachNewNode(self.plight) self.plnp.setPos(0, 0, 100) self.render.setLight(self.plnp) # set up terrain model self.terr_material = Material() self.terr_material.setShininess(1.0) self.terr_material.setAmbient(VBase4(0, 0, 0, 0)) self.terr_material.setDiffuse(VBase4(1, 1, 1, 1)) self.terr_material.setEmission(VBase4(0, 0, 0, 0)) self.terr_material.setSpecular(VBase4(0, 0, 0, 0)) # general scaling self.trrHorzSc = 4.0 self.trrVertSc = 4.0 # was 4.0 # Create sky #terrctr = self.trrHorzSc*65.0 #self.setup_skybox(terrctr,800.0,2.0,0.3) self.skysphere = self.loader.loadModel("sky-forest/SkySphere.bam") self.skysphere.setBin('background', 1) self.skysphere.setDepthWrite(0) self.skysphere.reparentTo(self.render) # Load some textures self.grsTxtSc = 5 self.numTreeTexts = 7 # ground texture self.txtGrass = self.loader.loadTexture('tex/ground005.png') self.txtGrass.setWrapU(Texture.WM_mirror) self.txtGrass.setWrapV(Texture.WM_mirror) self.txtGrass.setMagfilter(Texture.FTLinear) self.txtGrass.setMinfilter(Texture.FTLinearMipmapLinear) # set up terrain texture stages self.TS1 = TextureStage('terrtext') self.TS1.setSort(0) self.TS1.setMode(TextureStage.MReplace) # Set up the GeoMipTerrain self.terrain = GeoMipTerrain("myDynamicTerrain") img = PNMImage(Filename('tex/bowl_height_map.png')) self.terrain.setHeightfield(img) self.terrain.setBruteforce(0) self.terrain.setAutoFlatten(GeoMipTerrain.AFMMedium) # Set terrain properties self.terrain.setBlockSize(32) self.terrain.setNear(50) self.terrain.setFar(500) self.terrain.setFocalPoint(self.camera) # Store the root NodePath for convenience self.root = self.terrain.getRoot() self.root.clearTexture() self.root.setTwoSided(0) self.root.setCollideMask(BitMask32.bit(0)) self.root.setSz(self.trrVertSc) self.root.setSx(self.trrHorzSc) self.root.setSy(self.trrHorzSc) self.root.setMaterial(self.terr_material) self.root.setTexture(self.TS1, self.txtGrass) self.root.setTexScale(self.TS1, self.grsTxtSc, self.grsTxtSc) offset = 0.5 * img.getXSize() * self.trrHorzSc - 0.5 self.root.setPos(-offset, -offset, 0) self.terrain.generate() self.root.reparentTo(self.render) # load tree billboards self.txtTreeBillBoards = [] for a in range(self.numTreeTexts): fstr = 'trees/tree' + '%03d' % (a + 991) self.txtTreeBillBoards.append( \ self.loader.loadTexture(fstr + '-color.png', fstr + '-opacity.png')) self.txtTreeBillBoards[a].setMinfilter( Texture.FTLinearMipmapLinear) #self.placePlantOnTerrain('trees',300,0,20,20,self.trrHorzSc,self.trrVertSc, \ # self.numTreeTexts,self.txtTreeBillBoards,'scene-def/trees.txt') self.setup_house() self.setup_vehicle() self.taskMgr.add(self.skysphereTask, "SkySphere Task") def setup_house(self): # place farmhouse on terrain self.house = ModelNode('house1') self.loadModelOntoTerrain(self.render, self.terrain, self.house, 43.0, 0.275, 0.0, 0.0, self.trrHorzSc, self.trrVertSc, 'models/FarmHouse', Vec3(0, 0, 0), Point3(-12.0567, -29.1724, 0.0837742), Point3(12.2229, 21.1915, 21.3668)) def setup_vehicle(self): # place HMMWV on terrain self.hmmwv = ModelNode('hmmwv1') self.loadModelOntoTerrain(self.render, self.terrain, self.hmmwv, 33.0, 1.0, 20.0, 24.0, self.trrHorzSc, self.trrVertSc, 'models/hmmwv', Vec3(0, -90, 0), Point3(-1.21273, -2.49153, -1.10753), Point3(1.21273, 2.49153, 1.10753)) def setup_skybox(self, terrctr=645.0, boxsz=1000.0, aspect=1.0, uplift=0.0): vsz = boxsz / aspect self.bckgtx = [] self.bckgtx.append(self.loader.loadTexture('sky/Back2.png')) self.bckgtx.append(self.loader.loadTexture('sky/Right2.png')) self.bckgtx.append(self.loader.loadTexture('sky/Front2.png')) self.bckgtx.append(self.loader.loadTexture('sky/Left2.png')) self.bckgtx.append(self.loader.loadTexture('sky/Up.png')) for a in range(4): self.bckg = CardMaker('bkcard') lr = Point3(0.5 * boxsz, 0.5 * boxsz, -0.5 * vsz) ur = Point3(0.5 * boxsz, 0.5 * boxsz, 0.5 * vsz) ul = Point3(-0.5 * boxsz, 0.5 * boxsz, 0.5 * vsz) ll = Point3(-0.5 * boxsz, 0.5 * boxsz, -0.5 * vsz) self.bckg.setFrame(ll, lr, ur, ul) self.bckg.setHasNormals(0) self.bckg.setHasUvs(1) #self.bckg.setUvRange(self.bckgtx[a]) bkcrd = self.render.attachNewNode(self.bckg.generate()) bkcrd.setTexture(self.bckgtx[a]) self.bckgtx[a].setWrapU(Texture.WMClamp) self.bckgtx[a].setWrapV(Texture.WMClamp) bkcrd.setLightOff() bkcrd.setFogOff() bkcrd.setHpr(90.0 * a, 0, 0) cz = 0.5 * boxsz * uplift #print 'set card at:', terrctr,terrctr,cz, ' with points: ', lr,ur,ul,ll bkcrd.setPos(terrctr, terrctr, cz) self.top = CardMaker('bkcard') lr = Point3(0.5 * boxsz, -0.5 * boxsz, 0) ur = Point3(0.5 * boxsz, 0.5 * boxsz, 0) ul = Point3(-0.5 * boxsz, 0.5 * boxsz, 0) ll = Point3(-0.5 * boxsz, -0.5 * boxsz, 0) self.top.setFrame(ll, lr, ur, ul) self.top.setHasNormals(0) self.top.setHasUvs(1) #self.top.setUvRange(self.bckgtx[4]) bkcrd = self.render.attachNewNode(self.bckg.generate()) bkcrd.setTexture(self.bckgtx[4]) self.bckgtx[4].setWrapU(Texture.WMClamp) self.bckgtx[4].setWrapV(Texture.WMClamp) bkcrd.setLightOff() bkcrd.setFogOff() bkcrd.setHpr(0, 90, 90) bkcrd.setPos(terrctr, terrctr, 0.5 * vsz + 0.5 * boxsz * uplift) def placePlantOnTerrain(self, itemStr, itemCnt, Mode, typItemWidth, typItemHeight, trrHorzSc, trrVertSc, numTxtTypes, txtList, planFileName): # Billboarding plants crd = CardMaker('mycard') crd.setColor(0.5, 0.5, 0.5, 1) ll = Point3(-0.5 * typItemWidth, 0, 0) lr = Point3(0.5 * typItemWidth, 0, 0) ur = Point3(0.5 * typItemWidth, 0, typItemHeight) ul = Point3(-0.5 * typItemWidth, 0, typItemHeight) crd.setFrame(ll, lr, ur, ul) crd.setHasNormals(False) crd.setHasUvs(True) # generate/save/load locations try: plan_data_fp = open(planFileName, 'r') item_list = [] for line in plan_data_fp: toks = line.split(',') px = float(toks[0].strip(' ')) py = float(toks[1].strip(' ')) ang = float(toks[2].strip(' ')) dht = float(toks[3].strip(' ')) scl = float(toks[4].strip(' ')) idx = int(toks[5].strip(' ')) item_list.append((px, py, ang, dht, scl, idx)) plan_data_fp.close() print 'loaded ', itemStr, ' data file of size:', len(item_list) except IOError: # generate list and try to save item_list = [] for a in range(itemCnt): px = random.randrange(-self.trrHorzSc * 64, self.trrHorzSc * 64) py = random.randrange(-self.trrHorzSc * 64, self.trrHorzSc * 64) ang = 180 * random.random() dht = 0.0 scl = 0.75 + 0.25 * (random.random() + random.random()) idx = random.randrange(0, numTxtTypes) item_list.append([px, py, ang, dht, scl, idx]) try: plan_data_fp = open(planFileName, 'w') for c in item_list: print >> plan_data_fp, c[0], ',', c[1], ',', c[2], ',', c[ 3], ',', c[4], ',', c[5] plan_data_fp.close() print 'saved ', itemStr, ' data of size: ', len(item_list) except IOError: print 'unable to store ', itemStr, ' data of size: ', len( item_list) # define each plant for c in item_list: px = c[0] py = c[1] ang = c[2] dht = c[3] scl = c[4] idx = c[5] if idx >= numTxtTypes: idx = 0 if Mode > 0: for b in range(Mode): crdNP = self.render.attachNewNode(crd.generate()) crdNP.setTexture(txtList[idx]) crdNP.setScale(scl) crdNP.setTwoSided(True) ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc) crdNP.setPos(px, py, ht * trrVertSc + dht) crdNP.setHpr(ang + (180 / Mode) * b, 0, 0) crdNP.setTransparency(TransparencyAttrib.MAlpha) crdNP.setLightOff() else: # set up item as defined crd.setUvRange(txtList[idx]) crdNP = self.render.attachNewNode(crd.generate()) crdNP.setBillboardAxis() crdNP.setTexture(txtList[idx]) crdNP.setScale(scl) ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc) crdNP.setPos(px, py, ht * trrVertSc) crdNP.setTransparency(TransparencyAttrib.MAlpha) crdNP.setLightOff() def loadModelOntoTerrain(self, render_node, terr_obj, model_obj, hdg, scl, xctr, yctr, terr_horz_sc, terr_vert_sc, model_path, rotA, minP, maxP): # load model onto terrain hdg_rads = hdg * math.pi / 180.0 model_obj = self.loader.loadModel(model_path) rotAll = rotA rotAll.setX(rotAll.getX() + hdg) model_obj.setHpr(rotA) model_obj.setLightOff() # if model changes, these will have to be recomputed # minP = Point3(0,0,0) # maxP = Point3(0,0,0) # model_obj.calcTightBounds(minP,maxP) print minP print maxP htl = [] maxzofs = -1000.0 for xi in [minP[0], maxP[0]]: for yi in [minP[1], maxP[1]]: tx = xctr + scl * xi * math.cos(hdg_rads) ty = yctr + scl * yi * math.sin(hdg_rads) tht = self.terrain.getElevation(tx / terr_horz_sc, ty / terr_horz_sc) print 'tx=', tx, ', ty=', ty, ', tht=', tht htl.append(tht * terr_vert_sc - minP.getZ()) for hi in htl: if hi > maxzofs: maxzofs = hi print maxzofs model_obj.setPos(xctr, yctr, maxzofs) model_obj.setHpr(rotAll) model_obj.setScale(scl) model_obj.reparentTo(render_node) return maxzofs, minP, maxP def get_camera_image(self, requested_format=None): """ Returns the camera's image, which is of type uint8 and has values between 0 and 255. The 'requested_format' argument should specify in which order the components of the image must be. For example, valid format strings are "RGBA" and "BGRA". By default, Panda's internal format "BGRA" is used, in which case no data is copied over. """ tex = self.dr.getScreenshot() if requested_format is None: data = tex.getRamImage() else: data = tex.getRamImageAs(requested_format) image = np.frombuffer( data.get_data(), np.uint8) # use data.get_data() instead of data in python 2 image.shape = (tex.getYSize(), tex.getXSize(), tex.getNumComponents()) image = np.flipud(image) return image def get_camera_depth_image(self): """ Returns the camera's depth image, which is of type float32 and has values between 0.0 and 1.0. """ data = self.depthTex.getRamImage() depth_image = np.frombuffer(data.get_data(), np.float32) depth_image.shape = (self.depthTex.getYSize(), self.depthTex.getXSize(), self.depthTex.getNumComponents()) depth_image = np.flipud(depth_image) ''' Surface position can be inferred by calculating backward from the depth buffer. Each pixel on the screen represents a ray from the camera into the scene, and the depth value in the pixel indicates a distance along the ray. Because of this, it is not actually necessary to store surface position explicitly - it is only necessary to store depth values. Of course, OpenGL does that for free. So the framebuffer now needs to store surface normal, diffuse color, and depth value (to infer surface position). In practice, most ordinary framebuffers can only store color and depth - they don't have any place to store a third value. So we need to use a special offscreen buffer with an "auxiliary" bitplane. The auxiliary bitplane stores the surface normal. So then, there's the final postprocessing pass. This involves combining the diffuse color texture, the surface normal texture, the depth texture, and the light parameters into a final rendered output. The light parameters are passed into the postprocessing shader as constants, not as textures. If there are a lot of lights, things get interesting. You use one postprocessing pass per light. Each pass only needs to scan those framebuffer pixels that are actually in range of the light in question. To traverse only the pixels that are affected by the light, just render the illuminated area's convex bounding volume. The shader to store the diffuse color and surface normal is trivial. But the final postprocessing shader is a little complicated. What makes it tricky is that it needs to regenerate the original surface position from the screen position and depth value. The math for that deserves some explanation. We need to take a clip-space coordinate and depth-buffer value (ClipX,ClipY,ClipZ,ClipW) and unproject it back to a view-space (ViewX,ViewY,ViewZ) coordinate. Lighting is then done in view-space. Okay, so here's the math. Panda uses the projection matrix to transform view-space into clip-space. But in practice, the projection matrix for a perspective camera always contains four nonzero constants, and they're always in the same place: -- here are the non-zero elements of the projection matrix -- A 0 0 0 0 0 B 1 0 C 0 0 0 0 D 0 -- precompute these from above projection matrix -- ''' proj = self.cam.node().getLens().getProjectionMat() proj_x = 0.5 * proj.getCell(3, 2) / proj.getCell(0, 0) proj_y = 0.5 * proj.getCell(3, 2) proj_z = 0.5 * proj.getCell(3, 2) / proj.getCell(2, 1) proj_w = -0.5 - 0.5 * proj.getCell(1, 2) ''' -- now for each pixel compute viewpoint coordinates -- viewx = (screenx * projx) / (depth + projw) viewy = (1 * projy) / (depth + projw) viewz = (screeny * projz) / (depth + projw) ''' grid = np.mgrid[0:depth_image.shape[0], 0:depth_image.shape[1]] ygrid = np.float32(np.squeeze( grid[0, :, :])) / float(depth_image.shape[0] - 1) ygrid -= 0.5 xgrid = np.float32(np.squeeze( grid[1, :, :])) / float(depth_image.shape[1] - 1) xgrid -= 0.5 xview = 2.0 * xgrid * proj_x zview = 2.0 * ygrid * proj_z denom = np.squeeze(depth_image) + proj_w xview = xview / denom yview = proj_y / denom zview = zview / denom sqrng = xview**2 + yview**2 + zview**2 range_image = np.sqrt(sqrng) range_image_1 = np.expand_dims(range_image, axis=2) return depth_image, range_image_1 def compute_sample_pattern(self, limg_shape, res_factor): # assume velocity is XYZ and we are looking +X up and towards -Z pattern = [] lens = self.cam.node().getLens() sx = self.win.getXSize() sy = self.win.getYSize() ifov_vert = 2.0 * math.tan( 0.5 * math.radians(lens.getVfov())) / float(sy - 1) ifov_horz = 2.0 * math.tan( 0.5 * math.radians(lens.getHfov())) / float(sx - 1) #ifov_vert = lens.getVfov() / float(sy-1) #ifov_horz = lens.getHfov() / float(sy-1) for ldr_row in range(limg_shape[0]): theta = -10.0 - 41.33 * ( float(ldr_row) / float(limg_shape[0] - 1) - 0.5) for ldr_col in range(limg_shape[1]): psi = 60.0 * (float(ldr_col) / float(limg_shape[1] - 1) - 0.5) cpsi = math.cos(math.radians(psi)) vert_ang = theta / cpsi img_row_flt = (0.5 * float(sy - 1) - (math.tan(math.radians(vert_ang)) / ifov_vert)) #img_row_flt = 0.5*(sy-1) - (vert_ang / ifov_vert) if img_row_flt < 0: print('img_row_flt=%f' % img_row_flt) img_row_flt = 0.0 if img_row_flt >= sy: print('img_row_flt=%f' % img_row_flt) img_row_flt = float(sy - 1) img_col_flt = (0.5 * float(sx - 1) + (math.tan(math.radians(psi)) / ifov_horz)) #img_col_flt = 0.5*(sx-1) + (psi / ifov_horz) if img_col_flt < 0: print('img_col_flt=%f' % img_col_flt) img_col_flt = 0.0 if img_col_flt >= sx: print('img_col_flt=%f' % img_col_flt) img_col_flt = float(sx - 1) pattern.append((ldr_row, ldr_col, img_row_flt, img_col_flt)) return pattern def find_sorted_ladar_returns(self, rangearr, intensarr, ks_m): my_range = rangearr.copy() my_inten = intensarr.copy() ''' pixels data is organized by: [0] starting range of this return [1] ending range of this return [2] peak range of this return [3] total intensity of this return ''' int_mult = len(my_inten) pixels = map( list, zip(my_range.tolist(), my_range.tolist(), my_range.tolist(), my_inten.tolist())) spix = sorted(pixels, key=lambda x: x[0]) done = False while not done: mxpi = len(spix) if mxpi > 2: mindel = 1e20 mnidx = None for pidx in range(mxpi - 1): rdel = spix[pidx + 1][0] - spix[pidx][1] # must be within ks_m meters in range to merge if (rdel < ks_m) and (rdel < mindel): mindel = rdel mnidx = pidx # merge best two returns if mnidx is not None: # new range span for testing against neighbors spix[mnidx][1] = spix[mnidx + 1][1] # new peak range is range of max contributor if spix[mnidx + 1][3] > spix[mnidx][3]: spix[mnidx][2] = spix[mnidx + 1][2] # intensity of return is sum of contributors spix[mnidx][3] += spix[mnidx + 1][3] # remove one of the two merged del spix[mnidx + 1] else: done = True else: done = True # now eliminate all but max and last returns max_idx = None max_val = 0.0 for ci, pix in enumerate(spix): if pix[3] > max_val: max_val = pix[3] / int_mult max_idx = ci # if they are the same, return only one if spix[-1][3] >= spix[max_idx][3]: return [spix[-1]] else: return [spix[max_idx], spix[-1]] def sample_range_image(self, rng_img, int_img, limg_shape, vel_cam, pps, ldr_err, pattern): # depth image is set up as 512 x 512 and is 62.5 degrees vertical FOV # the center row is vertical, but we want to sample from the # region corresponding to HDL-32 FOV: from +10 to -30 degrees detailed_sensor_model = False fwd_vel = vel_cam[1] beam_div = 0.002 lens = self.cam.node().getLens() #sx = self.win.getXSize() sy = self.win.getYSize() ifov_vert = 2.0 * math.tan( 0.5 * math.radians(lens.getVfov())) / float(sy - 1) #ifov_horz = 2.0*math.tan(0.5*math.radians(lens.getHfov()))/float(sx-1) #ifov = math.radians(self.cam.node().getLens().getVfov() / self.win.getYSize()) sigma = beam_div / ifov_vert hs = int(2.0 * sigma + 1.0) gprof = gauss_kern(sigma, hs, normalize=False) rimg = np.zeros(limg_shape, dtype=np.float32) iimg = np.zeros(limg_shape, dtype=np.float32) margin = 10.0 for pidx, relation in enumerate(pattern): # get the usual scan pattern sample ldr_row, ldr_col, img_row_flt, img_col_flt = relation if ((img_row_flt > -margin) and (img_col_flt > -margin) and (img_row_flt < rng_img.shape[0] + margin) and (img_col_flt < rng_img.shape[1] + margin)): # within reasonable distance from image limits img_row = int(round(img_row_flt)) img_col = int(round(img_col_flt)) # motion compensation trng = np.float32(rng_img[img_row, img_col]) if trng > 0.0: # TODO: change this back to False done = True ic = 0 while not done: old_trng = trng del_row = pidx * fwd_vel / (ifov_vert * trng * pps) if (abs(del_row) > 1e-1) and (ic < 10): img_row_f = img_row_flt + del_row img_row = int(round(img_row_f)) trng = np.float32(rng_img[img_row, img_col]) ic += 1 if abs(trng - old_trng) < 0.5: done = True else: done = True # simple sensor processing: just sample from large images rimg[ldr_row, ldr_col] = np.float32(rng_img[img_row, img_col]) iimg[ldr_row, ldr_col] = np.float32(int_img[img_row, img_col]) if detailed_sensor_model: # detailed model subsamples whole beam width gpatch = copy_patch_centered((img_row, img_col), hs, int_img, 0.0) gpatch = np.float32(gpatch) gpatch *= gprof rpatch = copy_patch_centered((img_row, img_col), hs, rng_img, 0.0) rpatch = np.squeeze(rpatch) valid = rpatch > 1e-3 if np.count_nonzero(valid) > 0: rpatch_ts = rpatch[valid] gpatch_ts = gpatch[valid] returns = self.find_sorted_ladar_returns( rpatch_ts, gpatch_ts, 2.5) # for now we just take first return rimg[ldr_row, ldr_col] = returns[0][2] iimg[ldr_row, ldr_col] = returns[0][3] else: rimg[ldr_row, ldr_col] = 0.0 iimg[ldr_row, ldr_col] = np.float32(int_img[img_row, img_col]) rimg += ldr_err * np.random.standard_normal(rimg.shape) return rimg, iimg def skysphereTask(self, task): if self.base is not None: self.skysphere.setPos(self.base.camera, 0, 0, 0) self.terrain.generate() return task.cont
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) self.stimtype = 'random image' # session_start self.session_start_time = datetime.datetime.now() # self.accept("escape", sys.exit, [0])#don't let the user do this, because then the data isn't saved. self.accept('q', self.close) self.accept('Q', self.close) self.upArrowIsPressed = base.mouseWatcherNode.isButtonDown(KeyboardButton.up()) self.downArrowIsPressed = base.mouseWatcherNode.isButtonDown(KeyboardButton.down()) self.rightArrowIsPressed = base.mouseWatcherNode.isButtonDown(KeyboardButton.right()) self.leftArrowIsPressed = base.mouseWatcherNode.isButtonDown(KeyboardButton.left()) self.AUTO_REWARD = AUTO_REWARD # disable mouse control so that we can place the camera base.disableMouse() camera.setPosHpr(0, 0, 10, 0, -90, 0) mat = Mat4(camera.getMat()) mat.invertInPlace() base.mouseInterfaceNode.setMat(mat) # base.enableMouse() props = WindowProperties() # props.setOrigin(0, 0) props.setFullscreen(True) props.setCursorHidden(True) props.setMouseMode(WindowProperties.M_relative) base.win.requestProperties(props) base.setBackgroundColor(0, 0, 0) # set the background color to black print('FULSCREEN:') print(props.getFullscreen()) print('=============') # set up the textures # we now get buffer thats going to hold the texture of our new scene altBuffer = self.win.makeTextureBuffer("hello", 1524, 1024) # altBuffer.getDisplayRegion(0).setDimensions(0.5,0.9,0.5,0.8) # altBuffer = base.win.makeDisplayRegion() # altBuffer.makeDisplayRegion(0,1,0,1) # now we have to setup a new scene graph to make this scene self.dr2 = base.win.makeDisplayRegion(0, 0.001, 0, 0.001)#make this really,really small so it's not seeable by the subject altRender = NodePath("new render") # this takes care of setting up ther camera properly self.altCam = self.makeCamera(altBuffer) self.dr2.setCamera(self.altCam) self.altCam.reparentTo(altRender) self.altCam.setPos(0, -10, 0) self.bufferViewer.setPosition("lrcorner") # self.bufferViewer.position = (-.1,-.4,-.1,-.4) self.bufferViewer.setCardSize(1.0, 0.0) print(self.bufferViewer.position) self.imagesTexture = MovieTexture("image_sequence") # success = self.imagesTexture.read("models/natural_images.avi") # success = self.imagesTexture.read("models/movie_5hz.mpg") self.imagesTexture.setPlayRate(1.0) self.imagesTexture.setLoopCount(10) # self.imageTexture =loader.loadTexture("models/NaturalImages/BSDs_8143.tiff") # self.imagesTexture.reparentTo(altRender) self.fixationPoint = OnscreenImage(image='models/fixationpoint.jpg', pos=(0, 0,0),scale=0.01) cm = CardMaker("stimwindow") cm.setFrame(-4, 4, -3, 3) # cm.setUvRange(self.imagesTexture) self.card = NodePath(cm.generate()) self.card.reparentTo(altRender) if self.stimtype == 'image_sequence': self.card.setTexture(self.imagesTexture, 1) # add the score display self.scoreLabel = OnscreenText(text='Current Score:', pos=(-1, 0.9), scale=0.1, fg=(0.8, 0.8, 0.8, 1)) self.scoreText = OnscreenText(text=str(0), pos=(-1, 0.76), scale=0.18, fg=(0, 1, 0, 1), shadow=(0.1, 1, 0.1, 0.5)) self.feebackScoreText = OnscreenText(text='+ ' + str(0), pos=(-0.5, 0.5), scale=0.3, fg=(0, 1, 0, 1), shadow=(0.1, 1, 0.1, 0.5)) self.feebackScoreText.setX(3.) # self.imagesTexture.play() # self.bufferViewer.setPosition("lrcorner") # self.bufferViewer.setCardSize(1.0, 0.0) self.accept("v", self.bufferViewer.toggleEnable) self.accept("V", self.bufferViewer.toggleEnable) # Load the tunnel self.initTunnel() # initialize some things # for the tunnel construction: self.boundary_to_add_next_segment = -1 * TUNNEL_SEGMENT_LENGTH self.current_number_of_segments = 8 # task flow booleans self.in_waiting_period = False self.stim_started = False self.looking_for_a_cue_zone = True self.in_reward_window = False self.show_stimulus = False # for task control self.interval = 0 self.time_waiting_in_cue_zone = 0 self.wait_time = 1.83 self.stim_duration = 0 # in seconds # self.distribution_type = np.random.uniform# # self.distribution_type_inputs = [0.016,0.4] #change the min & max stim duration times #New lines EAS: set weights higher for faster image durations self.durWeights = list() a = np.linspace(0.016,0.4,10) for i,j in enumerate(a): if j<0.1: p1 = 0.25 self.durWeights.append(p1) elif j > 0.1 and j < 0.21: p1 = 0.1 self.durWeights.append(p1) elif j> 0.21: p1 = 0.04 self.durWeights.append(p1) self.rng = np.random.default_rng() a = np.asarray(a) self.distribution_type_inputs = a #subset_size = len(p) #End new lines # self.distribution_type_inputs = [0.05,1.5] #can be anytong should match # self.distribution_type_inputs = [0.016,0.4] #change the min & max stim duration times # self.distribution_type_inputs = [0.016,0.4, 10] #change the min & max stim duration times self.max_stim_duration = 1.0 # in seconds self.stim_elapsed = 0.0 # in seconds self.last_position = base.camera.getZ() self.position_on_track = base.camera.getZ() # for reward control self.reward_window = REWARD_WINDOW # in seconds self.reward_elapsed = 0.0 # self.new_dt = list() # self.reward_volume = 0.008 # in mL. this is for the hardcoded 0.1 seconds of reward time self.reward_volume = int(REWARD_VOLUME) # in uL, for the stepper motor self.reward_time = 0.1 # in sec, based on volume. hard coded right now but should be modified by the (1) calibration and (2) optionally by the main loop for dynamic reward scheduling # self.lick_buffer = [] self.current_score = 0 self.score = 0 self.feedback_score_startime = -2 # INITIALIZE NIDAQ self.nidevice = 'Dev2' self.encodervinchannel = 1 self.encodervsigchannel = 0 self.invertdo = False self.diport = 1 self.lickline = 1 self.doport = 0 self.rewardline = 0 self.rewardlines = [0] self.encoder_position_diff = 0 if have_nidaq: self._setupDAQ() self.do.WriteBit(1, 1) self.do.WriteBit(3, 1) # set reward high, because the logic is flipped somehow. possibly by haphazard wiring of the circuit (12/24/2018 djd) self.previous_encoder_position = self.ai.data[0][self.encodervsigchannel] else: self.previous_encoder_position = 0 self.encoder_gain = 3 # INITIALIZE LICK SENSOR self._lickSensorSetup() # INITIALIZE output data self.lickData = [] self.x = [] self.t = [] self.trialData = [] self.reactionTimeData = [] self.rewardData = [] self.rightKeyData = [] self.leftKeyData = [] self.imageData = [] self.imageTimeData = [] self.scoreData = [] self.trialDurationData = [] self.new_dt = [] # INITIALIZE KEY SENSOR, for backup inputs and other user controls self.keys = key.KeyStateHandler() self.accept('r', self._give_reward, [self.reward_volume]) self.accept('l', self._toggle_reward) # initialize the image list and populate what images you want included # self.img_list = glob.glob('models/2AFC_IMAGES_HUMAN/*.tif') # self.img_list = glob.glob('models/2AFC_IMAGES_HUMAN2/*.tif') # self.img_list = glob.glob('/Users/elizabethstubblefield/Desktop/cheetah_or_elephant/composite_images/masks/all_same_num_ea/*.tif') #Newest images self.img_list = glob.glob('models/all_same_ea/*.tif') #Newest images #No longer hard-coded: self.original_indices = [0,0] #this was manually counted... first number must was the index of the first easy img; was [43, -18] for ndx, name in enumerate(self.img_list): if 'Cheetah255' in name: self.original_indices[0] = ndx elif 'Elephant0' in name: self.original_indices[1] = ndx # print(self.img_list) # self.original_indices = [43,-18] #manually counted, grump #Problematic w/out at least 43 images in the folder self.imageTextures =[loader.loadTexture(img) for img in self.img_list] self.img_id = None #this variable is used so we know which stimulus is being presented self.img_mask = None #this tells us what the image mask being presented is # self._setupEyetracking() # self._startEyetracking() if AUTO_MODE: self.gameTask = taskMgr.add(self.autoLoop2, "autoLoop2") self.rewardTask = taskMgr.add(self.rewardControl, "reward") self.cue_zone = concatenate((self.cue_zone, arange( \ self.current_number_of_segments * -TUNNEL_SEGMENT_LENGTH-50, \ self.current_number_of_segments * -TUNNEL_SEGMENT_LENGTH - TUNNEL_SEGMENT_LENGTH - 100, \ -1))) self.auto_position_on_track = 0 self.auto_restart = False self.auto_running = True self.contTunnel() else: # Now we create the task. taskMgr is the task manager that actually # calls the function each frame. The add method creates a new task. # The first argument is the function to be called, and the second # argument is the name for the task. It returns a task object which # is passed to the function each frame. self.gameTask = taskMgr.add(self.gameLoop, "gameLoop") # self.stimulusTask = taskMgr.add(self.stimulusControl, "stimulus") self.lickTask = taskMgr.add(self.lickControl, "lick") self.rewardTask = taskMgr.add(self.rewardControl, "reward") self.keyTask = taskMgr.add(self.keyControl, "Key press")
class NodeEditor(DirectObject): def __init__(self, parent, customNodeMap={}, customExporterMap={}): DirectObject.__init__(self) fn = Filename.fromOsSpecific(os.path.dirname(__file__)) fn.makeTrueCase() self.icon_dir = str(fn) + "/" loadPrcFileData("", f"model-path {self.icon_dir}") # # NODE VIEW # self.viewNP = aspect2d.attachNewNode("viewNP") self.viewNP.setScale(0.5) # # NODE MANAGER # self.nodeMgr = NodeManager(self.viewNP, customNodeMap) # Drag view self.mouseSpeed = 1 self.mousePos = None self.startCameraMovement = False # Box select # variables to store the start and current pos of the mousepointer self.startPos = LPoint2f(0, 0) self.lastPos = LPoint2f(0, 0) # variables for the to be drawn box self.boxCardMaker = CardMaker("SelectionBox") self.boxCardMaker.setColor(1, 1, 1, 0.25) self.box = None # # MENU BAR # self.mainView = MainView(parent, customNodeMap, customExporterMap) self.enable_editor() # ------------------------------------------------------------------ # FRAME COMPATIBILITY FUNCTIONS # ------------------------------------------------------------------ def is_dirty(self): """ This method returns True if an unsaved state of the editor is given """ return len(self.nodeMgr.getAllNodes()) > 0 def enable_editor(self): """ Enable the editor. """ self.enable_events() # Task for handling dragging of the camera/view taskMgr.add(self.updateCam, "NodeEditor_task_camActualisation", priority=-4) self.viewNP.show() self.nodeMgr.showConnections() def disable_editor(self): """ Disable the editor. """ self.ignore_all() taskMgr.remove("NodeEditor_task_camActualisation") self.viewNP.hide() self.nodeMgr.hideConnections() def do_exception_save(self): """ Save content of editor if the application crashes """ Save(self.nodeMgr.nodeList, self.nodeMgr.connections, True) # ------------------------------------------------------------------ # NODE EDITOR RELATED EVENTS # ------------------------------------------------------------------ def enable_events(self): # Add nodes self.accept("addNode", self.nodeMgr.addNode) # Remove nodes self.accept("NodeEditor_removeNode", self.nodeMgr.removeNode) self.accept("x", self.nodeMgr.removeNode) self.accept("delete", self.nodeMgr.removeNode) # Selecting self.accept("selectNode", self.nodeMgr.selectNode) # Deselecting self.accept("mouse3", self.nodeMgr.deselectAll) # Node Drag and Drop self.accept("dragNodeStart", self.setDraggedNode) self.accept("dragNodeMove", self.updateNodeMove) self.accept("dragNodeStop", self.updateNodeStop) # Duplicate/Copy nodes self.accept("shift-d", self.nodeMgr.copyNodes) self.accept("NodeEditor_copyNodes", self.nodeMgr.copyNodes) # Refresh node logics self.accept("ctlr-r", self.nodeMgr.updateAllLeaveNodes) self.accept("NodeEditor_refreshNodes", self.nodeMgr.updateAllLeaveNodes) # # SOCKET RELATED EVENTS # self.accept("updateConnectedNodes", self.nodeMgr.updateConnectedNodes) # Socket connection with drag and drop self.accept("startPlug", self.nodeMgr.setStartPlug) self.accept("endPlug", self.nodeMgr.setEndPlug) self.accept("connectPlugs", self.nodeMgr.connectPlugs) self.accept("cancelPlug", self.nodeMgr.cancelPlug) # Draw line while connecting sockets self.accept("startLineDrawing", self.startLineDrawing) self.accept("stopLineDrawing", self.stopLineDrawing) # # CONNECTION RELATED EVENTS # self.accept("NodeEditor_updateConnections", self.nodeMgr.updateConnections) # # PROJECT MANAGEMENT # self.accept("NodeEditor_new", self.newProject) self.accept("NodeEditor_save", self.saveProject) self.accept("NodeEditor_load", self.loadProject) self.accept("quit_app", exit) # # EXPORTERS # self.accept("NodeEditor_customSave", self.customExport) # # EDITOR VIEW # # Zooming self.accept("NodeEditor_zoom", self.zoom) self.accept("NodeEditor_zoom_reset", self.zoomReset) self.accept("wheel_up", self.zoom, [True]) self.accept("wheel_down", self.zoom, [False]) # Drag view self.accept("mouse2", self.setMoveCamera, [True]) self.accept("mouse2-up", self.setMoveCamera, [False]) # Box select # accept the 1st mouse button events to start and stop the draw self.accept("mouse1", self.startBoxDraw) self.accept("mouse1-up", self.stopBoxDraw) # ------------------------------------------------------------------ # PROJECT FUNCTIONS # ------------------------------------------------------------------ def newProject(self): self.nodeMgr.cleanup() def saveProject(self): Save(self.nodeMgr.nodeList, self.nodeMgr.connections) def loadProject(self): self.nodeMgr.cleanup() Load(self.nodeMgr) def customExport(self, exporter): exporter(self.nodeMgr.nodeList, self.nodeMgr.connections) # ------------------------------------------------------------------ # CAMERA SPECIFIC FUNCTIONS # ------------------------------------------------------------------ def setMoveCamera(self, moveCamera): """Start dragging around the editor area/camera""" # store the mouse position if weh have a mouse if base.mouseWatcherNode.hasMouse(): x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() self.mousePos = Point2(x, y) # set the variable according to if we want to move the camera or not self.startCameraMovement = moveCamera def updateCam(self, task): """Task that will move the editor area/camera around according to mouse movements""" # variables to store the mouses current x and y position x = 0.0 y = 0.0 if base.mouseWatcherNode.hasMouse(): # get the mouse position x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() if base.mouseWatcherNode.hasMouse() \ and self.mousePos is not None \ and self.startCameraMovement: # Move the viewer node aspect independent wp = base.win.getProperties() aspX = 1.0 aspY = 1.0 wpXSize = wp.getXSize() wpYSize = wp.getYSize() if wpXSize > wpYSize: aspX = wpXSize / float(wpYSize) else: aspY = wpYSize / float(wpXSize) mouseMoveX = (self.mousePos.getX() - x) / self.viewNP.getScale( ).getX() * self.mouseSpeed * aspX mouseMoveY = (self.mousePos.getY() - y) / self.viewNP.getScale( ).getZ() * self.mouseSpeed * aspY self.mousePos = Point2(x, y) self.viewNP.setX(self.viewNP, -mouseMoveX) self.viewNP.setZ(self.viewNP, -mouseMoveY) self.nodeMgr.updateConnections() # continue the task until it got manually stopped return task.cont def zoom(self, zoomIn): """Zoom the editor in or out dependent on the value in zoomIn""" zoomFactor = 0.05 maxZoomIn = 2 maxZoomOut = 0.1 if zoomIn: s = self.viewNP.getScale() if s.getX() - zoomFactor < maxZoomIn and s.getY( ) - zoomFactor < maxZoomIn and s.getZ() - zoomFactor < maxZoomIn: self.viewNP.setScale(s.getX() + zoomFactor, s.getY() + zoomFactor, s.getZ() + zoomFactor) else: s = self.viewNP.getScale() if s.getX() - zoomFactor > maxZoomOut and s.getY( ) - zoomFactor > maxZoomOut and s.getZ() - zoomFactor > maxZoomOut: self.viewNP.setScale(s.getX() - zoomFactor, s.getY() - zoomFactor, s.getZ() - zoomFactor) self.nodeMgr.updateConnections() def zoomReset(self): """Set the zoom level back to the default""" self.viewNP.setScale(0.5) self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # DRAG LINE # ------------------------------------------------------------------ def startLineDrawing(self, startPos): """Start a task that will draw a line from the given start position to the cursor""" self.line = LineNodePath(render2d, thickness=2, colorVec=(0.8, 0.8, 0.8, 1)) self.line.moveTo(startPos) t = taskMgr.add(self.drawLineTask, "drawLineTask") t.startPos = startPos def drawLineTask(self, task): """Draws a line from a given start position to the cursor""" mwn = base.mouseWatcherNode if mwn.hasMouse(): pos = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) self.line.reset() self.line.moveTo(task.startPos) self.line.drawTo(pos) self.line.create() return task.cont def stopLineDrawing(self): """Stop the task that draws a line to the cursor""" taskMgr.remove("drawLineTask") if self.line is not None: self.line.reset() self.line = None # ------------------------------------------------------------------ # EDITOR NODE DRAGGING UPDATE # ------------------------------------------------------------------ def setDraggedNode(self, node): """This will set the node that is currently dragged around as well as update other selected nodes which will be moved in addition to the main dragged node""" self.draggedNode = node self.draggedNode.disable() self.tempNodePositions = {} for node in self.nodeMgr.selectedNodes: self.tempNodePositions[node] = node.frame.getPos(render2d) def updateNodeMove(self, mouseA, mouseB): """Will be called as long as a node is beeing dragged around""" for node in self.nodeMgr.selectedNodes: if node is not self.draggedNode and node in self.tempNodePositions.keys( ): editVec = Vec3(self.tempNodePositions[node] - mouseA) newPos = mouseB + editVec node.frame.setPos(render2d, newPos) self.nodeMgr.updateConnections() def updateNodeStop(self, node=None): """Will be called when a node dragging stopped""" self.draggedNode.enable() self.draggedNode = None self.tempNodePositions = {} self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # SELECTION BOX # ------------------------------------------------------------------ def startBoxDraw(self): """Start drawing the box""" if base.mouseWatcherNode.hasMouse(): # get the mouse position self.startPos = LPoint2f(base.mouseWatcherNode.getMouse()) taskMgr.add(self.dragBoxDrawTask, "dragBoxDrawTask") def stopBoxDraw(self): """Stop the draw box task and remove the box""" if not taskMgr.hasTaskNamed("dragBoxDrawTask"): return taskMgr.remove("dragBoxDrawTask") if self.startPos is None or self.lastPos is None: return self.nodeMgr.deselectAll() if self.box is not None: for node in self.nodeMgr.getAllNodes(): # store some view scales for calculations viewXScale = self.viewNP.getScale().getX() viewZScale = self.viewNP.getScale().getZ() # calculate the node edges nodeLeft = node.getLeft() * viewXScale nodeRight = node.getRight() * viewXScale nodeBottom = node.getBottom() * viewZScale nodeTop = node.getTop() * viewZScale # calculate bounding box edges left = min(self.lastPos.getX(), self.startPos.getX()) right = max(self.lastPos.getX(), self.startPos.getX()) top = max(self.lastPos.getY(), self.startPos.getY()) bottom = min(self.lastPos.getY(), self.startPos.getY()) # check for hits xGood = yGood = False if left < nodeLeft and right > nodeLeft: xGood = True elif left < nodeRight and right > nodeRight: xGood = True if top > nodeTop and bottom < nodeTop: yGood = True elif top > nodeBottom and bottom < nodeBottom: yGood = True # check if we have any hits if xGood and yGood: self.nodeMgr.selectNode(node, True, True) # Cleanup the selection box self.box.removeNode() self.startPos = None self.lastPos = None def dragBoxDrawTask(self, task): """This task will track the mouse position and actualize the box's size according to the first click position of the mouse""" if base.mouseWatcherNode.hasMouse(): if self.startPos is None: self.startPos = LPoint2f(base.mouseWatcherNode.getMouse()) # get the current mouse position self.lastPos = LPoint2f(base.mouseWatcherNode.getMouse()) else: return task.cont # check if we already have a box if self.box != None: # if so, remove that old box self.box.removeNode() # set the box's size self.boxCardMaker.setFrame(self.lastPos.getX(), self.startPos.getX(), self.startPos.getY(), self.lastPos.getY()) # generate, setup and draw the box node = self.boxCardMaker.generate() self.box = render2d.attachNewNode(node) self.box.setBin("gui-popup", 25) self.box.setTransparency(TransparencyAttrib.M_alpha) # run until the task is manually stopped return task.cont
class ZoneMaker(DirectObject): def __init__(self, player, scene, playerHand, enemyHand, playerBoard, enemyBoard, playerFace, enemyFace, playerGraveyard, enemyGraveyard): self.player = player self.playerHand = playerHand self.enemyHand = enemyHand self.playerBoard = playerBoard self.enemyBoard = enemyBoard self.playerFace = playerFace self.enemyFace = enemyFace self.playerGraveyard = playerGraveyard self.enemyGraveyard = enemyGraveyard self.scene = scene base.playerIconPath = base.player.iconPath base.enemyIconPath = base.enemy.iconPath base.playerCardBack = base.player.cardBack base.enemyCardBack = base.enemy.cardBack for name in ['mulliganHand', 'orphan']: setattr(self, name, self.scene.attachNewNode(name)) self.mulliganHand.reparentTo(base.camera) self.makePlayerFace() self.makeEnemyFace() # For showing a big version of a card on mouse over self.focusedCard = base.camera.attachNewNode('focused card') self.focusedCard.setPos(-0.5, 6, -0.3) for c in base.player.referenceDeck + base.enemy.referenceDeck: c.pandaNode = None self.lockMaker = CardMaker("lock icon") self.lockIcons = [] base.taskMgr.add(self.resizeMulliganHandTask, 'ResizeMulliganHand') def addHandCard(self, card, tr, parent=None): if parent is None: parent = self.playerHand cardModel = self.loadCard(card) cardModel.reparentTo(parent) cardModel.setPosHprScale(*tr, 1, 1, 1) cardModel.setPythonTag('zone', base.player.hand) def makeMulliganHand(self): """ Draw the player's hand for mulligan """ cleanup(self.mulliganHand) posX = 0 for c in base.player.hand: self.addHandCard(c, (posX, 0, 0, 0, 0, 0), self.mulliganHand) if c in base.toMulligan: hideCard(c.pandaNode) else: showCard(c.pandaNode) posX += 1.1 def resizeMulliganHandTask(self, task): if self.player.hasMulliganed: return Task.done ratio = base.camLens.getAspectRatio() scale = max(ratio * 1.05, 1) self.mulliganHand.setPosHpr( -1.1 * (len(base.player.hand) - 1) / 2 * scale, 12, 0, 0, 0, 0) self.mulliganHand.setScale(scale, 1, scale) return Task.cont def makePlayerHand(self): """ Redraw the player's hand. """ self.mulliganHand.stash() # Destroy entire hand. This is slow and may need to be changed # cleanup(self.playerHand) for node in self.playerHand.children: node.removeNode() fan = fanHand(len(base.player.hand)) for i, tr in enumerate(fan): self.addHandCard(base.player.hand[i], tr) def makeEnemyHand(self): for node in self.enemyHand.children: node.removeNode() def addEnemyHandCard(card, tr): if card.visible: cardModel = self.loadCard(card) else: cardModel = self.loadEnemyBlank(card) cardModel.setPosHpr(*tr) cardModel.setPythonTag('zone', base.enemy.hand) cardModel.reparentTo(self.enemyHand) fan = fanHand(len(base.enemy.hand)) for i, tr in enumerate(fan): addEnemyHandCard(base.enemy.hand[i], tr) def makeLockIcon(self, card): lockModel = self.playerBoard.attachNewNode(self.lockMaker.generate()) tex = loader.loadTexture("padlock.png") lockModel.setTexture(tex) lockModel.setPos(card, -0.5, 0, 1) lockModel.setHpr(base.camera, 0, 0, 0) self.lockIcons.append(lockModel) def makeBoard(self): """ Show the player's faceups and facedowns """ cleanup(self.playerBoard) width = 1.1 * (len(base.player.faceups) + len(base.player.facedowns)) posX = 0.55 - width / 2 def addFaceupCard(card): cardModel = self.loadCard(card) cardModel.reparentTo(self.playerBoard) cardModel.setPosHpr(posX, 0, 0, 0, 0, 0) cardModel.setPythonTag('zone', base.player.faceups) def addFdCard(card): cardModel = self.loadCard(card) cardModel.reparentTo(self.playerBoard) cardModel.setPosHpr(posX, 0, 0, 0, 0, 0) cardModel.setPythonTag('zone', base.player.facedowns) if not card.stale: self.makeLockIcon(cardModel) hideCard(cardModel) for c in base.player.faceups: addFaceupCard(c) posX += 1.1 for c in base.player.facedowns: addFdCard(c) posX += 1.1 def makeEnemyBoard(self): cleanup(self.enemyBoard) for n in self.enemyBoard.children: n.reparentTo(self.orphan) width = 1.1 * (len(base.enemy.faceups) + len(base.enemy.facedowns)) posX = 0.55 - width / 2 def addEnemyFdCard(card): if card.visible: cardModel = self.loadCard(card) hideCard(cardModel) else: cardModel = self.loadEnemyBlank(card) cardModel.reparentTo(self.enemyBoard) cardModel.setPosHpr(posX, 0, 0, 0, 0, 0) cardModel.setPythonTag('zone', base.enemy.facedowns) if not card.stale: self.makeLockIcon(cardModel) def addEnemyFaceupCard(card): cardModel = self.loadCard(card) cardModel.reparentTo(self.enemyBoard) cardModel.setPosHpr(posX, 0, 0, 0, 0, 0) cardModel.setPythonTag('zone', base.enemy.faceups) for c in base.enemy.faceups: addEnemyFaceupCard(c) posX += 1.1 for c in base.enemy.facedowns: addEnemyFdCard(c) posX += 1.1 def makePlayerGraveyard(self): # Show only the top card for now if len(base.player.graveyard) > 0: cleanup(self.playerGraveyard) c = self.loadCard(base.player.graveyard[-1]) showCard(c) c.setPythonTag('zone', base.player.graveyard) c.reparentTo(self.playerGraveyard) c.setPosHpr(0, 0, 0, 0, 0, 0) for c1 in base.player.graveyard[:-1]: if c1.pandaNode is not None: c1.pandaNode.removeNode() c1.pandaNode = None def makeEnemyGraveyard(self): if len(base.enemy.graveyard) > 0: cleanup(self.enemyGraveyard) c = self.loadCard(base.enemy.graveyard[-1]) showCard(c) c.setPythonTag('zone', base.enemy.graveyard) c.reparentTo(self.enemyGraveyard) c.setPosHpr(0, 0, 0, 0, 0, 0) for c1 in base.enemy.graveyard[:-1]: if c1.pandaNode is not None: c1.pandaNode.removeNode() c1.pandaNode = None def focusCard(self, card): """ Draws a big version of the card so the player can read the text easily. """ # If the node path is pointing to the right card, don't rebuild if (card != self.focusedCard and card.getPythonTag('_zone') is not self.focusedCard.getTag('_zone')): self.focusedCard.unstash() if len(self.focusedCard.children) > 0: self.focusedCard.children[0].removeNode() oldCard = self.focusedCard.getPythonTag('oldCard') if oldCard: oldCard.show() # Make a duplicate of the node. Actually a different node path # pointing to the same node copy = card.copyTo(card.getParent()) if card.getPythonTag('zone') is base.player.hand: copy.setPos(card, 0, -0.2, 1) copy.setHpr(0, 0, 0) copy.setScale(2.5) copy.wrtReparentTo(self.focusedCard) self.focusedCard.setPythonTag('oldCard', card) card.hide() elif card.getPythonTag('zone') is base.enemy.hand: copy.setPos(card, 0, -0.2, 0) copy.setHpr(0, 0, 0) copy.setScale(2.5) copy.wrtReparentTo(self.focusedCard) self.focusedCard.setPythonTag('oldCard', card) card.hide() elif card.getPythonTag('zone') is base.enemy.graveyard: # Don't get cut off by top of screen copy.wrtReparentTo(self.focusedCard) copy.setPos(copy, 1.5, -1, -2) copy.setHpr(0, 0, 0) copy.setScale(2.5) else: copy.wrtReparentTo(self.focusedCard) copy.setPos(copy, 1.5, -1, 1) copy.setHpr(0, 0, 0) copy.setScale(2.5) # Don't try to play this self.focusedCard.setCollideMask(BitMask32(0x0)) # Keep track of the zone to know if it's changed # _zone rather than zone so MouseHandler will grab the card under it self.focusedCard.setPythonTag('_zone', card.getPythonTag('zone')) def unfocusCard(self): # Stash the enlarged card image so it won't collide or be visible. # This is different from using hide() because it also prevents # collision. self.focusedCard.stash() c = self.focusedCard.getPythonTag('oldCard') if c: c.show() def loadCard(self, card): if card.pandaNode is not None: showCard(card.pandaNode) cardBuilder.updateCard(card) return card.pandaNode return cardBuilder.buildCard(card, self.scene) def loadEnemyBlank(self, card): if card.pandaNode is not None: return card.pandaNode return cardBuilder.buildBlankCard(card, self.scene) def makePlayerFace(self): cm = CardMaker("face") cardModel = self.playerFace.attachNewNode(cm.generate()) path = base.playerIconPath + "/" + base.playerCardBack tex = loader.loadTexture(path) cardModel.setTexture(tex) self.playerFace.setPythonTag('zone', base.player.face) cardModel.setPos(-0.5, 0, -0.5) base.playerFaceNode = cardModel base.playerFaceNode.setCollideMask(cardBuilder.cardCollisionMask) def makeEnemyFace(self): cm = CardMaker("face") cardModel = self.enemyFace.attachNewNode(cm.generate()) path = base.enemyIconPath + "/" + base.enemyCardBack tex = loader.loadTexture(path) cardModel.setTexture(tex) self.enemyFace.setPythonTag('zone', base.enemy.face) cardModel.setPos(-0.5, 0, -0.5) base.enemyFaceNode = cardModel # Want it to be possible to click on enemy face base.enemyFaceNode.setCollideMask(cardBuilder.cardCollisionMask) def redrawAll(self): if self.player.hasMulliganed: self.makePlayerHand() else: self.makeMulliganHand() self.makeBoard() self.makeEnemyHand() self.makeEnemyBoard() self.makePlayerGraveyard() self.makeEnemyGraveyard() for n in self.orphan.children: n.removeNode() def unmake(self): self.playerHand.removeNode() # In case it's parented to the camera self.mulliganHand.removeNode() base.taskMgr.remove('ResizeMulliganHand')
def __init__(self): ShowBase.__init__(self) self.t = 0 self.starttime = None self.setFrameRateMeter(True) cour = self.loader.loadFont('cmtt12.egg') self.textObject = OnscreenText(font=cour, text='abcdefghijklmnopqrstuvwxyz', pos=(0, -0.045), parent=self.a2dTopCenter, bg=(0, 0, 0, 0.5), fg=(1, 1, 1, 1), scale=0.07, mayChange=True) cm = CardMaker("ground") cm.setFrame(-2000, 2000, -2000, 2000) cm.setUvRange(Point2(-2000 / 5, -2000 / 5), Point2(2000 / 5, 2000 / 5)) tmp = self.render.attachNewNode(cm.generate()) tmp.reparentTo(self.render) self.camLens.setNear(0.1) tmp.setPos(0, 0, 0) tmp.lookAt((0, 0, -2)) tmp.setColor(1.0, 1.0, 1.0, 0.) #tmp.setTexScale(TextureStage.getDefault(), 1, 1) tex = self.loader.loadTexture('textures/grid2.png') tex.setWrapU(Texture.WMRepeat) tex.setWrapV(Texture.WMRepeat) tmp.setTexture(tex, 1) self.setBackgroundColor(0.0, 191.0 / 255.0, 1.0, 1.0) #color of the sky ambientLight = AmbientLight('ambientLight') ambientLight.setColor(Vec4(0.2, 0.2, 0.2, 1)) ambientLightNP = self.render.attachNewNode(ambientLight) self.render.setLight(ambientLightNP) # Directional light 01 directionalLight = DirectionalLight('directionalLight') directionalLight.setColor(Vec4(0.8, 0.8, 0.8, 1)) directionalLightNP = self.render.attachNewNode(directionalLight) # This light is facing backwards, towards the camera. directionalLightNP.setHpr(-120, -50, 0) directionalLightNP.node().setScene(self.render) directionalLightNP.node().setShadowCaster(True) directionalLightNP.node().getLens().setFov(40) directionalLightNP.node().getLens().setNearFar(10, 100) self.render.setLight(directionalLightNP) # Add the spinCameraTask procedure to the task manager. self.taskMgr.add(self.spinCameraTask, "SpinCameraTask") self.physics = TheanoRigid3DBodyEngine() self.benchmark_physics = None #Rigid3DBodyEngine() # Load the environment model. self.objects = dict() #self.load_robot_model("robotmodel/test.json") self.load_robot_model("robotmodel/predator.json") #self.load_robot_model("robotmodel/simple_predator.json") if self.benchmark_physics: self.benchmark_physics.compile() print "Compiling..." self.positions, self.velocities, self.rotations = self.physics.getInitialState( ) self.physics.compile() import theano.tensor as T positions = T.fmatrix() velocities = T.fmatrix() rotations = T.ftensor3() a, b, c = self.physics.step_from_this_state( (positions, velocities, rotations), dt=0.001, motor_signals=[-1, 1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) self.timestep = theano.function( inputs=[positions, velocities, rotations], outputs=[a, b, c], allow_input_downcast=True)
def __init__(self, name, spritesheet=None, sprite_size=None, hitbox_size=None, collision_mask=None, position=None, animations_speed=None): log.debug(f"Initializing {name} object") if not animations_speed: animations_speed = DEFAULT_ANIMATIONS_SPEED self.animations_timer = animations_speed self.animations_speed = animations_speed if not sprite_size: sprite_size = DEFAULT_SPRITE_SIZE if not spritesheet: #I cant link assets above, coz their default value is None texture = base.assets.sprite[name] else: texture = base.assets.sprite[spritesheet] size_x, size_y = sprite_size log.debug(f"{name}'s size has been set to {size_x}x{size_y}") #the magic that allows textures to be mirrored. With that thing being #there, its possible to use values in range 1-2 to get versions of sprites #that will face the opposite direction, removing the requirement to draw #them with hands. Without thing thing being there, 0 and 1 will be threated #as same coordinates, coz "out of box" texture wrap mode is "repeat" texture.set_wrap_u(Texture.WM_mirror) texture.set_wrap_v(Texture.WM_mirror) sprite_data = spritesheet_cutter.cut_spritesheet(texture, sprite_size) horizontal_scale, vertical_scale = sprite_data['offset_steps'] offsets = sprite_data['offsets'] entity_frame = CardMaker(name) #setting frame's size. Say, for 32x32 sprite all of these need to be 16 entity_frame.set_frame(-(size_x / 2), (size_x / 2), -(size_y / 2), (size_y / 2)) entity_object = render.attach_new_node(entity_frame.generate()) entity_object.set_texture(texture) #okay, this does the magic #basically, to show the very first sprite of 2 in row, we set tex scale #to half (coz half is our normal char's size). If we will need to use it #with sprites other than first - then we also should adjust offset accordingly #entity_object.set_tex_offset(TextureStage.getDefault(), 0.5, 0) #entity_object.set_tex_scale(TextureStage.getDefault(), 0.5, 1) entity_object.set_tex_scale(TextureStage.getDefault(), horizontal_scale, vertical_scale) #now, to use the stuff from cut_spritesheet function. #lets say, we need to use second sprite from sheet. Just do: #entity_object.set_tex_offset(TextureStage.getDefault(), *offsets[1]) #but, by default, offset should be always set to 0. In case our object #has just one sprite. Or something like that default_sprite = 0 entity_object.set_tex_offset(TextureStage.getDefault(), *offsets[default_sprite]) #enable support for alpha channel. This is a float, e.g making it non-100% #will require values between 0 and 1 entity_object.set_transparency(1) #if no position has been received - wont set it up if position: entity_object.set_pos(*position) #setting character's collisions entity_collider = CollisionNode(name) #if no collision mask has been received - using defaults if collision_mask: entity_collider.set_from_collide_mask(BitMask32(collision_mask)) entity_collider.set_into_collide_mask(BitMask32(collision_mask)) #TODO: move this to be under character's legs #right now its centered on character's center if hitbox_size: self.hitbox_size = hitbox_size else: #coz its sphere and not oval - it doesnt matter if we use x or y #but, for sake of convenience - we are going for size_y self.hitbox_size = (size_y / 2) entity_collider.add_solid(CollisionSphere(0, 0, 0, self.hitbox_size)) entity_collision = entity_object.attach_new_node(entity_collider) #this will explode if its not, but I dont have a default right now if name in ANIMS: entity_anims = ANIMS[name] self.name = name self.object = entity_object self.collision = entity_collision self.sprites = offsets #setting this to None may cause crashes on few rare cases, but going #for "idle_right" wont work for projectiles... So I technically add it #there for anims updater, but its meant to be overwritten at 100% cases self.current_animation = None #this will always be 0, so regardless of consistency I will live it be self.current_frame = default_sprite self.animations = entity_anims #death status, that may be usefull during cleanup self.dead = False #attaching python tags to object node, so these will be accessible during #collision events and similar stuff self.object.set_python_tag("name", self.name) #I thought to put ctrav there, but for whatever reason it glitched projectile #to fly into left wall. So I moved it to Creature subclass #debug function to show collisions all time #self.collision.show() #do_method_later wont work there, coz its indeed based on frames base.task_mgr.add(self.update_anims, "update entity's animations")
def __init__(self, texture_array, texture_angle = 0, mask_angle = 0, position = (0, 0), velocity = 0, window_size = 512, texture_size = 512, bgcolor = (0, 0, 0, 1)): super().__init__() self.texture_array = texture_array self.texture_dtype = type(self.texture_array.flat[0]) self.left_angle = texture_angle self.velocity = velocity self.mask_angle = mask_angle #this will change fairly frequently #Set window title and size self.window_properties = WindowProperties() self.window_properties.setSize(window_size, window_size) self.window_properties.setTitle("LeftDrift") ShowBaseGlobal.base.win.requestProperties(self.window_properties) #base is a panda3d global #CREATE MASKS (right mask for left stim, and vice-versa) self.right_mask = np.ones((texture_size,texture_size), dtype=np.uint8) #was 255* this but for modulate self.right_mask[:, texture_size//2: ] = 0 #texture_size//2:] = 0 #print(self.right_mask) #CREATE TEXTURE STAGES #Stimuli self.grating_texture = Texture("Grating") #T_unsigned_byte self.grating_texture.setup2dTexture(texture_size, texture_size, Texture.T_unsigned_byte, Texture.F_luminance) self.grating_texture.setRamImage(self.texture_array) self.left_texture_stage = TextureStage('grating') #Mask to restrict stimulus to LHS self.right_mask_texture = Texture("right_mask") self.right_mask_texture.setup2dTexture(texture_size, texture_size, Texture.T_unsigned_byte, Texture.F_luminance) self.right_mask_texture.setRamImage(self.right_mask) self.right_mask_stage = TextureStage('right_mask') #CREATE CARDS/SCENEGRAPH cm = CardMaker('left_stim_card') cm.setFrameFullscreenQuad() self.left_texture_card = self.aspect2d.attachNewNode(cm.generate()) self.right_mask_card = self.aspect2d.attachNewNode(cm.generate()) #SET TEXTURE STAGES self.left_texture_card.setTexture(self.left_texture_stage, self.grating_texture) self.right_mask_card.setTexture(self.right_mask_stage, self.right_mask_texture) #BASIC TRANSFORMS to set up angles and position #TEXTURE self.left_texture_card.setScale(np.sqrt(8)) #so it can handle arbitrary rotations and shifts self.left_texture_card.setR(self.left_angle) #MASK #self.right_card.setPos(position[0], 0, position[1]) self.right_mask_card.setScale(np.sqrt(8)) self.right_mask_card.setR(self.mask_angle) self.right_mask_card.setPos(position[0], 0, position[1] ) # ndc2uv(position[0]), ndc2uv(position[1])) self.right_mask_card.setTransparency(TransparencyAttrib.MAlpha) #enable transparency #Combine the two cards (take product of mask and texture) operand = TextureStage.COSrcColor source0 = self.right_mask_stage source1 = self.left_texture_stage self.right_mask_stage.setCombineRgb(TextureStage.CMModulate, source0, operand, source1, operand) #self.left_texture_card.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.M_add)) #self.left_texture_card.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.M_add)) #This puts a marker where the stimulus should end self.title = OnscreenText("x", style = 1, fg = (1,1,1,1), bg = bgcolor, pos = (position[0], position[1]), scale = 0.02) #Add texture move procedure to the task manager, if needed if self.velocity != 0: self.taskMgr.add(self.moveTextureTask, "moveTextureTask")
M = OdeMass() M.setBox(50, 1, 1, 1) boxBody.setMass(M) boxBody.setPosition(boxNP.getPos(render)) boxBody.setQuaternion(boxNP.getQuat(render)) # Create a BoxGeom boxGeom = OdeBoxGeom(space, 1, 1, 1) boxGeom.setCollideBits(BitMask32(0x00000002)) boxGeom.setCategoryBits(BitMask32(0x00000001)) boxGeom.setBody(boxBody) boxes.append((boxNP, boxBody)) # Add a plane to collide with cm = CardMaker("ground") cm.setFrame(-20, 20, -20, 20) ground = render.attachNewNode(cm.generate()) ground.setPos(0, 0, 0) ground.lookAt(0, 0, -1) groundGeom = OdePlaneGeom(space, Vec4(0, 0, 1, 0)) # groundGeom.setCollideBits(BitMask32(0x00000001)) # groundGeom.setCategoryBits(BitMask32(0x00000002)) # Set the camera position base.disableMouse() base.camera.setPos(40, 40, 20) base.camera.lookAt(0, 0, 0) # The task for our simulation def simulationTask(task): space.autoCollide() # Setup the contact joints
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) self.stimtype = 'image_sequence' #session_start self.session_start_time = datetime.datetime.now() self.accept("escape", sys.exit, [0]) self.accept('q', self.close) self.accept('Q', self.close) # disable mouse control so that we can place the camera base.disableMouse() camera.setPosHpr(0, 0, 10, 0, -90, 0) mat = Mat4(camera.getMat()) mat.invertInPlace() base.mouseInterfaceNode.setMat(mat) # base.enableMouse() props = WindowProperties() # props.setFullscreen(True) props.setCursorHidden(True) props.setMouseMode(WindowProperties.M_relative) base.win.requestProperties(props) base.setBackgroundColor(0, 0, 0) # set the background color to black #set up the textures # we now get buffer thats going to hold the texture of our new scene altBuffer = self.win.makeTextureBuffer("hello", 1524, 1024) # altBuffer.getDisplayRegion(0).setDimensions(0.5,0.9,0.5,0.8) # altBuffer = base.win.makeDisplayRegion() # altBuffer.makeDisplayRegion(0,1,0,1) # now we have to setup a new scene graph to make this scene self.dr2 = base.win.makeDisplayRegion(0, 0.1, 0, 0.1) altRender = NodePath("new render") # this takes care of setting up ther camera properly self.altCam = self.makeCamera(altBuffer) self.dr2.setCamera(self.altCam) self.altCam.reparentTo(altRender) self.altCam.setPos(0, -10, 0) self.bufferViewer.setPosition("llcorner") # self.bufferViewer.position = (.1,.4,.1,.4) self.bufferViewer.setCardSize(1.0, 0.0) print(self.bufferViewer.position) self.imagesTexture = MovieTexture("image_sequence") # success = self.imagesTexture.read("models/natural_images.avi") success = self.imagesTexture.read("models/movie_5hz.mpg") self.imagesTexture.setPlayRate(1.0) self.imagesTexture.setLoopCount(10) # self.imageTexture =loader.loadTexture("models/NaturalImages/BSDs_8143.tiff") # self.imagesTexture.reparentTo(altRender) cm = CardMaker("stimwindow") cm.setFrame(-4, 4, -3, 3) # cm.setUvRange(self.imagesTexture) self.card = NodePath(cm.generate()) self.card.reparentTo(altRender) if self.stimtype == 'image_sequence': self.card.setTexture(self.imagesTexture, 1) # self.imagesTexture.play() # self.bufferViewer.setPosition("lrcorner") # self.bufferViewer.setCardSize(1.0, 0.0) self.accept("v", self.bufferViewer.toggleEnable) self.accept("V", self.bufferViewer.toggleEnable) # Load the tunnel self.initTunnel() #initialize some things # for the tunnel construction: self.boundary_to_add_next_segment = -1 * TUNNEL_SEGMENT_LENGTH self.current_number_of_segments = 8 #task flow booleans self.in_waiting_period = False self.stim_started = False self.looking_for_a_cue_zone = True self.in_reward_window = False self.show_stimulus = False #for task control self.interval = 0 self.time_waiting_in_cue_zone = 0 self.wait_time = 1.0 self.stim_duration = 4.0 # in seconds self.max_stim_duration = 6.0 # in seconds self.stim_elapsed = 0.0 # in seconds self.last_position = base.camera.getZ() self.position_on_track = base.camera.getZ() #for reward control self.reward_window = 1.0 # in seconds self.reward_elapsed = 0.0 self.reward_volume = 0.008 # in mL. this is for the hardcoded 0.1 seconds of reward time self.reward_time = 0.1 # in sec, based on volume. hard coded right now but should be modified by the (1) calibration and (2) optionally by the main loop for dynamic reward scheduling # self.lick_buffer = [] #INITIALIZE NIDAQ self.nidevice = 'Dev1' self.encodervinchannel = 0 self.encodervsigchannel = 1 self.invertdo = False self.diport = 1 self.lickline = 1 self.doport = 0 self.rewardline = 0 self.rewardlines = [0] self._setupDAQ() self.do.WriteBit(1, 1) self.do.WriteBit( 3, 1 ) #set reward high, because the logic is flipped somehow. possibly by haphazard wiring of the circuit (12/24/2018 djd) self.previous_encoder_position = self.ai.data[0][2] self.encoder_gain = 20 #INITIALIZE LICK SENSOR self._lickSensorSetup() #INITIALIZE output data self.lickData = [] self.x = [] self.t = [] self.trialData = [] self.rewardData = [] #INITIALIZE KEY SENSOR, for backup inputs and other user controls self.keys = key.KeyStateHandler() self.accept('r', self._give_reward, [self.reward_volume]) img_list = glob.glob('models/NaturalImages/*.tiff')[:10] print(img_list) self.imageTextures = [loader.loadTexture(img) for img in img_list] if AUTO_MODE: self.gameTask = taskMgr.add(self.autoLoop2, "autoLoop2") self.rewardTask = taskMgr.add(self.rewardControl, "reward") self.cue_zone = concatenate( (self.cue_zone, arange( self.current_number_of_segments * -TUNNEL_SEGMENT_LENGTH - 10, self.current_number_of_segments * -TUNNEL_SEGMENT_LENGTH - TUNNEL_SEGMENT_LENGTH - 10, -1))) self.auto_position_on_track = 0 self.auto_restart = False self.auto_running = True self.contTunnel() else: # Now we create the task. taskMgr is the task manager that actually # calls the function each frame. The add method creates a new task. # The first argument is the function to be called, and the second # argument is the name for the task. It returns a task object which # is passed to the function each frame. self.gameTask = taskMgr.add(self.gameLoop, "gameLoop") # self.stimulusTask = taskMgr.add(self.stimulusControl, "stimulus") self.lickTask = taskMgr.add(self.lickControl, "lick") self.rewardTask = taskMgr.add(self.rewardControl, "reward")
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(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, (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 placePlantOnTerrain(self, itemStr, itemCnt, Mode, typItemWidth, typItemHeight, trrHorzSc, trrVertSc, numTxtTypes, txtList, planFileName): # Billboarding plants crd = CardMaker('mycard') crd.setColor(0.5, 0.5, 0.5, 1) ll = Point3(-0.5 * typItemWidth, 0, 0) lr = Point3(0.5 * typItemWidth, 0, 0) ur = Point3(0.5 * typItemWidth, 0, typItemHeight) ul = Point3(-0.5 * typItemWidth, 0, typItemHeight) crd.setFrame(ll, lr, ur, ul) crd.setHasNormals(False) crd.setHasUvs(True) # generate/save/load locations try: plan_data_fp = open(planFileName, 'r') item_list = [] for line in plan_data_fp: toks = line.split(',') px = float(toks[0].strip(' ')) py = float(toks[1].strip(' ')) ang = float(toks[2].strip(' ')) dht = float(toks[3].strip(' ')) scl = float(toks[4].strip(' ')) idx = int(toks[5].strip(' ')) item_list.append((px, py, ang, dht, scl, idx)) plan_data_fp.close() print 'loaded ', itemStr, ' data file of size:', len(item_list) except IOError: # generate list and try to save item_list = [] for a in range(itemCnt): px = random.randrange(-self.trrHorzSc * 64, self.trrHorzSc * 64) py = random.randrange(-self.trrHorzSc * 64, self.trrHorzSc * 64) ang = 180 * random.random() dht = 0.0 scl = 0.75 + 0.25 * (random.random() + random.random()) idx = random.randrange(0, numTxtTypes) item_list.append([px, py, ang, dht, scl, idx]) try: plan_data_fp = open(planFileName, 'w') for c in item_list: print >> plan_data_fp, c[0], ',', c[1], ',', c[2], ',', c[ 3], ',', c[4], ',', c[5] plan_data_fp.close() print 'saved ', itemStr, ' data of size: ', len(item_list) except IOError: print 'unable to store ', itemStr, ' data of size: ', len( item_list) # define each plant for c in item_list: px = c[0] py = c[1] ang = c[2] dht = c[3] scl = c[4] idx = c[5] if idx >= numTxtTypes: idx = 0 if Mode > 0: for b in range(Mode): crdNP = self.render.attachNewNode(crd.generate()) crdNP.setTexture(txtList[idx]) crdNP.setScale(scl) crdNP.setTwoSided(True) ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc) crdNP.setPos(px, py, ht * trrVertSc + dht) crdNP.setHpr(ang + (180 / Mode) * b, 0, 0) crdNP.setTransparency(TransparencyAttrib.MAlpha) crdNP.setLightOff() else: # set up item as defined crd.setUvRange(txtList[idx]) crdNP = self.render.attachNewNode(crd.generate()) crdNP.setBillboardAxis() crdNP.setTexture(txtList[idx]) crdNP.setScale(scl) ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc) crdNP.setPos(px, py, ht * trrVertSc) crdNP.setTransparency(TransparencyAttrib.MAlpha) crdNP.setLightOff()
def renderQuadInto(self, name="filter-stage", mul=1, div=1, align=1, depthtex=None, colortex=None, auxtex0=None, auxtex1=None, size=None, addToList=True, fullscreen=True): """ Creates an offscreen buffer for an intermediate computation. Installs a quad into the buffer. Returns the fullscreen quad. The size of the buffer is initially equal to the size of the main window. The parameters 'mul', 'div', and 'align' can be used to adjust that size. """ texgroup = (depthtex, colortex, auxtex0, auxtex1) if not size: winx, winy = self.getScaledSize(mul, div, align) else: winx, winy = size depthbits = bool(depthtex != None) buffer = self.createBuffer(name, winx, winy, texgroup, depthbits) if (buffer == None): return None cm = CardMaker("filter-stage-quad") if fullscreen: cm.setFrameFullscreenQuad() else: cm.setFrame(-1, 1, -1, 1) quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) 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) dr = buffer.makeDisplayRegion((0, 1, 0, 1)) dr.disableClears() dr.setCamera(quadcam) dr.setActive(True) dr.setScissorEnabled(False) # This clear stage is important if the buffer is padded, so that # any pixels accidentally sampled in the padded region won't # be reading from unititialised memory. buffer.setClearColor((0, 0, 0, 1)) buffer.setClearColorActive(False) if addToList: self.buffers.append(buffer) self.sizes.append((mul, div, align)) self.forceSizes.append((size is not None)) return quad else: return [quad, buffer]
from panda3d.core import NodePath from panda3d.core import CardMaker from panda3d.core import Material from panda3d.core import PNMImage from panda3d.core import Texture from panda3d.core import TextureStage from panda3d.core import DirectionalLight from panda3d.core import AmbientLight cm = CardMaker('card') cm.set_frame(-31, 31, -31, 31) map_np = NodePath("map") card = map_np.attach_new_node(cm.generate()) card.set_p(-90) mat = Material() mat.set_base_color((1.0, 1.0, 1.0, 1)) mat.set_emission((1.0, 1.0, 1.0, 1)) mat.set_metallic(1.0) mat.set_roughness(1.0) card.set_material(mat) texture_size = 256 base_color_pnm = PNMImage(texture_size, texture_size) base_color_pnm.fill(0.72, 0.45, 0.2) # Copper base_color_tex = Texture("BaseColor") base_color_tex.load(base_color_pnm) ts = TextureStage('BaseColor') # a.k.a. Modulate ts.set_mode(TextureStage.M_modulate)
class ToonBlitzAssetMgr(DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory( 'DistributedToonBlitzAssets') def __init__(self, game): self.__defineConstants() self.game = game self.load() def __defineConstants(self): pass def load(self): self.world = NodePath('ToonBlitzWorld') self.background = loader.loadModel( 'phase_4/models/minigames/toonblitz_game') self.background.reparentTo(self.world) self.startingWall = loader.loadModel( 'phase_4/models/minigames/toonblitz_game_wall') self.startingPipe = loader.loadModel( 'phase_4/models/minigames/toonblitz_game_start') self.exitElevator = loader.loadModel( 'phase_4/models/minigames/toonblitz_game_elevator') self.arrow = loader.loadModel( 'phase_4/models/minigames/toonblitz_game_arrow') self.sprayProp = loader.loadModel( 'phase_4/models/minigames/prop_waterspray') self.treasureModelList = [] salesIcon = loader.loadModel('phase_4/models/minigames/salesIcon') self.treasureModelList.append(salesIcon) moneyIcon = loader.loadModel('phase_4/models/minigames/moneyIcon') self.treasureModelList.append(moneyIcon) legalIcon = loader.loadModel('phase_4/models/minigames/legalIcon') self.treasureModelList.append(legalIcon) corpIcon = loader.loadModel('phase_4/models/minigames/corpIcon') self.treasureModelList.append(corpIcon) self.particleGlow = loader.loadModel( 'phase_4/models/minigames/particleGlow') self.blockTypes = [] for i in xrange(4): blockType = loader.loadModel( 'phase_4/models/minigames/toonblitz_game_block0' + str(i)) self.blockTypes.append(blockType) self.stomper = loader.loadModel( 'phase_4/models/minigames/toonblitz_game_stomper') plane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, -50))) dropPlane = CollisionNode('dropPlane') dropPlane.addSolid(plane) dropPlane.setCollideMask(ToontownGlobals.FloorBitmask) self.world.attachNewNode(dropPlane) self.gameMusic = base.loader.loadMusic( 'phase_4/audio/bgm/MG_TwoDGame.ogg') self.treasureGrabSound = loader.loadSfx( 'phase_4/audio/sfx/SZ_DD_treasure.ogg') self.sndOof = base.loader.loadSfx( 'phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.soundJump = base.loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_vine_game_jump.ogg') self.fallSound = base.loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_vine_game_fall.ogg') self.watergunSound = base.loader.loadSfx( 'phase_4/audio/sfx/AA_squirt_seltzer_miss.ogg') self.splashSound = base.loader.loadSfx( 'phase_4/audio/sfx/Seltzer_squirt_2dgame_hit.ogg') self.threeSparkles = loader.loadSfx( 'phase_4/audio/sfx/threeSparkles.ogg') self.sparkleSound = loader.loadSfx('phase_4/audio/sfx/sparkly.ogg') self.headCollideSound = loader.loadSfx( 'phase_3.5/audio/sfx/AV_collision.ogg') self.faceStartPos = Vec3(-0.8, 0, -0.87) self.faceEndPos = Vec3(0.8, 0, -0.87) self.aspect2dRoot = aspect2d.attachNewNode('TwoDGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) self.cardMaker = CardMaker('card') self.cardMaker.reset() self.cardMaker.setName('ProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.progressLine = self.aspect2dRoot.attachNewNode( self.cardMaker.generate()) self.progressLine.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) self.progressLine.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in xrange( ToonBlitzGlobals.NumSections[self.game.getSafezoneId()] + 1): hash = self.aspect2dRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(self.progressLine.getScale()[2], 1, self.progressLine.getScale()[2] * 5) t = float(n) / ToonBlitzGlobals.NumSections[ self.game.getSafezoneId()] hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) def destroy(self): while len(self.blockTypes): blockType = self.blockTypes[0] self.blockTypes.remove(blockType) del blockType self.blockTypes = None while len(self.treasureModelList): treasureModel = self.treasureModelList[0] self.treasureModelList.remove(treasureModel) del treasureModel self.treasureModelList = None self.startingWall.removeNode() del self.startingWall self.startingPipe.removeNode() del self.startingPipe self.exitElevator.removeNode() del self.exitElevator self.stomper.removeNode() del self.stomper self.arrow.removeNode() del self.arrow self.sprayProp.removeNode() del self.sprayProp self.aspect2dRoot.removeNode() del self.aspect2dRoot self.world.removeNode() del self.world del self.gameMusic del self.treasureGrabSound del self.sndOof del self.soundJump del self.fallSound del self.watergunSound del self.splashSound del self.threeSparkles del self.sparkleSound del self.headCollideSound self.game = None return def onstage(self): self.world.reparentTo(render) base.playMusic(self.gameMusic, looping=1, volume=0.9) def offstage(self): self.world.hide() self.gameMusic.stop() def enterPlay(self): pass def exitPlay(self): pass def enterPause(self): pass def exitPause(self): pass def playJumpSound(self): base.localAvatar.soundRun.stop() base.playSfx(self.soundJump, looping=0) def playWatergunSound(self): self.watergunSound.stop() base.playSfx(self.watergunSound, looping=0) def playSplashSound(self): self.splashSound.stop() base.playSfx(self.splashSound, looping=0) def playHeadCollideSound(self): self.headCollideSound.stop() base.playSfx(self.headCollideSound, looping=0)
def __init__(self, mapFileName): # Instance variables self.camPos = Vec3(0, 0, 0) self.faceVec = Vec2(0, 0) self.velocity = 0 self.episodeFrameCounter = 0 self.historyFrameCounter = 0 self.deviationCounter = 0 self.accSignal = 0 self.turnSignal = 0 self.signalGameFeedback = Event() self.lock = Lock() self.bufferFeedback = bytearray() self.signalShutdown = Event() # Panda3D-related initialization # Car-view Camera base.camLens.setNear(0.05) base.camLens.setFov(70) # A fixed, top-view Camera _ = Camera("top_cam") topCam = render.attachNewNode(_) topCam.setName("top_cam") topCam.setPos(0, 0, 40) topCam.setHpr(0, -90, 0) dr = base.camNode.getDisplayRegion(0) dr.setActive(0) window = dr.getWindow() drTop = window.makeDisplayRegion(0.5, 1, 0, 0.5) drTop.setSort(dr.getSort()) drTop.setCamera(topCam) self.drCar = window.makeDisplayRegion(0, 0.5, 0.5, 1) self.drCar.setSort(dr.getSort()) self.drCar.setCamera(base.cam) # BulletWorld world = BulletWorld() world.setGravity(Vec3(0, 0, 0)) props = WindowProperties() props.setSize(1024, 768) base.win.requestProperties(props) # Floor shapeGround = BulletPlaneShape(Vec3(0, 0, 1), 0.1) nodeGround = BulletRigidBodyNode('Ground') nodeGround.addShape(shapeGround) npGround = render.attachNewNode(nodeGround) npGround.setPos(0, 0, -2) world.attachRigidBody(nodeGround) cmGround = CardMaker("Ground") cmGround.setFrame(-10, 10, -10, 10); npGroundTex = render.attachNewNode(cmGround.generate()) npGroundTex.reparentTo(npGround) ts = TextureStage("ts") ts.setMode(TextureStage.M_modulate) groundTexture = loader.loadTexture(mapFileName) npGroundTex.setP(270) npGroundTex.setTexScale(ts, 1, 1) npGround.setTexture(ts, groundTexture) # Car shapeBox = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) nodeBox = BulletRigidBodyNode('Box') nodeBox.setMass(1.0) nodeBox.addShape(shapeBox) self.npBox = render.attachNewNode(nodeBox) self.npBox.setPos(self.camPos) world.attachRigidBody(nodeBox) modelBox = loader.loadModel('models/box.egg') modelBox.flattenLight() modelBox.setScale(0.5) modelBox.reparentTo(self.npBox)
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) self.disableMouse() self.camera.setPos(0, -26, 4) self.setBackgroundColor(0, 0, 0) # Create a texture into which we can copy the main window. # We set it to RTMTriggeredCopyTexture mode, which tells it that we # want it to copy the window contents into a texture every time we # call self.win.triggerCopy(). self.tex = Texture() self.tex.setMinfilter(Texture.FTLinear) self.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture) # Set the initial color to clear the texture to, before rendering it. # This is necessary because we don't clear the texture while rendering, # and otherwise the user might see garbled random data from GPU memory. self.tex.setClearColor((0, 0, 0, 1)) self.tex.clearImage() # Create another 2D camera. Tell it to render before the main camera. self.backcam = self.makeCamera2d(self.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) # Obtain two texture cards. One renders before the dragon, the other # after. self.bcard = self.win.getTextureCard() self.bcard.reparentTo(self.background) self.bcard.setTransparency(1) self.fcard = self.win.getTextureCard() self.fcard.reparentTo(self.render2d) self.fcard.setTransparency(1) # Initialize one of the nice effects. self.chooseEffectGhost() # Add the task that initiates the screenshots. taskMgr.add(self.takeSnapShot, "takeSnapShot") # Create some black squares on top of which we will # place the instructions. blackmaker = CardMaker("blackmaker") blackmaker.setColor(0, 0, 0, 1) blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00) instcard = NodePath(blackmaker.generate()) instcard.reparentTo(self.render2d) blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85) titlecard = NodePath(blackmaker.generate()) titlecard.reparentTo(self.render2d) # Panda does its best to hide the differences between DirectX and # OpenGL. But there are a few differences that it cannot hide. # One such difference is that when OpenGL copies from a # visible window to a texture, it gets it right-side-up. When # DirectX does it, it gets it upside-down. There is nothing panda # can do to compensate except to expose a flag and let the # application programmer deal with it. You should only do this # in the rare event that you're copying from a visible window # to a texture. if self.win.getGsg().getCopyTextureInverted(): print("Copy texture is inverted.") self.bcard.setScale(1, 1, -1) self.fcard.setScale(1, 1, -1) # Put up the instructions title = OnscreenText(text="Panda3D: Tutorial - Motion Trails", fg=(1, 1, 1, 1), parent=base.a2dBottomCenter, pos=(0, 0.1), scale=.08) instr0 = addInstructions(0.06, "Press ESC to exit") instr1 = addInstructions(0.12, "Press 1: Ghost effect") instr2 = addInstructions(0.18, "Press 2: PaintBrush effect") instr3 = addInstructions(0.24, "Press 3: Double Vision effect") instr4 = addInstructions(0.30, "Press 4: Wings of Blue effect") instr5 = addInstructions(0.36, "Press 5: Whirlpool effect") # Enable the key events self.accept("escape", sys.exit, [0]) self.accept("1", self.chooseEffectGhost) self.accept("2", self.chooseEffectPaintBrush) self.accept("3", self.chooseEffectDoubleVision) self.accept("4", self.chooseEffectWingsOfBlue) self.accept("5", self.chooseEffectWhirlpool)
def __init__(self, texture_array, stim_angles=(0, 0), mask_angle=0, position=(0, 0), velocity=0, band_radius=3, window_size=512, texture_size=512, bgcolor=(0, 0, 0, 1)): super().__init__() self.mask_position_ndc = position self.mask_position_uv = (ndc2uv(self.mask_position_ndc[0]), ndc2uv(self.mask_position_ndc[1])) self.mask_scale = np.sqrt(8) self.texture_array = texture_array self.texture_dtype = type(self.texture_array.flat[0]) self.ndims = self.texture_array.ndim self.left_texture_angle = stim_angles[0] self.right_texture_angle = stim_angles[1] self.velocity = velocity self.mask_angle = mask_angle #this will change fairly frequently #Set window title and size self.window_properties = WindowProperties() self.window_properties.setSize(window_size, window_size) self.window_properties.setTitle("BinocularStatic") ShowBaseGlobal.base.win.requestProperties( self.window_properties) #base is a panda3d global #CREATE MASKS (right mask for left stim, and vice-versa) self.right_mask = 255 * np.ones( (texture_size, texture_size), dtype=np.uint8) self.right_mask[:, texture_size // 2 - band_radius:] = 0 #CREATE TEXTURE STAGES #Grating texture self.grating_texture = Texture("Grating") #T_unsigned_byte self.grating_texture.setup2dTexture(texture_size, texture_size, Texture.T_unsigned_byte, Texture.F_luminance) self.grating_texture.setRamImage(self.texture_array) self.left_texture_stage = TextureStage('grating') #Mask self.right_mask_texture = Texture("right_mask") self.right_mask_texture.setup2dTexture(texture_size, texture_size, Texture.T_unsigned_byte, Texture.F_luminance) self.right_mask_texture.setRamImage(self.right_mask) self.right_mask_stage = TextureStage('right_mask') #Multiply the texture stages together self.right_mask_stage.setCombineRgb(TextureStage.CMModulate, TextureStage.CSTexture, TextureStage.COSrcColor, TextureStage.CSPrevious, TextureStage.COSrcColor) #CREATE CARDS/SCENEGRAPH cm = CardMaker('stimcard') cm.setFrameFullscreenQuad() self.left_card = self.aspect2d.attachNewNode(cm.generate()) #SET TEXTURE STAGES self.left_card.setTexture(self.left_texture_stage, self.grating_texture) self.left_card.setTexture(self.right_mask_stage, self.right_mask_texture) #Add texture move procedure to the task manager, if needed if self.velocity != 0: self.taskMgr.add(self.update_trs, "moveTextureTask") self.title = OnscreenText("x", style=1, fg=(1, 1, 1, 1), bg=(0, 0, 0, .8), pos=self.mask_position_ndc, scale=0.05)
divergenceBackBuffer = RenderBuffer('DivergenceBack', -93) def loadShader(frag): return Shader.load(Shader.SL_GLSL, vertex='default.vert', fragment=frag) AdvectShader = loadShader('advect.frag') DivergenceShader = loadShader('divergence.frag') JacobiShader = loadShader('jacobi.frag') GradientShader = loadShader('gradient.frag') SplatShader = loadShader('splat.frag') BoundaryShader = loadShader('boundary.frag') MainShader = loadShader('main.frag') visualizeQuad = NodePath(card.generate()) visualizeQuad.reparentTo(render2d) inverseCanvasSize = (1.0 / w, 1.0 / h) def enableAll(): densityBuffer.active = True densityBackBuffer.active = True velocityBuffer.active = True velocityBackBuffer.active = True pressureBuffer.active = True pressureBackBuffer.active = True divergenceBuffer.active = True divergenceBackBuffer.active = True
class Tmx2Bam(): def __init__(self, input_file, output_file=None, prefabs=""): self.dir = os.path.dirname(input_file) self.depth = 0 self.cardmaker = CardMaker("image") self.cardmaker.set_frame(-0.5, 0.5, -0.5, 0.5) self.linesegs = LineSegs() self.textnode = TextNode("text") self.tilesheets = [] # Every tsx file loaded. self.tiles = {} # Every unique tile/card. self.node = NodePath("tmx_root") # load prefab models self.prefabs = {} if prefabs: loader = Loader.get_global_ptr() for prefab_node in loader.load_sync(prefabs).get_children(): prefab_node.clear_transform() self.prefabs[prefab_node.name] = NodePath(prefab_node) self.tmx = ET.parse(input_file).getroot() self.xscale = int(self.tmx.get("tilewidth")) self.yscale = int(self.tmx.get("tileheight")) self.size = [0, 0] self.load_group(self.tmx) if output_file: self.export_bam(output_file) def attributes_to_tags(self, node, element): if not element == None: for property in element: if property.get("name") and property.get("value"): node.set_tag(property.get("name"), property.get("value")) for key in element.keys(): node.set_tag(key, element.get(key)) def build_text(self, object): self.textnode.set_text(object[0].text) # TODO: set color # TODO: set wrap return self.textnode.generate() def build_polygon(self, object): self.linesegs.reset() points = object[0].get("points").split(" ") points = [tuple(map(float, i.split(","))) for i in points] startx = points[0][0] / self.xscale starty = points[0][1] / self.yscale self.linesegs.move_to(startx, -starty, 0) for point in points: x, y = point[0] / self.xscale, point[1] / self.yscale self.linesegs.draw_to(x, -y, 0) self.linesegs.draw_to(startx, -starty, 0) return self.linesegs.create() def build_rectangle(self, w, h): self.linesegs.reset() self.linesegs.move_to(0, 0, 0) self.linesegs.draw_to(w, 0, 0) self.linesegs.draw_to(w, -h, 0) self.linesegs.draw_to(0, -h, 0) self.linesegs.draw_to(0, 0, 0) return self.linesegs.create() def build_tile(self, tsx, id): tile = None # Cross-reference with self.prefabs in case there's a shape # corresponding with a tile's type use_prefab = False for tile in tsx.findall("tile"): if int(tile.get("id")) == id: type = tile.get("type") if type in self.prefabs: geometry_node = NodePath(str(id)) self.prefabs[type].copy_to(geometry_node) use_prefab = True break # Else we generate a card if not use_prefab: geometry = self.cardmaker.generate() geometry_node = NodePath(geometry) geometry_node.set_texture(tsx.get("texture"), 1) geometry_node.set_p(-90) geometry_node.set_transparency(True) # scale and offset UVs for single sprite columns = int(tsx.get("columns")) rows = int(tsx.get("rows")) w, h = 1 / columns, 1 / rows tile_x, tile_y = int(id % columns), int(id / (columns)) u, v = (tile_x * w), 1 - ((tile_y * h) + h) for stage in geometry_node.find_all_texture_stages(): geometry_node.set_texture(stage, tsx.get("texture"), 1) geometry_node.set_tex_scale(stage, w, h) geometry_node.set_tex_offset(stage, (u, v)) self.attributes_to_tags(geometry_node, tile) return geometry_node def animated_tile(self, tsx, tile): node = NodePath("animated tile") sequence = SequenceNode("animated tile") duration = int(tile[0][0].get("duration")) if duration >= 9000: sequence.set_frame_rate(0) else: sequence.set_frame_rate(1000 / duration) for frame in tile[0]: tileid = int(frame.get("tileid")) tile_node = self.build_tile(tsx, tileid) sequence.add_child(tile_node.node()) sequence.loop(True) node.attach_new_node(sequence) return node def get_tile(self, map_id): tileset, set_id = self.get_tileset(map_id) tsx = tileset.get("tsx") if map_id in self.tiles: # if card is already stored node = self.tiles[map_id] # use that one else: # else build and store it is_special = False node = self.build_tile(tsx, set_id) for element in tsx: if element.tag == "tile": if int(element.get("id")) == set_id: # if it contains an element, it's always an animation if len(element) > 0: node = self.animated_tile(tsx, element) self.attributes_to_tags(node, element) break self.tiles[map_id] = node return node def load_layer(self, layer): layer_node = NodePath(layer.get("name")) static_tiles = NodePath("static") # Static tiles to flatten flat_animated_tiles = NodePath("animated") # Animated tiles to flatten dynamic_tiles = NodePath( "dynamic") # All tiles unless otherwise specified (don't flatten) tile_groups = {} # should we flatten this layer store_data = flatten = False properties = layer.find("properties") if properties: for property in properties: if property.get("name") == "flatten": flatten = True if property.get("name") == "store_data": store_data = True # build all tiles in data as a grid of cards data = layer.find("data").text data = data.replace('\n', '') data = data.split(",") collumns = int(layer.get("width")) rows = int(layer.get("height")) self.size = [collumns, rows] for y in range(rows): for x in range(collumns): id = int(data[(y * collumns) + (x % collumns)]) data[(y * collumns) + (x % collumns)] = id if id > 0: tile = NodePath("tile") self.get_tile(id).copy_to(tile) if flatten: if tile.find("**/+SequenceNode"): tile.reparent_to(flat_animated_tiles) else: tile.reparent_to(static_tiles) else: tile.reparent_to(layer_node) tile.set_pos(x, -y, 0) if flatten: if static_tiles.get_num_children() > 0: clear_all_tags(static_tiles) static_tiles.flatten_strong() if flat_animated_tiles.get_num_children() > 0: clear_all_tags(flat_animated_tiles) flat_animated_tiles = self.flatten_animated_tiles( flat_animated_tiles) for t in (static_tiles, flat_animated_tiles): t.reparent_to(layer_node) if store_data: layer_node.set_python_tag("data", data) self.append_layer(layer_node, properties) def flatten_animated_tiles(self, group_node): # FIXME: hard to read: get_child() everywhere # Makes a new node for each frame using all its tiles # flatten the s*** out of the node and add to a new SequenceNode. tiles = group_node.get_children() flattened_sequence = SequenceNode(tiles[0].name) for a, animation in enumerate(tiles[0].node().get_children()): for f, frame in enumerate(animation.get_child(0).get_children()): combined_frame = NodePath("frame " + str(f)) for tile in tiles: new_np = NodePath("frame") new_np.set_pos(tile.get_pos()) animation = tile.node().get_child(a).get_child(0) new_np.attach_new_node(animation.get_child(f)) new_np.reparent_to(combined_frame) combined_frame.flattenStrong() flattened_sequence.add_child(combined_frame.node()) framerate = animation.get_frame_rate() flattened_sequence.set_frame_rate(framerate) flattened_sequence.loop(True) return NodePath(flattened_sequence) def load_objectgroup(self, objectgroup): layer_node = NodePath(objectgroup.get("name")) for object in objectgroup: name = object.get("name") if not name: name = "object" node = NodePath(name) if len(object) > 0: # Has a type, so it's either a polygon, text, point or ellipse # Points and ellipses are just an empty for now. kind = object[0].tag if kind == "polygon": node.attach_new_node(self.build_polygon(object)) elif kind == "text": node.attach_new_node(self.build_text(object)) node.set_p(-90) self.attributes_to_tags(node, object[0]) else: # Doesn't have a type, so it's either an image or a rectangle node = NodePath(name) w = float(object.get("width")) / self.xscale h = float(object.get("height")) / self.yscale if object.get("gid"): # Has a gid, so it's an image self.get_tile(int(object.get("gid"))).copy_to(node) node.set_scale(w, h, 1) else: # It's none of the above, so it's a rectangle node.attach_new_node(self.build_rectangle(w, h)) x = y = 0 if object.get("x"): x = float(object.get("x")) / self.xscale if object.get("y"): y = float(object.get("y")) / self.yscale node.set_pos(x, -y, 0) self.attributes_to_tags(node, object) node.reparent_to(layer_node) self.append_layer(layer_node, objectgroup.find("properties")) def load_imagelayer(self, imagelayer): # FIXME: A lot of this stuff is repeated in build_tilcard image = imagelayer[0] right = int(image.get("width")) / self.xscale down = int(image.get("height")) / self.yscale self.cardmaker.set_frame(0, right, -down, 0) node = NodePath(self.cardmaker.generate()) self.cardmaker.set_frame(0, 1, -1, 0) texture = Texture() texture.read(os.path.join(self.dir, image.get("source"))) texture.setMagfilter(SamplerState.FT_nearest) texture.setMinfilter(SamplerState.FT_nearest) node.set_texture(texture) node.set_transparency(True) node.reparent_to(self.node) ox = imagelayer.get("offsetx") x, y = 0, 0 if ox: x = float(ox) / self.xscale oy = imagelayer.get("offsety") if oy: y = float(oy) / self.yscale node.set_pos((x, -y, self.depth)) node.set_p(-90) def load_group(self, group): for layer in group: if layer.tag == "tileset": self.load_tsx(layer) elif layer.tag == "layer": self.load_layer(layer) elif layer.tag == "objectgroup": self.load_objectgroup(layer) elif layer.tag == "imagelayer": self.load_imagelayer(layer) elif layer.tag == "group": self.load_group(layer) def append_layer(self, node, properties): self.attributes_to_tags(node, properties) node.set_z(self.depth) self.depth += 1 if properties: for property in properties: if property.get("name") == "z": node.set_z(int(property.get("value"))) self.depth -= 1 break node.reparent_to(self.node) def get_tileset(self, id): for tilesheet in self.tilesheets: if int(tilesheet.get("firstgid")) > id: break else: last = tilesheet id_in_sheet = id - int(last.get("firstgid")) return last, id_in_sheet, def load_tsx(self, layer): tsx_filename = layer.get("source") tsx = ET.parse(os.path.join(self.dir, tsx_filename)).getroot() # Load texture and store in the element tree. img_filename = tsx[0].get("source") texture = Texture() dir = os.path.join(self.dir, tsx_filename) place = os.path.join(os.path.split(dir)[0], img_filename) texture.read(place) texture.setMagfilter(SamplerState.FT_nearest) texture.setMinfilter(SamplerState.FT_nearest) tsx.set("texture", texture) columns = int(tsx.get("columns")) rows = int(tsx.get("tilecount")) // columns tsx.set("rows", str(rows)) layer.set("tsx", tsx) self.tilesheets.append(layer) def export_bam(self, filename): print("Exporting as {}".format(filename)) self.node.writeBamFile("{}".format(filename))
class FancyLoadingScreen(DirectObject.DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory('LoadingScreen') def __init__(self, parent): DirectObject.DirectObject.__init__(self) self.debugMode = config.GetInt('loading-screen') == 2 self.parent = parent self.state = False self.currScreenshot = None self.snapshot = None self.snapshotFrame = None self.snapshotFrameBasic = None self.currentTime = 0 self.analyzeMode = False self.loadScale = 1.0 self.unmappedTicks = [] self.stepInfo = { } self.accept(base.win.getWindowEvent(), self.adjustSize) self.accept('tick', self.tick) self.currStage = 'unmapped' self.stagePercent = 0 self.numObjects = 0 self.currPercent = 0.0 self.line = LineSegs() self.line.setColor((0, 0, 0, 1)) self.line.setThickness(1) self.stageLabel = None self.currNum = 0 self.overallPercent = 0 self.lastPercent = 0 self.topLock = aspect2dp.attachNewNode('topShift') self.root = self.topLock.attachNewNode('loadingScreenRoot') self.root.setZ(-1) self.root.stash() self.model = loader.loadModel('models/gui/pir_m_gui_gen_loadScreen.bam') self.model.setP(90) self.model.reparentTo(self.root) cm = CardMaker('backdrop') cm.setFrame(-10, 10, -10, 10) if self.debugMode: self.backdrop = self.root.attachNewNode(cm.generate()) self.backdrop.setX(-1.5) self.backdrop.setZ(-1) self.backdrop.setScale(4) self.backdrop.setColor(0.5, 0.5, 0.5, 1) cm = CardMaker('loadingBarBase') cm.setFrame(-0.90000000000000002, 0.90000000000000002, 0.10000000000000001, 0.5) self.loadingBarBacking = self.root.attachNewNode(cm.generate()) self.loadingBarRoot = self.root.attachNewNode('loadingBarRoot') cm.setName('analysisBarBase') cm.setFrame(-0.90000000000000002, 0.90000000000000002, -0.5, -0.10000000000000001) self.analysisBar = self.root.attachNewNode(cm.generate()) self.analysisBarRoot = self.root.attachNewNode('analysisBarRoot') self.analysisBar.hide() self.analysisButtons = [] self.enterToContinue = DirectLabel(parent = self.root, text = 'Press Shift To Continue', relief = None, text_scale = 0.10000000000000001, pos = (0, 0, -0.90000000000000002), text_align = TextNode.ACenter) self.enterToContinue.hide() self.stageLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (-1.25, 0, 0.75), text_align = TextNode.ALeft, textMayChange = 1) self.tickLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (0.75, 0, 0.75), textMayChange = 1) self.overallLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (0, 0, -0.75), textMayChange = 1) else: self.backdrop = loader.loadModel('models/gui/pir_m_gui_gen_loadScreen') self.backdrop.reparentTo(self.root) bg = self.backdrop.find('**/expandable_bg') bg.setScale(1000, 1, 1000) bg.flattenStrong() self.backdrop.find('**/loadbar_grey').setColorScale(0.14999999999999999, 0.14999999999999999, 0.14999999999999999, 0.10000000000000001) self.loadingBar = self.backdrop.find('**/loadbar') self.loadingBar.setColorScale(0.20000000000000001, 0.59999999999999998, 0.5, 1) self.loadingPlank = NodePathCollection() self.loadingPlank.addPath(self.backdrop.find('**/plank_loading_bar')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar_frame')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar_grey')) self.titlePlank = self.backdrop.find('**/plank_title') self.percentLabel = DirectLabel(text = '0%', parent = self.root, relief = None, text_font = PiratesGlobals.getPirateFont(), text_fg = PiratesGuiGlobals.TextFG2, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = 0.031, pos = (0, 0, -0.44450000000000001), textMayChange = 1) self.loadingPlank.addPath(self.percentLabel) self.screenshot = self.backdrop.find('**/screenshot') copyGeom = self.loadingBar.find('**/+GeomNode').node().getGeom(0) format = copyGeom.getVertexData().getFormat() primitive = copyGeom.getPrimitive(0) data = GeomVertexData(self.screenshot.node().getGeom(0).getVertexData()) data.setFormat(format) writer = GeomVertexWriter(data, 'texcoord') writer.setData2f(0, 0) writer.setData2f(1, 0) writer.setData2f(1, 1) writer.setData2f(0, 1) geom = Geom(data) geom.addPrimitive(primitive) self.screenshot.node().removeGeom(0) self.screenshot.node().addGeom(geom) self.titlePlankMiddle = self.backdrop.find('**/plank_title_middle_box') self.titlePlankLeft = self.backdrop.find('**/plank_title_left') self.titlePlankRight = self.backdrop.find('**/plank_title_right') self.loadingBarColors = [ (((i % 10) / 10.0 + 0.5) / 2.0, ((i % 100) / 10 / 10.0 + 0.5) / 2.0, (i / 100 / 10.0 + 0.5) / 2.0, 1) for i in range(1000) ] random.shuffle(self.loadingBarColors) self.lastUpdateTime = globalClock.getRealTime() self.locationLabel = DirectLabel(parent = self.root, relief = None, text = '', text_font = PiratesGlobals.getPirateOutlineFont(), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = PiratesGuiGlobals.TextScaleTitleJumbo * 0.69999999999999996, text_align = TextNode.ACenter, pos = (0.0, 0.0, 0.51500000000000001), textMayChange = 1) self.locationText = None self.hintLabel = DirectLabel(parent = self.root, relief = None, text = '', text_font = PiratesGlobals.getPirateOutlineFont(), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = PiratesGuiGlobals.TextScaleTitleJumbo * 0.5, text_align = TextNode.ACenter, pos = (0.0, 0.0, -0.62), text_wordwrap = 30, textMayChange = 1) self.hintText = None self.adImage = None self.allowLiveFlatten = ConfigVariableBool('allow-live-flatten') self.title_art = [] self.tempVolume = [] self.adjustSize(base.win) gsg = base.win.getGsg() if gsg: self.root.prepareScene(gsg) def startLoading(self, expectedLoadScale): if not self.debugMode: self.loadingBar.setSx(0) self.loadScale = float(expectedLoadScale) self.currStage = 'unmapped' self.stagePercent = 0 self.numObjects = 0 self.currPercent = 0.0 self.loadingStart = globalClock.getRealTime() self.currNum = 0 self.overallPercent = 0 self.lastPercent = 0 self.stepNum = 0 if self.debugMode: self.overallLabel['text'] = '0.0' self.stageLabel['text'] = self.currStage self.update() def beginStep(self, stageName, amt = 0, percent = 0.001): if not self.state: return None if self.currStage != 'unmapped' and stageName != self.currStage: if __dev__ and self.debugMode: self.notify.error('step %s not finished when step %s was started!' % (self.currStage, stageName)) else: self.notify.warning('step %s not finished when step %s was started!' % (self.currStage, stageName)) return None self.stepNum += 1 if self.debugMode: stageColor = self.loadingBarColors[self.stepNum] self.stepInfo[stageName] = [ globalClock.getRealTime() - self.loadingStart, 0.0, stageColor, [], self.lastPercent + self.stagePercent, percent, amt] self.stepCard = CardMaker('step-%s' % stageName) self.stepCard.setColor(stageColor) self.currPoly = NodePath('empty') self.stageLabel['text'] = stageName self.tickLabel['text'] = '0.0' self.currPercent = 0.0 self.overallPercent = min(100.0 * self.loadScale, self.lastPercent + self.stagePercent) self.lastPercent = self.overallPercent self.currStage = stageName self.stagePercent = percent self.numObjects = amt self.currNum = 0 base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() def endStep(self, stageName): if self.currStage == 'unmapped': self.notify.warning('step %s was started before loading screen was enabled' % stageName) return None if stageName != self.currStage: if __dev__ and self.debugMode: self.notify.error('step %s was active while step %s was trying to end!' % (self.currStage, stageName)) else: return None self.tick() if self.debugMode: stageInfo = self.stepInfo[self.currStage] stageInfo[1] = globalClock.getRealTime() - self.loadingStart - stageInfo[0] self.currPoly.detachNode() self.stepCard.setFrame((self.lastPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, ((self.lastPercent + self.stagePercent) / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, 0.10000000000000001, 0.5) self.loadingBarRoot.attachNewNode(self.stepCard.generate()) self.stageLabel['text'] = 'unmapped' self.currStage = 'unmapped' self.currPercent = 0.0 def tick(self): if self.state == False or self.analyzeMode: return None if self.debugMode: if self.currStage == 'unmapped': self.unmappedTicks.append(globalClock.getRealTime() - self.loadingStart) else: self.stepInfo[self.currStage][3].append(globalClock.getRealTime() - self.loadingStart) self.currNum += 1 self.currPercent = min(1.0, self.currNum / float(self.numObjects + 1)) self.overallPercent = min(100.0 * self.loadScale, self.lastPercent + self.currPercent * self.stagePercent) self.update() def destroy(self): taskMgr.remove('updateLoadingScreen') for part in (self.model, self.snapshot): if part is not None: tex = part.findTexture('*') if tex: tex.releaseAll() part.removeNode() self.model = None self.snapshot = None if self.snapshotFrame: self.snapshotFrame.destroy() if self.snapshotFrameBasic: self.snapshotFrameBasic.destroy() if self.locationLabel: self.locationLabel.destroy() if self.hintLabel: self.hintLabel.destroy() if self.debugMode: self.stageLabel.destroy() self.tickLabel.destroy() self.overallLabel.destroy() self.enterToContinue.destroy() self.stageLabel = None self.tickLabel = None self.overallLabel = None self.enterToContinue = None self.ignoreAll() def showTitleFrame(self): if base.config.GetBool('no-loading-screen', 0): return None for part in self.title_art: part.show() def hideTitleFrame(self): for part in self.title_art: part.hide() def show(self, waitForLocation = False, disableSfx = True, expectedLoadScale = 1.0): if self.state and base.config.GetBool('no-loading-screen', 0) or not (self.locationLabel): return None render.hide() render2d.hide() render2dp.hide() if not self.debugMode: self.loadingPlank.hide() self.root.unstash() self.root.showThrough() self.state = True gsg = base.win.getGsg() if gsg: gsg.setIncompleteRender(False) base.setTaskChainNetNonthreaded() self.allowLiveFlatten.setValue(1) self.startLoading(expectedLoadScale) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() base.refreshAds() taskMgr.add(self.update, 'updateLoadingScreen', priority = -100) if base.sfxManagerList and disableSfx: index = 0 while index < len(base.sfxManagerList): sfx_manager = base.sfxManagerList[index] sfx_manager.setVolume(0.0) index += 1 if base.appRunner: base.appRunner.notifyRequest('onLoadingMessagesStart') self._FancyLoadingScreen__setLocationText(self.locationText) self._FancyLoadingScreen__setHintText(self.hintText) if not waitForLocation: screenshot = random.choice(tutorialShots_MoveAim) self._FancyLoadingScreen__setLoadingArt(screenshot) def showHint(self, destId = None, ocean = False): if base.config.GetBool('no-loading-screen', 0) or not (self.locationLabel): return None if ocean: hint = getOceanHint() elif hasattr(base, 'localAvatar'): totalReputation = 0 level = base.localAvatar.getLevel() if totalReputation: hint = getHint(destId, level) else: hint = getHint(destId) else: hint = getHint() shipPVPIslands = [ '1196970035.53sdnaik', '1196970080.56sdnaik'] if (destId in shipPVPIslands or ocean) and base.localAvatar.getCurrentIsland() in shipPVPIslands: hint = getPrivateeringHint() if self.parent and base.localAvatar.style.getTutorial() == PiratesGlobals.TUT_MET_JOLLY_ROGER: hint = '%s: %s' % (PLocalizer.LoadingScreen_Hint, PLocalizer.GeneralTip7) self._FancyLoadingScreen__setHintText(hint) def update(self, task = None): if not (self.state) or self.analyzeMode: return Task.cont realTime = globalClock.getRealTime() if realTime - self.lastUpdateTime < 0.10000000000000001: return Task.cont self.currentTime += min(10, (realTime - self.lastUpdateTime) * 250) self.lastUpdateTime = realTime if self.debugMode: self.overallLabel['text'] = '%3.1f' % (self.overallPercent / self.loadScale) self.tickLabel['text'] = '%3.1f' % (self.currPercent * 100.0) else: self.percentLabel['text'] = '%d%%' % (self.overallPercent / self.loadScale) if self.currStage != 'unmapped': if self.debugMode: self.currPoly.detachNode() self.stepCard.setFrame((self.lastPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, (self.overallPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, 0.20000000000000001, 0.40000000000000002) self.currPoly = self.loadingBarRoot.attachNewNode(self.stepCard.generate()) if not self.debugMode: self.loadingBar.setSx((self.overallPercent / self.loadScale) * 3.3999999999999999) if self.overallPercent > 0: self.loadingPlank.show() base.eventMgr.doEvents() base.graphicsEngine.renderFrame() return Task.cont def hide(self, reallyHide = not (config.GetInt('loading-screen', 0) == 2)): if not self.state: return None if not reallyHide: if not self.analyzeMode: self.loadingEnd = globalClock.getRealTime() self.accept('shift', self.hide, extraArgs = [ 1]) self.enterToContinue.show() self.generateAnalysis() return None self.cleanupLoadingScreen() if self.debugMode: self.enterToContinue.hide() self.ignore('shift') self.root.hide() self.root.stash() render2d.show() render2dp.show() render.show() base.graphicsEngine.renderFrame() self.state = False self.currentTime = 0 self.locationText = None self.hintText = None self.currScreenshot = None gsg = base.win.getGsg() if gsg: gsg.setIncompleteRender(True) render.prepareScene(gsg) render2d.prepareScene(gsg) taskMgr.remove('updateLoadingScreen') self.allowLiveFlatten.clearValue() base.setTaskChainNetThreaded() if base.sfxManagerList: index = 0 while index < len(base.sfxManagerList): sfx_manager = base.sfxManagerList[index] sfx_manager.setVolume(base.options.sound_volume) index += 1 messenger.send('texture_state_changed') if base.appRunner: base.appRunner.notifyRequest('onLoadingMessagesStop') def showTarget(self, targetId = None, ocean = False, jail = False, pickapirate = False, exit = False, potionCrafting = False, benchRepair = False, shipRepair = False, cannonDefense = False, fishing = False): if base.config.GetBool('no-loading-screen', 0): return None if pickapirate: screenshot = screenShot_EnterGame elif exit: screenshot = screenShot_ExitGame elif ocean: screenshot = screenShot_Dinghy elif jail: screenshot = screenShot_Jail elif potionCrafting: screenshot = screenShot_Potions elif benchRepair: screenshot = screenShot_BenchRepair elif shipRepair: screenshot = screenShot_ShipRepair elif cannonDefense: screenshot = screenShot_CannonDefense elif fishing: screenshot = screenShot_Fishing elif base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_GOT_CUTLASS: screenshot = screenShot_Weapon elif base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_MET_JOLLY_ROGER: screenshot = screenShot_Cutlass elif base.cr.newsManager and base.cr.newsManager.getHoliday(21): screenshot = screenShots_WinterHolidayLocations.get(targetId) if not screenshot: screenshot = screenShots_Locations.get(targetId) else: screenshot = screenShots_Locations.get(targetId) if not screenshot: if areaType_Jungles.has_key(targetId): screenshot = random.choice(screenShots_Jungles) elif areaType_Swamps.has_key(targetId): screenshot = random.choice(screenShots_Swamps) elif areaType_Caves.has_key(targetId): screenshot = random.choice(screenShots_Caves) else: island = getParentIsland(targetId) screenshot = screenShots_Locations.get(island, [ random.choice(screenShots)])[0] if isinstance(screenshot, list): screenshot = random.choice(screenshot) self._FancyLoadingScreen__setLoadingArt(screenshot) if pickapirate: targetName = PLocalizer.LoadingScreen_PickAPirate elif exit: targetName = None elif ocean: targetName = PLocalizer.LoadingScreen_Ocean elif jail: targetName = PLocalizer.LoadingScreen_Jail else: targetName = PLocalizer.LocationNames.get(targetId) base.setLocationCode('Loading: %s' % targetName) if targetName is None: return None if len(targetName): self._FancyLoadingScreen__setLocationText(targetName) def _FancyLoadingScreen__setLoadingArt(self, screenshot): if self.currScreenshot: return None if self.parent and hasattr(base, 'localAvatar') and base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_MET_JOLLY_ROGER and screenshot not in tutorialShots: screenshot = random.choice(tutorialShots) try: self.currScreenshot = loader.loadModel(screenshot).findAllTextures()[0] except: self.currScreenshot = loader.loadModel(random.choice(screenshot)).findAllTextures()[0] if not self.debugMode: self.screenshot.setTexture(self.currScreenshot) def _FancyLoadingScreen__setLocationText(self, locationText): if self.debugMode: return None self.locationText = locationText if not self.locationText: self.locationText = '' self.titlePlank.hide() if len(self.locationText) > 12: scaleFactor = len(self.locationText) / 12.0 self.titlePlankMiddle.setSx(scaleFactor) self.titlePlankRight.setX(0.215 * scaleFactor - 0.215) self.titlePlankLeft.setX(-1 * (0.215 * scaleFactor - 0.215)) else: self.titlePlankMiddle.setSx(1) self.titlePlankRight.setX(0) self.titlePlankLeft.setX(0) self.locationLabel['text'] = self.locationText if self._FancyLoadingScreen__isVisible() and len(self.locationText): self.locationLabel.show() self.titlePlank.show() else: self.locationLabel.hide() self.titlePlank.hide() launcher.setValue('gameLocation', self.locationText) def _FancyLoadingScreen__setHintText(self, hintText): self.hintText = hintText if not self.hintText: self.hintText = '' self.hintLabel['text'] = self.hintText if self._FancyLoadingScreen__isVisible(): self.hintLabel.show() def _FancyLoadingScreen__isVisible(self): return self.state def scheduleHide(self, function): base.cr.queueAllInterestsCompleteEvent() self.acceptOnce(function, self.interestComplete) def interestComplete(self): self.endStep('scheduleHide') self.hide() def _FancyLoadingScreen__setAdArt(self): return None imageFrame = self.model.find('**/frame') randomImageNumber = random.randint(0, len(screenShots) - 1) imageFileName = screenShots[randomImageNumber] self.adImage = loader.loadModel(imageFileName) self.adImage.reparentTo(imageFrame) self.adImage.setScale(2.1499999999999999 * 5, 1, 1.2 * 5) self.adImage.setPos(0, 0, 2.2999999999999998) self.adImage.setBin('fixed', 1) if randomImageNumber == 0: urlToGet = 'http://log.go.com/log?srvc=dis&guid=951C36F8-3ACD-4EB2-9F02-8E8A0A217AF5&drop=0&addata=3232:64675:408091:64675&a=0' self.httpSession = HTTPClient() self.nonBlockHTTP = self.httpSession.makeChannel(False) self.nonBlockHTTP.beginGetDocument(DocumentSpec(urlToGet)) instanceMarker = 'FunnelLoggingRequest-%s' % str(random.randint(1, 1000)) self.startCheckingAsyncRequest(instanceMarker) def startCheckingAsyncRequest(self, name): taskMgr.remove(name) taskMgr.doMethodLater(0.5, self.pollAdTask, name) def pollAdTask(self, task): result = self.nonBlockHTTP.run() if result == 0: self.stopCheckingAdTask(task) else: return Task.again def stopCheckingAdTask(self, name): taskMgr.remove(name) def cleanupLoadingScreen(self): if self.debugMode: self.loadingBarRoot.removeChildren() self.cleanupAnalysis() self.stepInfo = { } self.unmappedTicks = [] def showInfo(self, stepName, pos): self.stageLabel['text'] = stepName info = self.stepInfo[stepName] self.tickLabel['text'] = '%s ticks(%s)' % (len(info[3]), info[6]) self.overallLabel['text'] = '%3.2f seconds (%d%%)' % (info[1], 100 * info[1] / (self.loadingEnd - self.loadingStart)) def generateAnalysis(self): if self.analyzeMode: self.cleanupAnalysis() self.analyzeMode = True cm = CardMaker('cm') self.analysisBar.show() loadingTime = self.loadingEnd - self.loadingStart for stepName in self.stepInfo: (startTime, duration, color, ticks, startPercent, percent, expectedTicks) = self.stepInfo[stepName] cm.setName(stepName) cm.setColor(color) cm.setFrame((startTime / loadingTime) * 1.8 - 0.90000000000000002, ((startTime + duration) / loadingTime) * 1.8 - 0.90000000000000002, -0.5, -0.10000000000000001) self.analysisBarRoot.attachNewNode(cm.generate()) button = DirectFrame(parent = self.analysisBarRoot, geom = NodePath('empty'), image = NodePath('empty'), state = DGG.NORMAL, relief = None, frameSize = ((startTime / loadingTime) * 1.8 - 0.90000000000000002, ((startTime + duration) / loadingTime) * 1.8 - 0.90000000000000002, -0.5, -0.10000000000000001)) button.bind(DGG.ENTER, self.showInfo, extraArgs = [ stepName]) self.analysisButtons.append(button) button = DirectFrame(parent = self.analysisBarRoot, geom = NodePath('empty'), image = NodePath('empty'), state = DGG.NORMAL, relief = None, frameSize = ((startPercent / self.loadScale / 100.0) * 1.8 - 0.90000000000000002, ((startPercent + percent) / self.loadScale / 100.0) * 1.8 - 0.90000000000000002, 0.10000000000000001, 0.5)) button.bind(DGG.ENTER, self.showInfo, extraArgs = [ stepName]) self.analysisButtons.append(button) for tick in ticks: self.line.moveTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.5)) self.line.drawTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.55000000000000004)) for tick in self.unmappedTicks: self.line.moveTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.5)) self.line.drawTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.55000000000000004)) self.analysisSegs = self.analysisBarRoot.attachNewNode(self.line.create()) def cleanupAnalysis(self): for button in self.analysisButtons: button.destroy() self.analysisButtons = [] self.analysisBarRoot.removeChildren() self.analysisBar.hide() self.analyzeMode = False self.analysisSegs = None def adjustSize(self, window): x = max(1, window.getXSize()) y = max(1, window.getYSize()) minSz = min(x, y) aspect = float(x) / y if x > y: self.topLock.setZ(1) else: self.topLock.setZ(float(y) / x) if minSz > IDEALX: self.topLock.setScale(IDEALX / float(x)) elif minSz > IDEALY: self.topLock.setScale(IDEALY / float(y)) else: self.topLock.setScale(1.0)
def __init__(self): ShowBase.__init__(self) props = WindowProperties() props.setTitle('Differentiable Physics Engine') self.win.requestProperties(props) self.t = 0 self.starttime = time.time() #self.setFrameRateMeter(True) cour = self.loader.loadFont('cmtt12.egg') self.textObject = None #OnscreenText(font= cour, text = 'abcdefghijklmnopqrstuvwxyz', pos=(0, -0.045), parent = self.a2dTopCenter, bg=(0,0,0,0.5), fg =(1,1,1,1), scale = 0.07, mayChange=True) cm = CardMaker("ground") cm.setFrame(-2000, 2000, -2000, 2000) cm.setUvRange(Point2(-2000 / 5, -2000 / 5), Point2(2000 / 5, 2000 / 5)) tmp = self.render.attachNewNode(cm.generate()) tmp.reparentTo(self.render) self.camLens.setNear(0.1) tmp.setPos(0, 0, 0) tmp.lookAt((0, 0, -2)) tmp.setColor(1.0, 1.0, 1.0, 0.) tmp.setTexScale(TextureStage.getDefault(), 1, 1) tex = self.loader.loadTexture('textures/grid2.png') tex.setWrapU(Texture.WMRepeat) tex.setWrapV(Texture.WMRepeat) tmp.setTexture(tex, 1) self.setBackgroundColor(0.0, 191.0 / 255.0, 1.0, 1.0) #color of the sky ambientLight = AmbientLight('ambientLight') ambientLight.setColor(Vec4(0.2, 0.2, 0.2, 1)) ambientLightNP = self.render.attachNewNode(ambientLight) self.render.setLight(ambientLightNP) # Directional light 01 directionalLight = DirectionalLight('directionalLight') directionalLight.setColor(Vec4(0.8, 0.8, 0.8, 1)) directionalLightNP = self.render.attachNewNode(directionalLight) # This light is facing backwards, towards the camera. directionalLightNP.setHpr(-120, -50, 0) directionalLightNP.node().setScene(self.render) directionalLightNP.node().setShadowCaster(True) directionalLightNP.node().getLens().setFov(40) directionalLightNP.node().getLens().setNearFar(10, 100) self.render.setLight(directionalLightNP) # Add the spinCameraTask procedure to the task manager. self.taskMgr.add(self.spinCameraTask, "SpinCameraTask") self.physics = Rigid3DBodyEngine() # Load the environment model. self.objects = dict() #self.load_robot_model("robotmodel/test.json") #self.load_robot_model("robotmodel/predator.json") #self.load_robot_model("robotmodel/full_predator.json") #self.load_robot_model("robotmodel/demi_predator.json") #self.load_robot_model("robotmodel/ball.json") self.load_robot_model("robotmodel/biped.json") #self.load_robot_model("robotmodel/robot_arm_mini.json") self.physics.compile() self.step = np.zeros(shape=(16, ))
def __init__(self, parent): DirectObject.DirectObject.__init__(self) self.debugMode = config.GetInt('loading-screen') == 2 self.parent = parent self.state = False self.currScreenshot = None self.snapshot = None self.snapshotFrame = None self.snapshotFrameBasic = None self.currentTime = 0 self.analyzeMode = False self.loadScale = 1.0 self.unmappedTicks = [] self.stepInfo = { } self.accept(base.win.getWindowEvent(), self.adjustSize) self.accept('tick', self.tick) self.currStage = 'unmapped' self.stagePercent = 0 self.numObjects = 0 self.currPercent = 0.0 self.line = LineSegs() self.line.setColor((0, 0, 0, 1)) self.line.setThickness(1) self.stageLabel = None self.currNum = 0 self.overallPercent = 0 self.lastPercent = 0 self.topLock = aspect2dp.attachNewNode('topShift') self.root = self.topLock.attachNewNode('loadingScreenRoot') self.root.setZ(-1) self.root.stash() self.model = loader.loadModel('models/gui/pir_m_gui_gen_loadScreen.bam') self.model.setP(90) self.model.reparentTo(self.root) cm = CardMaker('backdrop') cm.setFrame(-10, 10, -10, 10) if self.debugMode: self.backdrop = self.root.attachNewNode(cm.generate()) self.backdrop.setX(-1.5) self.backdrop.setZ(-1) self.backdrop.setScale(4) self.backdrop.setColor(0.5, 0.5, 0.5, 1) cm = CardMaker('loadingBarBase') cm.setFrame(-0.90000000000000002, 0.90000000000000002, 0.10000000000000001, 0.5) self.loadingBarBacking = self.root.attachNewNode(cm.generate()) self.loadingBarRoot = self.root.attachNewNode('loadingBarRoot') cm.setName('analysisBarBase') cm.setFrame(-0.90000000000000002, 0.90000000000000002, -0.5, -0.10000000000000001) self.analysisBar = self.root.attachNewNode(cm.generate()) self.analysisBarRoot = self.root.attachNewNode('analysisBarRoot') self.analysisBar.hide() self.analysisButtons = [] self.enterToContinue = DirectLabel(parent = self.root, text = 'Press Shift To Continue', relief = None, text_scale = 0.10000000000000001, pos = (0, 0, -0.90000000000000002), text_align = TextNode.ACenter) self.enterToContinue.hide() self.stageLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (-1.25, 0, 0.75), text_align = TextNode.ALeft, textMayChange = 1) self.tickLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (0.75, 0, 0.75), textMayChange = 1) self.overallLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (0, 0, -0.75), textMayChange = 1) else: self.backdrop = loader.loadModel('models/gui/pir_m_gui_gen_loadScreen') self.backdrop.reparentTo(self.root) bg = self.backdrop.find('**/expandable_bg') bg.setScale(1000, 1, 1000) bg.flattenStrong() self.backdrop.find('**/loadbar_grey').setColorScale(0.14999999999999999, 0.14999999999999999, 0.14999999999999999, 0.10000000000000001) self.loadingBar = self.backdrop.find('**/loadbar') self.loadingBar.setColorScale(0.20000000000000001, 0.59999999999999998, 0.5, 1) self.loadingPlank = NodePathCollection() self.loadingPlank.addPath(self.backdrop.find('**/plank_loading_bar')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar_frame')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar_grey')) self.titlePlank = self.backdrop.find('**/plank_title') self.percentLabel = DirectLabel(text = '0%', parent = self.root, relief = None, text_font = PiratesGlobals.getPirateFont(), text_fg = PiratesGuiGlobals.TextFG2, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = 0.031, pos = (0, 0, -0.44450000000000001), textMayChange = 1) self.loadingPlank.addPath(self.percentLabel) self.screenshot = self.backdrop.find('**/screenshot') copyGeom = self.loadingBar.find('**/+GeomNode').node().getGeom(0) format = copyGeom.getVertexData().getFormat() primitive = copyGeom.getPrimitive(0) data = GeomVertexData(self.screenshot.node().getGeom(0).getVertexData()) data.setFormat(format) writer = GeomVertexWriter(data, 'texcoord') writer.setData2f(0, 0) writer.setData2f(1, 0) writer.setData2f(1, 1) writer.setData2f(0, 1) geom = Geom(data) geom.addPrimitive(primitive) self.screenshot.node().removeGeom(0) self.screenshot.node().addGeom(geom) self.titlePlankMiddle = self.backdrop.find('**/plank_title_middle_box') self.titlePlankLeft = self.backdrop.find('**/plank_title_left') self.titlePlankRight = self.backdrop.find('**/plank_title_right') self.loadingBarColors = [ (((i % 10) / 10.0 + 0.5) / 2.0, ((i % 100) / 10 / 10.0 + 0.5) / 2.0, (i / 100 / 10.0 + 0.5) / 2.0, 1) for i in range(1000) ] random.shuffle(self.loadingBarColors) self.lastUpdateTime = globalClock.getRealTime() self.locationLabel = DirectLabel(parent = self.root, relief = None, text = '', text_font = PiratesGlobals.getPirateOutlineFont(), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = PiratesGuiGlobals.TextScaleTitleJumbo * 0.69999999999999996, text_align = TextNode.ACenter, pos = (0.0, 0.0, 0.51500000000000001), textMayChange = 1) self.locationText = None self.hintLabel = DirectLabel(parent = self.root, relief = None, text = '', text_font = PiratesGlobals.getPirateOutlineFont(), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = PiratesGuiGlobals.TextScaleTitleJumbo * 0.5, text_align = TextNode.ACenter, pos = (0.0, 0.0, -0.62), text_wordwrap = 30, textMayChange = 1) self.hintText = None self.adImage = None self.allowLiveFlatten = ConfigVariableBool('allow-live-flatten') self.title_art = [] self.tempVolume = [] self.adjustSize(base.win) gsg = base.win.getGsg() if gsg: self.root.prepareScene(gsg)
def _build_grid(self): color = getattr(self.parameters, "color", (0, 0, 0, 0)) node = NodePath(self.identifier) sx = self.grid.maxx - self.grid.minx + 1 sy = self.grid.maxy - self.grid.miny + 1 # 1. the squares squares = {} card = CardMaker('') cardgeom = NodePath(card.generate()) for n in range(sx): for nn in range(sy): square = NodePath(self.identifier + '-square-%d-%d' % (n + 1, nn + 1)) cardgeom.instanceTo(square) square.setPos(float(n) / sx, 0, -float(nn + 1) / sy) square.setScale(1.0 / sx, 1, 1.0 / sy) square.setColor(0, 0, 0, 1) square.reparentTo(node) squares[n, nn] = square #2: the lines gnode = GeomNode(self.identifier + "-lines") vformat = GeomVertexFormat.getV3cp() vdata = GeomVertexData(self.identifier + '-lines', vformat, Geom.UHStatic) v_vertex = GeomVertexWriter(vdata, 'vertex') v_colors = GeomVertexWriter(vdata, 'color') for n in range(sx + 1): px = float(n) / sx v_vertex.addData3f(px, 0.0, 0.0) v_colors.addData4f(*color) v_vertex.addData3f(px, 0, -1) v_colors.addData4f(*color) for n in range(sy + 1): py = float(n) / sy v_vertex.addData3f(0.0, 0.0, -py) v_colors.addData4f(*color) v_vertex.addData3f(1.0, 0, -py) v_colors.addData4f(*color) geom = Geom(vdata) prim = GeomLines(Geom.UHStatic) for n in range(sx + 1): prim.addVertex(2 * n) prim.addVertex(2 * n + 1) for n in range(sy + 1): prim.addVertex(2 * (sx + n + 1)) prim.addVertex(2 * (sx + n + 1) + 1) prim.closePrimitive() geom.addPrimitive(prim) gnode.addGeom(geom) node1 = NodePath(gnode) node1.reparentTo(node) self.node, self.squares, self.sx, self.sy = node, squares, sx, sy self.node.reparentTo(self.parentnode)
global pipeline pipeline = simplepbr.init( msaa_samples=1, max_lights=8, #enable_shadows=True, ) pipeline.use_normal_maps = False pipeline.use_emission_maps = True pipeline.use_occlusion_maps = True cm = CardMaker('card') cm.set_frame(-1, 1, -1, 1) card_np = base.render.attach_new_node(cm.generate()) mat = Material() mat.set_base_color((1.0, 1.0, 1.0, 1)) mat.set_emission((1.0, 1.0, 1.0, 1)) mat.set_metallic(1.0) mat.set_roughness(1.0) card_np.set_material(mat) texture_size = 256 texture_bands_x = 2 texture_bands_y = 2
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) base.setBackgroundColor(0, 0, 0) self.accept("escape", sys.exit) # Escape quits self.disableMouse() camera.setPosHpr(0, 0, 0, 0, 0, 0) lens = PerspectiveLens() lens.setFov(90, 60) lens.setNear(0.01) lens.setFar(100000) self.cam.node().setLens(lens) self.ballSize = 0.025 self.cueLength = 0.2 # self.ballRoot = render.attachNewNode("ballRoot") # #self.ball = loader.loadModel("models/ball") # self.ball = loader.loadModel("models/ball_0_center.egg") # #self.ball = loader.loadModel("models/ball.dae") # self.ball.setScale(ballSize, ballSize, ballSize) # self.ball.reparentTo(self.ballRoot) # #print(self.ball.getBounds()) # #exit(1) # #self.ballSphere = self.ball.find("**/ball") # #print(self.ball.getScale()[0]) # cs = CollisionSphere(0, 0, 0, 1) # self.ballSphere = self.ball.attachNewNode(CollisionNode('ball')) # self.ballSphere.node().addSolid(cs) # self.ballSphere.node().setFromCollideMask(BitMask32.bit(0)) # self.ballSphere.node().setIntoCollideMask(BitMask32.bit(1)) self.sceneIndex = 2 self.planeInfo = PlaneScene(self.sceneIndex) self.planeScene = self.planeInfo.generateEggModel() self.planeScene.setTwoSided(True) self.planeScene.reparentTo(render) self.planeScene.hide() planeTriangles, horizontalPlaneTriangles, self.gravityDirection = self.planeInfo.getPlaneTriangles( ) self.ballRoots = [] self.balls = [] self.ballSpheres = [] self.ballGroundRays = [] for ballIndex in xrange(3): ballRoot = render.attachNewNode("ballRoot_" + str(ballIndex)) ball = loader.loadModel("models/ball_" + str(ballIndex) + "_center.egg") ball.setScale(self.ballSize, self.ballSize, self.ballSize) cs = CollisionSphere(0, 0, 0, 1) ballSphere = ball.attachNewNode( CollisionNode('ball_' + str(ballIndex))) ballSphere.node().addSolid(cs) ballSphere.node().setFromCollideMask( BitMask32.bit(0) | BitMask32.bit(1) | BitMask32.bit(3) | BitMask32.bit(4)) ballSphere.node().setIntoCollideMask(BitMask32.bit(1)) ball.reparentTo(ballRoot) self.ballRoots.append(ballRoot) self.balls.append(ball) self.ballSpheres.append(ballSphere) ballGroundRay = CollisionRay() # Create the ray ballGroundRay.setOrigin(0, 0, 0) # Set its origin ballGroundRay.setDirection( self.gravityDirection[0], self.gravityDirection[1], self.gravityDirection[2]) # And its direction # Collision solids go in CollisionNode # Create and name the node ballGroundCol = CollisionNode('ball_ray_' + str(ballIndex)) ballGroundCol.addSolid(ballGroundRay) # Add the ray ballGroundCol.setFromCollideMask( BitMask32.bit(2)) # Set its bitmasks ballGroundCol.setIntoCollideMask(BitMask32.allOff()) # Attach the node to the ballRoot so that the ray is relative to the ball # (it will always be 10 feet over the ball and point down) ballGroundColNp = ballRoot.attachNewNode(ballGroundCol) self.ballGroundRays.append(ballGroundColNp) ballRoot.hide() continue # Finally, we create a CollisionTraverser. CollisionTraversers are what # do the job of walking the scene graph and calculating collisions. # For a traverser to actually do collisions, you need to call # traverser.traverse() on a part of the scene. Fortunately, ShowBase # has a task that does this for the entire scene once a frame. By # assigning it to self.cTrav, we designate that this is the one that # it should call traverse() on each frame. self.cTrav = CollisionTraverser() # Collision traversers tell collision handlers about collisions, and then # the handler decides what to do with the information. We are using a # CollisionHandlerQueue, which simply creates a list of all of the # collisions in a given pass. There are more sophisticated handlers like # one that sends events and another that tries to keep collided objects # apart, but the results are often better with a simple queue self.cHandler = CollisionHandlerQueue() # Now we add the collision nodes that can create a collision to the # traverser. The traverser will compare these to all others nodes in the # scene. There is a limit of 32 CollisionNodes per traverser # We add the collider, and the handler to use as a pair #self.cTrav.addCollider(self.ballSphere, self.cHandler) for ballSphere in self.ballSpheres: self.cTrav.addCollider(ballSphere, self.cHandler) continue for ballGroundRay in self.ballGroundRays: self.cTrav.addCollider(ballGroundRay, self.cHandler) continue #self.cTrav.addCollider(self.ballGroundColNp, self.cHandler) # Collision traversers have a built in tool to help visualize collisions. # Uncomment the next line to see it. #self.cTrav.showCollisions(render) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(LVector3(0, 0, -1)) directionalLight.setColor((0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) for ballRoot in self.ballRoots: ballRoot.setLight(render.attachNewNode(ambientLight)) ballRoot.setLight(render.attachNewNode(directionalLight)) continue # This section deals with adding a specular highlight to the ball to make # it look shiny. Normally, this is specified in the .egg file. m = Material() m.setSpecular((1, 1, 1, 1)) m.setShininess(96) for ball in self.balls: ball.setMaterial(m, 1) continue self.original = False if self.original: camera.setPosHpr(0, 0, 25, 0, -90, 0) self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) self.walls = self.maze.find("**/wall_collide") self.walls.node().setIntoCollideMask(BitMask32.bit(0)) self.walls.show() pass #planeTriangles, planeNormals = self.planeInfo.getPlaneGeometries() self.triNPs = [] for triangleIndex, triangle in enumerate(planeTriangles): #print(triangleIndex) #for triangle in triangles: #print(triangle) tri = CollisionPolygon( Point3(triangle[0][0], triangle[0][1], triangle[0][2]), Point3(triangle[1][0], triangle[1][1], triangle[1][2]), Point3(triangle[2][0], triangle[2][1], triangle[2][2])) triNP = render.attachNewNode( CollisionNode('tri_' + str(triangleIndex))) triNP.node().setIntoCollideMask(BitMask32.bit(0)) triNP.node().addSolid(tri) self.triNPs.append(triNP) #triNP.show() continue #print(horizontalPlaneTriangles) for triangleIndex, triangle in enumerate(horizontalPlaneTriangles): #print(triangleIndex) #for triangle in triangles: #print(triangle) tri = CollisionPolygon( Point3(triangle[0][0], triangle[0][1], triangle[0][2]), Point3(triangle[1][0], triangle[1][1], triangle[1][2]), Point3(triangle[2][0], triangle[2][1], triangle[2][2])) triNP = render.attachNewNode( CollisionNode('ground_' + str(triangleIndex))) triNP.node().setIntoCollideMask(BitMask32.bit(2)) triNP.node().addSolid(tri) self.triNPs.append(triNP) #triNP.show() continue # tri = CollisionPolygon(Point3(-1, 4, -1), Point3(2, 4, -1), Point3(2, 4, 2)) # triNP = render.attachNewNode(CollisionNode('tri')) # triNP.node().setIntoCollideMask(BitMask32.bit(0)) # triNP.node().addSolid(tri) # triNP.show() #self.planeScene.node().setIntoCollideMask(BitMask32.bit(0)) # roomRootNP = self.planeScene # roomRootNP.flattenLight() # mesh = BulletTriangleMesh() # polygons = roomRootNP.findAllMatches("**/+GeomNode") # # p0 = Point3(-10, 4, -10) # # p1 = Point3(-10, 4, 10) # # p2 = Point3(10, 4, 10) # # p3 = Point3(10, 4, -10) # # mesh.addTriangle(p0, p1, p2) # # mesh.addTriangle(p1, p2, p3) # print(polygons) # for polygon in polygons: # geom_node = polygon.node() # #geom_node.reparentTo(self.render) # #print(geom_node.getNumGeoms()) # ts = geom_node.getTransform() # #print(ts) # for geom in geom_node.getGeoms(): # mesh.addGeom(geom, ts) # continue # continue # #self.scene = roomRootNP # shape = BulletTriangleMeshShape(mesh, dynamic=False) # #shape = BulletPlaneShape(Vec3(0, 0, 1), 1) # room = BulletRigidBodyNode('scene') # room.addShape(shape) # #room.setLinearDamping(0.0) # #room.setFriction(0.0) # print(shape) # room.setDeactivationEnabled(False) # roomNP = render.attachNewNode(room) # roomNP.setPos(0, 0, 0) # roomNP.node().setIntoCollideMask(BitMask32.bit(0)) # self.world = BulletWorld() # self.world.setGravity(Vec3(0, 0, 0)) # self.world.attachRigidBody(roomNP.node()) #room.setRestitution(1) #self.roomNP = self.scene self.cueRoot = render.attachNewNode("cueRoot") self.cue = loader.loadModel("models/cue_center.egg") self.cue.setScale(self.cueLength * 3, self.cueLength * 3, self.cueLength) self.cue.reparentTo(self.cueRoot) self.cuePos = (10, 0, 0) self.pickerNode = CollisionNode('mouseRay') # Attach that node to the camera since the ray will need to be positioned # relative to it self.pickerNP = camera.attachNewNode(self.pickerNode) # Everything to be picked will use bit 1. This way if we were doing other # collision we could separate it self.pickerNode.setFromCollideMask(BitMask32.bit(2)) self.pickerNode.setIntoCollideMask(BitMask32.allOff()) self.pickerRay = CollisionRay() # Make our ray # Add it to the collision node self.pickerNode.addSolid(self.pickerRay) # Register the ray as something that can cause collisions self.cTrav.addCollider(self.pickerNP, self.cHandler) self.accept("mouse1", self.hit) # left-click grabs a piece self.holeLength = 0.06 holePos, holeHpr = self.planeInfo.getHolePos() self.holeRoot = render.attachNewNode("holeRoot") #self.hole = loader.loadModel("models/hole_horizontal_center.egg") self.hole = loader.loadModel("models/hole_color.egg") #self.hole = loader.loadModel("models/billiards_hole_center.egg") self.hole.setScale(self.holeLength, self.holeLength, self.holeLength) self.hole.reparentTo(self.holeRoot) self.hole.setTwoSided(True) self.holeRoot.setPos(holePos[0], holePos[1], holePos[2]) self.holeRoot.setHpr(holeHpr[0], holeHpr[1], holeHpr[2]) #tex = loader.loadTexture('models/Black_Hole.jpg') #self.hole.setTexture(tex, 1) self.holeRoot.hide() ct = CollisionTube(0, 0, 0, 0, 0.001, 0, 0.5) self.holeTube = self.hole.attachNewNode(CollisionNode('hole')) self.holeTube.node().addSolid(ct) self.holeTube.node().setFromCollideMask(BitMask32.allOff()) self.holeTube.node().setIntoCollideMask(BitMask32.bit(4)) #self.holeTube.show() inPortalPos, inPortalHpr, outPortalPos, outPortalHpr, self.portalNormal = self.planeInfo.getPortalPos( ) self.portalLength = 0.06 self.inPortalRoot = render.attachNewNode("inPortalRoot") self.inPortal = loader.loadModel("models/portal_2_center.egg") self.inPortal.setScale(self.portalLength, self.portalLength, self.portalLength) self.inPortal.reparentTo(self.inPortalRoot) self.inPortalRoot.setPos(inPortalPos[0], inPortalPos[1], inPortalPos[2]) self.inPortalRoot.setHpr(inPortalHpr[0], inPortalHpr[1], inPortalHpr[2]) self.inPortalRoot.hide() ct = CollisionTube(0, 0, 0, 0, 0.001, 0, 1) self.inPortalTube = self.inPortal.attachNewNode( CollisionNode('portal_in')) self.inPortalTube.node().addSolid(ct) self.inPortalTube.node().setFromCollideMask(BitMask32.allOff()) self.inPortalTube.node().setIntoCollideMask(BitMask32.bit(3)) #self.inPortalTube.hide() self.outPortalRoot = render.attachNewNode("outPortalRoot") self.outPortal = loader.loadModel("models/portal_2_center.egg") self.outPortal.setScale(self.portalLength, self.portalLength, self.portalLength) self.outPortal.reparentTo(self.outPortalRoot) self.outPortalRoot.setPos(outPortalPos[0], outPortalPos[1], outPortalPos[2]) self.outPortalRoot.setHpr(outPortalHpr[0], outPortalHpr[1], outPortalHpr[2]) self.outPortalRoot.hide() ct = CollisionTube(0, 0, 0, 0, 0.001, 0, 1) self.outPortalTube = self.outPortal.attachNewNode( CollisionNode('portal_out')) self.outPortalTube.node().addSolid(ct) self.outPortalTube.node().setFromCollideMask(BitMask32.allOff()) self.outPortalTube.node().setIntoCollideMask(BitMask32.bit(3)) #self.outPortalTube.hide() #self.inPortalTube.show() #self.outPortalTube.show() #self.holeTube.show() #self.cTrav.addCollider(self.holeTube, self.cHandler) background_image = loader.loadTexture('dump/' + str(self.sceneIndex) + '_image.png') cm = CardMaker('background') cm.setHas3dUvs(True) info = np.load('dump/' + str(self.sceneIndex) + '_info.npy') #self.camera = getCameraFromInfo(self.info) depth = 10.0 sizeU = info[2] / info[0] * depth sizeV = info[6] / info[5] * depth cm.setFrame(Point3(-sizeU, depth, -sizeV), Point3(sizeU, depth, -sizeV), Point3(sizeU, depth, sizeV), Point3(-sizeU, depth, sizeV)) self.card = self.render.attachNewNode(cm.generate()) self.card.setTransparency(True) self.card.setTexture(background_image) self.card.hide() self.ballGroundMap = {} self.ballBouncing = np.full(len(self.balls), 3) self.started = False self.start() self.hitIndex = 0 self.showing = 'none' self.showingProgress = 0 partsScene = PartsScene(self.sceneIndex) self.planeNPs, self.planeCenters = partsScene.generateEggModel() return
class CameraApp(GuiHandler): __ImageDir = "data/images" def __init__(self, device): GuiHandler.__init__(self) self.func3 = "Si" self.func2 = "" self.func1 = "No" self.title = "Guardar?" self.parent = device self.video_mode = False option = WebcamVideo.get_option(0) self.texture = MovieTexture(option) self.texture.setKeepRamImage(True) #self.texture = OpenCVTexture() #self.texture.fromCamera() scale = self.texture.getTexScale() print scale #self.texture = OpenCVTexture() self.card = CardMaker('webcam') self.card.setFrame(-scale[0], scale[0], -scale[1], scale[1]) self.card.setUvRange(Point2(scale[0], 0), Point2(0, scale[1])) self.card = render.attachNewNode(self.card.generate()) screen = self.parent.get_screen() self.card.reparentTo(screen.getParent()) self.card.setTransform(screen.getTransform()) self.card.setSx(0.49) self.card.setSz(0.394) self.card.setHpr(0, 270, 0) self.card.setPos(0.004, 0.335, 0.1) self.card.hide() def activate(self, events): self.toggle_view(True) events.add_action("boton_izq1", self.quit) events.add_action("centro", self.shoot) events.add_action("boton_der", self.shoot) events.add_action("boton_izq", self.cancel) def shoot(self): if self.video_mode: max = self.texture.getXSize() * self.texture.getYSize() data = array.array('B') data.fromstring(self.texture.getRamImageAs("BGR1").getData()) img = cairo.ImageSurface.create_for_data( data, cairo.FORMAT_ARGB32, self.texture.getXSize(), self.texture.getYSize(), self.texture.getXSize() * 4) self.cam_shot = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.texture.getVideoWidth(), self.texture.getVideoHeight()) ctx = cairo.Context(self.cam_shot) ctx.set_source_surface(img, 0, 0) ctx.paint() self.paint_background() self.cr.set_source_surface(self.draw_viewer(self.cam_shot), 30, self.top_margin + 5) self.cr.paint() self.paint_foreground() self.surface.write_to_png(self.get_output()) self.parent.repaint() self.toggle_view(False) else: print "Saving..." pic_path = CameraApp.__ImageDir + "/p" + Util.generate_id( ) + ".png" print pic_path self.cam_shot.write_to_png(pic_path) self.toggle_view(True) def paint_scene(self): drawer_width = self.width - 60 drawer_height = 2 * self.height / 3 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.width, self.height) context = cairo.Context(surface) scale_x = float(self.width) / float(self.cam_shot.get_width()) scale_y = float(self.height) / float(self.cam_shot.get_height()) context.scale(scale_x, scale_y) context.set_source_surface(self.cam_shot, 0, 0) context.paint() return surface def cancel(self): self.cam_shot = None self.toggle_view(True) def draw_viewer(self, image_surface): drawer_width = self.width - 60 drawer_height = 2 * self.height / 3 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, drawer_width, drawer_height) context = cairo.Context(surface) context.rectangle(0, 0, drawer_width, drawer_height) context.set_source_rgba(.05, .05, .05, .8) context.fill() context.rectangle(1, 1, drawer_width - 2, drawer_height - 2) context.clip() context.new_path() context.transform( get_transformation_matrix(drawer_width, drawer_height, image_surface.get_width(), image_surface.get_height())) context.set_source_surface(image_surface, 0, 0) context.paint() return surface def paint_background(self): # Fondo gradient = cairo.LinearGradient(0, 0, 0, self.height) gradient.add_color_stop_rgb(0, 0, 0, 0) gradient.add_color_stop_rgb(1, .4, .4, .4) self.cr.set_source(gradient) self.cr.move_to(0, 0) self.cr.line_to(self.width, 0) self.cr.line_to(self.width, self.height) self.cr.line_to(0, self.height) self.cr.close_path() self.cr.fill() def quit(self): self.toggle_view(False) self.parent.launch("menu") def toggle_view(self, video): self.video_mode = video if video: #self.texture.fromCamera() self.card.setTexture(self.texture) print(self.texture.getVideoWidth(), self.texture.getVideoHeight()) self.card.show() self.parent.get_screen().hide() else: #self.texture = OpenCVTexture() self.card.setTexture(self.texture) self.card.hide() self.parent.get_screen().show()
class TextFileSelectionNode(DirectObject, TextFileNode): def __init__(self, name, filename=None, **options): DirectObject.__init__(self) TextFileNode.__init__(self, name, None, **options) self.cardmaker = CardMaker('selection cards') self.selection_cards = [] self.selecting = False self.rect_w, self.rect_h = 1, 1 self.accept('shift', self.toggle_select, extraArgs=[True]) self.accept('shift-up', self.toggle_select, extraArgs=[False]) # Selection editing def clear_rects(self): for card in self.selection_cards: if card in list(self.children): self.remove_child(card) self.selection_cards = [] def draw_rect(self, rect, color=(1,1,1,1)): rx, ry, rw, rh = rect l = ((rx)*self.rect_w) r = ((rx+rw+1)*self.rect_w)-0.2 u = ((ry-1)*self.rect_h)+0.5 d = ((ry+rh)*self.rect_h)+0.3 self.cardmaker.set_frame(l,r,-u,-d) self.cardmaker.set_color(color) card = self.cardmaker.generate() self.add_child(card) return card def draw_line_rect(self, line_number, start, end=0): x = self.line_number_width+start y = line_number-self.line_offset w = len(self.lines[line_number])-start if end: w = min(w,end) self.selection_cards.append(self.draw_rect([x,y,w,0])) def remove_range(self): end, start = self.selection_direction() if start[1] == end[1]: a = self.lines[start[1]][:end[0]] b = self.lines[start[1]][start[0]:] self.lines[start[1]] = a + b self.x, self.y = end else: a = self.lines[start[1]][:start[0]] b = self.lines[end[1]][end[0]:] self.lines[start[1]] = a + b for i in range(1, (end[1]-start[1])+2): self.lines.pop(start[1]+1) self.x, self.y = start def select_range(self): self.clear_rects() self.selection_buffer = [] start, end = self.selection_direction() if start[1] == end[1]: self.draw_line_rect(start[1], end[0], start[0]-end[0]) self.selection_buffer.append(self.lines[start[1]][start[0]:end[0]]) else: if start[0] > 0: self.draw_line_rect(start[1], 0, start[0]) self.selection_buffer.append(self.lines[start[1]][:start[0]]) for i in range(1, start[1]-end[1]): i = start[1] - i self.draw_line_rect(i,0) self.selection_buffer.append(self.lines[i]) self.draw_line_rect(end[1], end[0]) self.selection_buffer.append(self.lines[end[1]][start[0]:]) def selection_direction(self): if self.y > self.selection_start[1]: return (self.x, self.y), self.selection_start else: return self.selection_start, (self.x, self.y) def toggle_select(self, on=True): if len(self.selection_buffer) > 0: already_selecting = True else: already_selecting = False self.selecting = on if self.selecting and not already_selecting: self.selection_start = [self.x, self.y]
class main(ShowBase): def __init__(self): ShowBase.__init__(self) # Disable the default camera movements self.disableMouse() # # VIEW SETTINGS # self.win.setClearColor((0.16, 0.16, 0.16, 1)) render.setAntialias(AntialiasAttrib.MAuto) render2d.setAntialias(AntialiasAttrib.MAuto) # # NODE VIEW # self.viewNP = aspect2d.attachNewNode("viewNP") self.viewNP.setScale(0.5) # # NODE MANAGER # self.nodeMgr = NodeManager(self.viewNP) # # NODE RELATED EVENTS # # Add nodes self.accept("addNode", self.nodeMgr.addNode) # Remove nodes self.accept("removeNode", self.nodeMgr.removeNode) self.accept("x", self.nodeMgr.removeNode) self.accept("delete", self.nodeMgr.removeNode) # Selecting self.accept("selectNode", self.nodeMgr.selectNode) # Deselecting self.accept("mouse3", self.nodeMgr.deselectAll) # Node Drag and Drop self.accept("dragNodeStart", self.setDraggedNode) self.accept("dragNodeMove", self.updateNodeMove) self.accept("dragNodeStop", self.updateNodeStop) # Duplicate/Copy nodes self.accept("shift-d", self.nodeMgr.copyNodes) self.accept("copyNodes", self.nodeMgr.copyNodes) # Refresh node logics self.accept("ctlr-r", self.nodeMgr.updateAllLeaveNodes) self.accept("refreshNodes", self.nodeMgr.updateAllLeaveNodes) # # SOCKET RELATED EVENTS # self.accept("updateConnectedNodes", self.nodeMgr.updateConnectedNodes) # Socket connection with drag and drop self.accept("startPlug", self.nodeMgr.setStartPlug) self.accept("endPlug", self.nodeMgr.setEndPlug) self.accept("connectPlugs", self.nodeMgr.connectPlugs) self.accept("cancelPlug", self.nodeMgr.cancelPlug) # Draw line while connecting sockets self.accept("startLineDrawing", self.startLineDrawing) self.accept("stopLineDrawing", self.stopLineDrawing) # # PROJECT MANAGEMENT # self.accept("new", self.newProject) self.accept("save", self.saveProject) self.accept("load", self.loadProject) self.accept("quit", exit) # # EDITOR VIEW # # Zooming self.accept("zoom", self.zoom) self.accept("zoom_reset", self.zoomReset) self.accept("wheel_up", self.zoom, [True]) self.accept("wheel_down", self.zoom, [False]) # Drag view self.mouseSpeed = 1 self.mousePos = None self.startCameraMovement = False self.accept("mouse2", self.setMoveCamera, [True]) self.accept("mouse2-up", self.setMoveCamera, [False]) # Box select # accept the 1st mouse button events to start and stop the draw self.accept("mouse1", self.startBoxDraw) self.accept("mouse1-up", self.stopBoxDraw) # variables to store the start and current pos of the mousepointer self.startPos = LPoint2f(0, 0) self.lastPos = LPoint2f(0, 0) # variables for the to be drawn box self.boxCardMaker = CardMaker("SelectionBox") self.boxCardMaker.setColor(1, 1, 1, 0.25) self.box = None # # WINDOW RELATED EVENTS # self.screenSize = base.getSize() self.accept("window-event", self.windowEventHandler) # # MENU BAR # self.menuBar = MenuBar() # # TASKS # # Task for handling dragging of the camera/view self.taskMgr.add(self.updateCam, "task_camActualisation", priority=-4) # ------------------------------------------------------------------ # PROJECT FUNCTIONS # ------------------------------------------------------------------ def newProject(self): self.nodeMgr.cleanup() def saveProject(self): Save(self.nodeList, self.connections) def loadProject(self): self.nodeMgr.cleanup() Load(self.nodeMgr) # ------------------------------------------------------------------ # CAMERA SPECIFIC FUNCTIONS # ------------------------------------------------------------------ def setMoveCamera(self, moveCamera): """Start dragging around the editor area/camera""" # store the mouse position if weh have a mouse if base.mouseWatcherNode.hasMouse(): x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() self.mousePos = Point2(x, y) # set the variable according to if we want to move the camera or not self.startCameraMovement = moveCamera def updateCam(self, task): """Task that will move the editor area/camera around according to mouse movements""" # variables to store the mouses current x and y position x = 0.0 y = 0.0 if base.mouseWatcherNode.hasMouse(): # get the mouse position x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() if base.mouseWatcherNode.hasMouse() \ and self.mousePos is not None \ and self.startCameraMovement: # Move the viewer node aspect independent wp = self.win.getProperties() aspX = 1.0 aspY = 1.0 wpXSize = wp.getXSize() wpYSize = wp.getYSize() if wpXSize > wpYSize: aspX = wpXSize / float(wpYSize) else: aspY = wpYSize / float(wpXSize) mouseMoveX = (self.mousePos.getX() - x) / self.viewNP.getScale( ).getX() * self.mouseSpeed * aspX mouseMoveY = (self.mousePos.getY() - y) / self.viewNP.getScale( ).getZ() * self.mouseSpeed * aspY self.mousePos = Point2(x, y) self.viewNP.setX(self.viewNP, -mouseMoveX) self.viewNP.setZ(self.viewNP, -mouseMoveY) self.nodeMgr.updateConnections() # continue the task until it got manually stopped return task.cont def zoom(self, zoomIn): """Zoom the editor in or out dependent on the value in zoomIn""" zoomFactor = 0.05 maxZoomIn = 2 maxZoomOut = 0.1 if zoomIn: s = self.viewNP.getScale() if s.getX() - zoomFactor < maxZoomIn and s.getY( ) - zoomFactor < maxZoomIn and s.getZ() - zoomFactor < maxZoomIn: self.viewNP.setScale(s.getX() + zoomFactor, s.getY() + zoomFactor, s.getZ() + zoomFactor) else: s = self.viewNP.getScale() if s.getX() - zoomFactor > maxZoomOut and s.getY( ) - zoomFactor > maxZoomOut and s.getZ() - zoomFactor > maxZoomOut: self.viewNP.setScale(s.getX() - zoomFactor, s.getY() - zoomFactor, s.getZ() - zoomFactor) self.nodeMgr.updateConnections() def zoomReset(self): """Set the zoom level back to the default""" self.viewNP.setScale(0.5) self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # DRAG LINE # ------------------------------------------------------------------ def startLineDrawing(self, startPos): """Start a task that will draw a line from the given start position to the cursor""" self.line = LineNodePath(render2d, thickness=2, colorVec=(0.8, 0.8, 0.8, 1)) self.line.moveTo(startPos) t = self.taskMgr.add(self.drawLineTask, "drawLineTask") t.startPos = startPos def drawLineTask(self, task): """Draws a line from a given start position to the cursor""" mwn = base.mouseWatcherNode if mwn.hasMouse(): pos = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) self.line.reset() self.line.moveTo(task.startPos) self.line.drawTo(pos) self.line.create() return task.cont def stopLineDrawing(self): """Stop the task that draws a line to the cursor""" taskMgr.remove("drawLineTask") if self.line is not None: self.line.reset() self.line = None # ------------------------------------------------------------------ # EDITOR NODE DRAGGING UPDATE # ------------------------------------------------------------------ def setDraggedNode(self, node): """This will set the node that is currently dragged around as well as update other selected nodes which will be moved in addition to the main dragged node""" self.draggedNode = node self.tempNodePositions = {} for node in self.nodeMgr.selectedNodes: self.tempNodePositions[node] = node.frame.getPos(render2d) def updateNodeMove(self, mouseA, mouseB): """Will be called as long as a node is beeing dragged around""" for node in self.nodeMgr.selectedNodes: if node is not self.draggedNode and node in self.tempNodePositions.keys( ): editVec = Vec3(self.tempNodePositions[node] - mouseA) newPos = mouseB + editVec node.frame.setPos(render2d, newPos) self.nodeMgr.updateConnections() def updateNodeStop(self, node=None): """Will be called when a node dragging stopped""" self.draggedNode = None self.tempNodePositions = {} self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # BASIC WINDOW HANDLING # ------------------------------------------------------------------ def windowEventHandler(self, window=None): """Custom handler for window events. We mostly use this for resizing.""" # call showBase windowEvent which would otherwise get overridden and breaking the app self.windowEvent(window) if window != self.win: # This event isn't about our window. return if window is not None: # window is none if panda3d is not started if self.screenSize == base.getSize(): return self.screenSize = base.getSize() # Resize all editor frames self.menuBar.resizeFrame() # ------------------------------------------------------------------ # SELECTION BOX # ------------------------------------------------------------------ def startBoxDraw(self): """Start drawing the box""" if self.mouseWatcherNode.hasMouse(): # get the mouse position self.startPos = LPoint2f(self.mouseWatcherNode.getMouse()) taskMgr.add(self.dragBoxDrawTask, "dragBoxDrawTask") def stopBoxDraw(self): """Stop the draw box task and remove the box""" if not taskMgr.hasTaskNamed("dragBoxDrawTask"): return taskMgr.remove("dragBoxDrawTask") if self.startPos is None or self.lastPos is None: return self.nodeMgr.deselectAll() if self.box is not None: for node in self.nodeMgr.getAllNodes(): # store some view scales for calculations viewXScale = self.viewNP.getScale().getX() viewZScale = self.viewNP.getScale().getZ() # calculate the node edges nodeLeft = node.getLeft() * viewXScale nodeRight = node.getRight() * viewXScale nodeBottom = node.getBottom() * viewZScale nodeTop = node.getTop() * viewZScale # calculate bounding box edges left = min(self.lastPos.getX(), self.startPos.getX()) right = max(self.lastPos.getX(), self.startPos.getX()) top = max(self.lastPos.getY(), self.startPos.getY()) bottom = min(self.lastPos.getY(), self.startPos.getY()) # check for hits xGood = yGood = False if left < nodeLeft and right > nodeLeft: xGood = True elif left < nodeRight and right > nodeRight: xGood = True if top > nodeTop and bottom < nodeTop: yGood = True elif top > nodeBottom and bottom < nodeBottom: yGood = True # check if we have any hits if xGood and yGood: self.nodeMgr.selectNode(node, True, True) # Cleanup the selection box self.box.removeNode() self.startPos = None self.lastPos = None def dragBoxDrawTask(self, task): """This task will track the mouse position and actualize the box's size according to the first click position of the mouse""" if self.mouseWatcherNode.hasMouse(): if self.startPos is None: self.startPos = LPoint2f(self.mouseWatcherNode.getMouse()) # get the current mouse position self.lastPos = LPoint2f(self.mouseWatcherNode.getMouse()) else: return task.cont # check if we already have a box if self.box != None: # if so, remove that old box self.box.removeNode() # set the box's size self.boxCardMaker.setFrame(self.lastPos.getX(), self.startPos.getX(), self.startPos.getY(), self.lastPos.getY()) # generate, setup and draw the box node = self.boxCardMaker.generate() self.box = render2d.attachNewNode(node) self.box.setBin("gui-popup", 25) self.box.setTransparency(TransparencyAttrib.M_alpha) # run until the task is manually stopped return task.cont
def __init__(self, parent=None, pos=(0, 0, 0), fading=False, fading_position_offset=(0, 0, 0), fading_duration=0.5, backgroundImage=None, backgroundColor=None, enableMask=False, noFocus=False, shownFunc=None, hiddenFunc=None, funcExtraArgs=[], sort=None): '''if fading enabled, it will apply a fading effect on show()&hide() Important Attributes: enableMask: This creates a big transparent plane (DirectButton) off screen so the directGui below won't be clicked (However due to this trick we won't be able to accept mouse events (I have paid back 'mouse3' by self.__maskClick)) noFocus: if it is true, it doesn't need SogalBase to manage its focus state (it will not affect other Sogalforms' focus state ''' self.__fading = fading self.__fadingPositionOffset = fading_position_offset self.__fadingDuration = fading_duration self.__originPos = pos self.__currentInterval = None self.__maskEnabled = enableMask self.__noFocus = noFocus self.__shownFunc = shownFunc self.__hiddenFunc = hiddenFunc self.__eventExtraArgs = funcExtraArgs self.__mask = None if self.__maskEnabled: self.__mask = DialogMask() #self.__mask = DirectButton(parent = aspect2d, frameColor =(1,1,1,0.1), relief = DGG.FLAT,commandButtons = [DGG.RMB],command = self.__maskClick) self.__mask.hide() self.__backgroundImage = backgroundImage self.__backgroundColor = backgroundColor self.__bgPath = None self.__imagePath = None self.__hidden = True NodePath.__init__(self, self.__class__.__name__) parent = parent or aspect2d if sort: self.reparentTo(parent, sort=sort) else: self.reparentTo(parent) self.setPos(pos) if self.__backgroundColor: self.__bgPath = NodePath('bgPath') self.__bgPath.setTransparency(TransparencyAttrib.MAlpha) cm = CardMaker('cm') cm.setFrameFullscreenQuad() cm.setColor(self.__backgroundColor) self.__bgPath.attachNewNode(cm.generate()) self.__bgPath.reparentTo(aspect2d, self.getSort()) self.__bgPath.hide() #TODO: backgroundImage self.setTransparency(TransparencyAttrib.MAlpha) self.accept('window-event', self.windowResize) self.windowResize(None) NodePath.hide(self)
class RaceGUI: GagPie = 0 gagRoot = 'phase_3.5/maps/inventory_' class RacerInfo: def __init__(self, face, mapSpot): self.curvetime = 0 self.maxlaphit = 0 self.face = face self.mapspot = mapSpot self.place = 1 self.enabled = True self.finished = False self.gag = None return def update(self, curvetime=None, maxlaphit=None, faceX=None, mapspotPt=None, place=None, finished=None): if self.enabled: if not curvetime == None: self.curvetime = curvetime if not maxlaphit == None: self.maxlaphit = maxlaphit if not faceX == None: self.face.setX(faceX) if not mapspotPt == None: self.mapspot.setPos(mapspotPt) if not place == None: self.place = place if not finished == None: self.finished = finished return def disable(self): self.enabled = False if not self.finished: self.face.hide() self.mapspot.hide() def enable(self): self.enabled = True self.face.show() self.mapspot.show() def __init__(self, distRace): self.race = distRace self.timerEnabled = False self.maxLapHit = 0 self.photoFinish = False toonInteriorTextures = loader.loadModel( 'phase_3.5/models/modules/toon_interior_textures') invTextures = loader.loadModel('phase_3.5/models/gui/inventory_icons') racingTextures = loader.loadModel( 'phase_6/models/karting/racing_textures') self.gagTextures = [ toonInteriorTextures.find('**/couch'), invTextures.find('**/inventory_bannana_peel'), racingTextures.find('**/boost_arrow'), invTextures.find('**/inventory_anvil'), invTextures.find('**/inventory_creampie') ] self.gagTextures[1].setScale(7.5) self.gagTextures[3].setScale(7.5) self.gagTextures[4].setScale(7.5) self.cardMaker = CardMaker('card') self.racerDict = {} self.render2dRoot = render2d.attachNewNode('RaceGuiRender2dRoot') self.render2dRoot.setDepthWrite(1) self.directObjList = [] self.aspect2dRoot = aspect2d.attachNewNode('RaceGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) self.raceModeRoot = self.aspect2dRoot.attachNewNode('RaceModeRoot') gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=1.05, text=TTLocalizer.KartRace_Leave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(-0.99, 0, 0.925), command=self.race.leaveRace) self.closeButton.reparentTo(self.aspect2dRoot) self.directObjList.append(self.closeButton) self.raceTimeDelta = 0 self.raceModeReady = False self.resultModeReady = False self.gagCycleSound = base.loader.loadSfx( 'phase_3.5/audio/sfx/tick_counter.ogg') if hasattr(self.gagCycleSound, 'setPlayRate'): self.gagCycleSound.setPlayRate(0.2) self.gagCycleSound.setLoop(1) self.gagAcquireSound = base.loader.loadSfx( 'phase_6/audio/sfx/SZ_MM_gliss.ogg') self.disable() return def initRaceMode(self): self.mapScene = base.a2dTopRight.attachNewNode('MapScene') self.mapScene.setPos(-0.2, 0, -0.2) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in range(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.5), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel( relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel( relief=None, pos=(-0.22, 0, -0.2), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence( self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4( 1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4( 1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * ( 1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in range(self.race.lapCount): minLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame( parent=base.a2dBottomLeft, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(0.2, 0, 0.55)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return def initResultMode(self): self.endPanel = RaceEndPanel(len(self.race.avIds), self.race) self.endPanel.reparentTo(self.aspect2dRoot) self.directObjList.append(self.endPanel) self.resultModeReady = True self.disable() def showGag(self, gagIndex): if gagIndex < len(self.gagTextures): for gag in self.gagTextures: gag.hide() self.gagTextures[gagIndex].show() def updateGag(self, gagIndex): if self.gag: if hasattr(self, 'gagCycleInterval'): self.gagCycleInterval.finish() del self.gagCycleInterval self.gag.setHpr(0, 0, 0) self.showGag(gagIndex) if gagIndex == 0: self.gag.hide() else: self.gag.show() self.gagAcquireSound.play() self.gagAcquireInterval = LerpHprInterval(self.gag, duration=0.5, blendType='easeOut', startHpr=Point3( 0, -90, 0), hpr=Point3(0, 0, 0)) self.gagAcquireInterval.start() def waitingOnGag(self, cycleTime): if self.gag: numTextures = len(self.gagTextures) startOffset = random.choice(list(range(0, numTextures))) self.gag.show() self.gagCycleInterval = Parallel( LerpFunc(self.showNextGag, fromData=startOffset, toData=numTextures * 2 * cycleTime + startOffset, blendType='easeOut', duration=cycleTime), LerpHprInterval(self.gag, duration=cycleTime, hpr=Point3( 0, 180 * numTextures * 2 * cycleTime - 90, 0), blendType='easeOut', startHpr=Point3(0, 0, 0)), SoundInterval(self.gagCycleSound, loop=1, duration=cycleTime, startTime=0), name='gagCycleInterval') self.gagCycleInterval.start() def showNextGag(self, t): if self.gag: currGagIndex = int(t % (len(self.gagTextures) - 1)) + 1 self.showGag(currGagIndex) def enableSpeedometer(self): self.race.localKart.showSpeedometer() def disableSpeedometer(self): self.race.localKart.hideSpeedometer() def disableRaceMode(self): self.disableSpeedometer() self.render2dRoot.hide() self.raceModeRoot.hide() for x in self.timeLabels: for y in x: y.hide() self.setTimerEnabled(False) def disableResultMode(self): self.endPanel.disable() def disable(self): self.closeButton.hide() taskMgr.removeTasksMatching('clearRaceEndPanel') if self.raceModeReady: self.disableRaceMode() if self.resultModeReady: self.disableResultMode() def enableRaceMode(self): self.enableSpeedometer() self.render2dRoot.show() self.raceModeRoot.show() self.maxLapHit = min(self.maxLapHit, self.race.lapCount - 1) for x in range(self.maxLapHit + 1): for y in self.timeLabels[x]: y.configure(text_font=ToontownGlobals.getSignFont()) y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) def enableResultMode(self): self.endPanel.enable() if not self.race.circuitLoop: taskMgr.doMethodLater(180, self.endPanel.closeButtonPressed, 'clearRaceEndPanel', extraArgs=[]) def destroy(self): self.disable() if hasattr(self, 'wrongWaySeq'): self.wrongWaySeq.finish() self.wrongWaySeq = None taskMgr.removeTasksMatching('removeIt') taskMgr.removeTasksMatching('removeCam*') taskMgr.removeTasksMatching('clearRaceEndPanel') for obj in self.directObjList: obj.destroy() if hasattr(self, 'mapScene'): self.mapScene.removeNode() self.mapScene = None self.aspect2dRoot.removeNode() self.aspect2dRoot = None self.raceModeRoot.removeNode() self.raceModeRoot = None self.render2dRoot.removeNode() self.render2dRoot = None self.closeButton = None self.gag = None self.lapLabel = None self.timeLabels = None self.placeLabelStr = None self.placeLabelNum = None self.photoFinishLabel = None self.mapScene = None self.race = None return def setSpotAsymptotic(self, diffT, spot): p = (-1, 1)[diffT > 0] * (1 - 1 / pow(abs(diffT) / self.cutoff + 1, 2)) spot.setX(p) def setSpotRaceLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t / self.lapCount)) def setSpotLapLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t - int(t))) def update(self, time): placeSorter = [] placeCount = 0 for key in list(self.racerDict.keys()): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if not racer.finished and racer.enabled: placeSorter.append((curvetime, key)) if racer.finished or racer.enabled: placeCount += 1 pt = Vec3(0, 0, 0) mapT = (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1 * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint(mapT % self.race.curve.getMaxT(), pt) lapT = bound(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) t = time - self.race.baseTime - self.raceTimeDelta if key == localAvatar.doId: if self.race.laps > maxlaphit: racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if self.maxLapHit < self.race.lapCount: for y in self.timeLabels[self.maxLapHit - 1]: y.configure( text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure( text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime( ) - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(0.1) if self.maxLapHit == self.race.lapCount - 1: lapNotice[ 'text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice[ 'text'] = TTLocalizer.KartRace_LapText % str( self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, 'removeIt', extraArgs=[]) self.lapLabel['text'] = str( bound(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str(self.race.lapCount) suffix = { 1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix } placeSorter.sort() for x, p in zip(placeSorter, range(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=p + placeCount - len(placeSorter)) localRacer = self.racerDict[localAvatar.doId] nearDiff, farDiff = RaceGlobals.TrackDict[self.race.trackId][8] if not localRacer.finished and self.faceEndPos[ 0] - localRacer.face.getX() < nearDiff: for racerId in list(self.racerDict.keys()): racer = self.racerDict[racerId] if not racer.enabled or racerId == localAvatar.doId or racer.face.getX( ) >= self.faceEndPos[0]: continue if self.faceEndPos[0] - racer.face.getX() < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = '' self.placeLabelStr['text'] = '' else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str( self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[ localAvatar.doId].place] minutes = int(t / 60) t -= minutes * 60 seconds = int(t) padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if self.timerEnabled and self.maxLapHit < self.race.lapCount: self.timeLabels[self.maxLapHit][0]['text'] = "%d'" % minutes self.timeLabels[self.maxLapHit][1]['text'] = "%s%d''" % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % fraction if self.race.wrongWay and not self.wrongWaySeq.isPlaying(): self.wrongWaySeq.loop() elif not self.race.wrongWay and self.wrongWaySeq.isPlaying(): self.wrongWaySeq.finish() def updateRacerInfo(self, avId, curvetime=None, maxlaphit=None): if avId in list(self.racerDict.keys()): self.racerDict[avId].update(curvetime=curvetime, maxlaphit=maxlaphit) def racerEntered(self, avId): toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.race.kartMap.get(avId, None), None) if not toon or not kart: return if kart.getBodyColor() == InvalidEntry: bodyColor = getDefaultColor() else: bodyColor = getAccessory(kart.getBodyColor()) headframe = RaceHeadFrame(av=toon, color=bodyColor) eyes = headframe.head.find('**/eyes*') eyes.setDepthTest(1) eyes.setDepthWrite(1) headframe.configure(geom_scale=(0.5, 0.5, 0.5)) headframe.setZ(self.faceStartPos[2]) headframe.setDepthWrite(True) headframe.setDepthTest(True) headframe.reparentTo(self.raceModeRoot) self.directObjList.append(headframe) mapspot = loader.loadModel('phase_6/models/karting/race_mapspot') mapspot.setColor(bodyColor) mapspot.reparentTo(self.mapLines) mapspot.setHpr(self.mapScene, 0, 0, 0) self.racerDict[avId] = self.RacerInfo(headframe, mapspot) for key, i in zip(list(self.racerDict.keys()), list(range(len(list(self.racerDict.keys()))))): face = self.racerDict[key].face mapspot = self.racerDict[key].mapspot face.setX(self.faceStartPos[0]) face.setY(-1 - 5 * (i + 1)) face.setScale(0.15) mapspot.getChild(0).setY((-5 - 5 * (i + 1)) * 1000) mapspot.setScale(self.mapScene, 0.15) mapspot.setPos(self.race.startingPos[0][0]) if key == localAvatar.doId: face.setY(-1) face.setScale(face.getScale() * 1.25) mapspot.getChild(0).setY(-5 * 1000) mapspot.setScale(mapspot.getScale() * 1.25) self.face = face self.mapspot = mapspot return def racerLeft(self, avId, unexpected=False): racer = self.racerDict.get(avId, None) if racer: racer.disable() return def racerFinished(self, avId, trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): racer = self.racerDict.get(avId, None) if racer: racer.update(finished=True) racer.disable() self.endPanel.displayRacer(place, entryFee, qualify, winnings, trackId, bonus, trophies, racer.face, base.cr.doId2do[avId].getName(), totalTime, circuitPoints, circuitTime) if racer.face in self.directObjList: self.directObjList.remove(racer.face) if avId == localAvatar.doId: self.disableRaceMode() self.enableResultMode() self.endPanel.startWinningsPanel(entryFee, winnings, trackId, bonus, trophies) return def racerFinishedCircuit(self, avId, place, entryFee, winnings, bonus, trophies): racer = self.racerDict.get(avId, None) if racer: newTotalTickets = winnings + entryFee + bonus self.endPanel.updateWinnings(place, newTotalTickets) if avId == localAvatar.doId: self.endPanel.updateWinningsFromCircuit( place, entryFee, winnings, bonus, trophies) return def circuitFinished(self, placeFixup): self.endPanel.circuitFinished(placeFixup) def setTimerEnabled(self, enabled): self.timerEnabled = enabled