def equip(self): if not BaseHitscan.equip(self): return False self.sprayParticleRoot = render.attachNewNode('sprayParticleRoot') self.sprayParticleRoot.setLightOff(1) self.sprayParticleRoot.hide(CIGlobals.ShadowCameraBitmask) if self.isLocal(): self.released = True self.waterBar = WaterBar() self.__updateWaterBar() self.waterBar.reparentTo(base.a2dLeftCenter) self.waterBar.setScale(0.6) self.waterBar.setX(0.166) self.hydrant = loader.loadModel( 'phase_5/models/props/battle_hydrant.bam') self.model.reparentTo(self.hydrant) self.model.pose('chan', 2) self.hoseJoint = self.model.controlJoint(None, "modelRoot", "joint_x") self.hydrantNode = self.avatar.attachNewNode('hydrantNode') self.hydrantNode.clearTransform(self.avatar.getGeomNode().getChild(0)) self.hydrantNode.setHpr(0, 0, 0) self.hydrantScale = self.hydrantNode.attachNewNode('hydrantScale') self.hydrant.reparentTo(self.hydrantScale) self.avatar.pose('firehose', 30) self.avatar.update(0) torso = self.avatar.getPart('torso') if 'dgm' in self.avatar.getTorso(): self.hydrant.setPos(torso, 0, 0, -1.85) else: self.hydrant.setPos(torso, 0, 0, -1.45) hbase = self.hydrant.find('**/base') hbase.setColor(1, 1, 1, 0.5) hbase.setPos(self.avatar, 0, 0, 0) self.avatar.loop('neutral') tAppearDelay = 0.7 dAnimHold = 5.1 dHoseHold = 0.7 tSprayDelay = 2.8 track = Parallel() toonTrack = Sequence(Wait(tAppearDelay), Func(self.avatar.setForcedTorsoAnim, 'firehose'), self.getAnimationTrack('firehose', endFrame=30), Func(self.__doBob)) propTrack = Sequence( Func(self.hydrantNode.reparentTo, self.avatar), LerpScaleInterval(self.hydrantScale, tAppearDelay * 0.5, Point3(1, 1, 1.4), startScale=Point3(1, 1, 0.01)), LerpScaleInterval(self.hydrantScale, tAppearDelay * 0.3, Point3(1, 1, 0.8), startScale=Point3(1, 1, 1.4)), LerpScaleInterval(self.hydrantScale, tAppearDelay * 0.1, Point3(1, 1, 1.2), startScale=Point3(1, 1, 0.8)), LerpScaleInterval(self.hydrantScale, tAppearDelay * 0.1, Point3(1, 1, 1), startScale=Point3(1, 1, 1.2)), ActorInterval(self.model, 'chan', endFrame=30)) track.append(toonTrack) track.append(propTrack) self.setAnimTrack(track, startNow=True) if self.isFirstPerson(): self.hydrantNode.hide() return True
def drawBattle(self, battle): if not self.battleReady: self.battle = battle self.battleRender = NodePath('battleRender') self.battleRender.reparentTo(self.render) self.battleEventHandler = BattleEventHandler(self) self.camera.setPos(0, 0, 40) self.camera.setHpr(0, -90, 0) self.blackMaterial = Material() self.blackMaterial.setDiffuse(VBase4(0, 0, 0, 1)) self.whiteMaterial = Material() self.whiteMaterial.setDiffuse(VBase4(256, 256, 256, 1)) self.battleBoard = self.loader.loadModel('models/plane') self.battleBoard.setPos(0, 0, 4) self.battleBoard.setScale(2) self.battleBoard.setMaterial(self.blackMaterial) self.battleBoard.reparentTo(self.render) self.resources.setText('') self.battlePhase = 'initial' self.battleTurn = 0 self.battlePlayedTurns = 0 self.clicked = None self.isMoving = False self.mover = None self.battleFields = [] for x in range(0, 8): self.battleFields.append([]) for y in range(0, 8): field = self.loader.loadModel('models/plane') posX = x * 2.4 - 8.5 posY = y * 2.4 - 8.5 field.setPos(posX, posY, 4.2) field.setScale(0.11) cs = CollisionPolygon(Point3(-10, -10, 0), Point3(-10, 10, 0), Point3(10, 10, 0), Point3(10, -10, 0)) cnodePath = field.attachNewNode(CollisionNode('cnode')) cnodePath.node().addSolid(cs) field.setTag('clickable', 'true') field.setTag('field', 'true') field.setTag('x', str(x)) field.setTag('y', str(y)) field.reparentTo(self.battleRender) self.battleFields[x].append(field) self.battleReady = True if self.mover and not self.mover.is_alive(): self.mover = None self.isMoving = False black = False white = False for x in self.battleFields: for y in x: child = y.getChildren()[-1] if child.hasTag('piece'): if child.getMaterial() == self.blackMaterial: black = True if child.getMaterial() == self.whiteMaterial: white = True if white and black: return if not white: print('black wins') turn = self.game.turn self.game.players[turn ^ 1].figures.remove(self.whiteTroops) self.whiteTroops.model.removeNode() if not black: print('white wins') turn = self.game.turn field = self.blackTroops.field self.game.players[turn].figures.remove(self.blackTroops) self.blackTroops.model.removeNode() field.put(self.whiteTroops) if not black or not white: self.pop()
def doDeathTrack(self): def removeDeathSuit(suit, deathSuit): if not deathSuit.isEmpty(): deathSuit.detachNode() suit.cleanupLoseActor() self.deathSuit.reparentTo(self.suit.getParent()) self.deathSuit.setScale(self.suit.getScale()) self.deathSuit.setPos(render, self.suit.getPos(render)) self.deathSuit.setHpr(render, self.suit.getHpr(render)) self.suit.hide() self.collNodePath.reparentTo(self.deathSuit) gearPoint = Point3(0, 0, self.suit.height / 2.0 + 2.0) smallGears = BattleParticles.createParticleEffect( file='gearExplosionSmall') singleGear = BattleParticles.createParticleEffect('GearExplosion', numParticles=1) smallGearExplosion = BattleParticles.createParticleEffect( 'GearExplosion', numParticles=10) bigGearExplosion = BattleParticles.createParticleEffect( 'BigGearExplosion', numParticles=30) smallGears.setPos(gearPoint) singleGear.setPos(gearPoint) smallGearExplosion.setPos(gearPoint) bigGearExplosion.setPos(gearPoint) smallGears.setDepthWrite(False) singleGear.setDepthWrite(False) smallGearExplosion.setDepthWrite(False) bigGearExplosion.setDepthWrite(False) suitTrack = Sequence( Func(self.collNodePath.stash), ActorInterval(self.deathSuit, 'lose', startFrame=80, endFrame=140), Func(removeDeathSuit, self.suit, self.deathSuit, name='remove-death-suit')) explosionTrack = Sequence( Wait(1.5), MovieUtil.createKapowExplosionTrack(self.deathSuit, explosionPoint=gearPoint)) gears1Track = Sequence(ParticleInterval(smallGears, self.deathSuit, worldRelative=0, duration=4.3, cleanup=True), name='gears1Track') gears2MTrack = Track((0.0, explosionTrack), (0.7, ParticleInterval(singleGear, self.deathSuit, worldRelative=0, duration=5.7, cleanup=True)), (5.2, ParticleInterval(smallGearExplosion, self.deathSuit, worldRelative=0, duration=1.2, cleanup=True)), (5.4, ParticleInterval(bigGearExplosion, self.deathSuit, worldRelative=0, duration=1.0, cleanup=True)), name='gears2MTrack') def removeParticle(particle): if particle and hasattr(particle, 'renderParent'): particle.cleanup() del particle removeParticles = Sequence(Func(removeParticle, smallGears), Func(removeParticle, singleGear), Func(removeParticle, smallGearExplosion), Func(removeParticle, bigGearExplosion)) self.deathTrack = Sequence( Parallel(suitTrack, gears2MTrack, gears1Track, self._deathSoundIval), removeParticles) self.deathTrack.start()
def __init__(self, showbase): DirectObject.__init__(self) self.showbase = showbase self.showbase.disableMouse() # This disables the default mouse based camera control used by panda. This default control is awkward, and won't be used. self.showbase.camera.setPos(0, -150, 200) self.showbase.camera.lookAt(0, 0, 0) # Gives the camera an initial position and rotation. self.mx, self.my = 0, 0 # Sets up variables for storing the mouse coordinates self.orbiting = False # A boolean variable for specifying whether the camera is in orbiting mode. Orbiting mode refers to when the camera is being moved # because the user is holding down the right mouse button. self.target = Vec3() # sets up a vector variable for the camera's target. The target will be the coordinates that the camera is currently focusing on. self.camDist = 150 # A variable that will determine how far the camera is from it's target focus self.panRateDivisor = 10 # This variable is used as a divisor when calculating how far to move the camera when panning. Higher numbers will yield slower panning # and lower numbers will yield faster panning. This must not be set to 0. self.panZoneSize = .1 # This variable controls how close the mouse cursor needs to be to the edge of the screen to start panning the camera. It must be less than 1, # and I recommend keeping it less than .2 self.panLimitsX = Vec2(-1000, 1000) self.panLimitsY = Vec2(-1000, 1000) # These two vairables will serve as limits for how far the camera can pan, so you don't scroll away from the map. self.maxZoomOut = 500 self.maxZoomIn = 25 # These two variables set the max distance a person can zoom in or out self.orbitRate = 75 # This is the rate of speed that the camera will rotate when middle mouse is pressed and mouse moved # recommended rate 50-100 self.setTarget(0, 0, 0) # calls the setTarget function to set the current target position to the origin. self.turnCameraAroundPoint(0, 0) # calls the turnCameraAroundPoint function with a turn amount of 0 to set the camera position based on the target and camera distance self.accept("mouse2", self.startOrbit) # sets up the camrea handler to accept a right mouse click and start the "drag" mode. self.accept("mouse2-up", self.stopOrbit) # sets up the camrea handler to understand when the right mouse button has been released, and ends the "drag" mode when # the release is detected. self.storeX = 0 self.storeY = 0 # for storing of the x and y for the orbit # The next pair of lines use lambda, which creates an on-the-spot one-shot function. self.accept("wheel_up", self.zoomIn) # sets up the camera handler to detet when the mouse wheel is rolled upwards and uses a lambda function to call the # adjustCamDist function with the argument 0.9 self.accept("wheel_down", self.zoomOut) # sets up the camera handler to detet when the mouse wheel is rolled upwards and uses a lambda function to call the # adjustCamDist function with the argument 1.1 # Keys array (down if 1, up if 0) self.keys = {"cam-left": 0, "cam-right": 0, "cam-up": 0, "cam-down": 0} # Using Arrow Keys self.accept("arrow_left", self.setValue, [self.keys, "cam-left", 1]) self.accept("arrow_right", self.setValue, [self.keys, "cam-right", 1]) self.accept("arrow_up", self.setValue, [self.keys, "cam-up", 1]) self.accept("arrow_down", self.setValue, [self.keys, "cam-down", 1]) self.accept("arrow_left-up", self.setValue, [self.keys, "cam-left", 0]) self.accept("arrow_right-up", self.setValue, [self.keys, "cam-right", 0]) self.accept("arrow_up-up", self.setValue, [self.keys, "cam-up", 0]) self.accept("arrow_down-up", self.setValue, [self.keys, "cam-down", 0]) self.keyPanRate = 1.5 # pan rate for when user presses the arrow keys # set up plane for checking collision with for mouse-3d world self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0))
def pieThrow(self, toonId, timestamp, h, x, y, z, power): if toonId not in self.toonIds: return if toonId != base.localAvatar.doId: self.view.pieThrow(toonId, timestamp, h, Point3(x, y, z), power)
def __init__(self, items, parent=None, sidePad=.0, edgePos=PTop, align=ALeft, effect=ENone, buttonThrower=None, font=None, baselineOffset=.0, scale=.05, itemHeight=1., leftPad=.0, separatorHeight=.5, underscoreThickness=1, BGColor=(0, 0, 0, .7), BGBorderColor=(1, .85, .4, 1), separatorColor=(1, 1, 1, 1), frameColorHover=(1, .85, .4, 1), frameColorPress=(0, 1, 0, 1), textColorReady=(1, 1, 1, 1), textColorHover=(0, 0, 0, 1), textColorPress=(0, 0, 0, 1), textColorDisabled=(.5, .5, .5, 1), draggable=False, onMove=None): ''' sidePad : additional space on the left and right of the text item edgePos : menu bar position on the screen, use DropDownMenu.PLeft, PRight, PBottom, or PTop align : menu items alignment on menu bar, use DropDownMenu.ALeft, ACenter, or ARight effect : the drop down appearance effect, use DropDownMenu.ENone, EFade, ESlide, or EStretch draggable : menu bar's draggability status onMove : a function which will be called after changing edge position Read the remaining options documentation in PopupMenu class. ''' self.parent = parent if parent else getattr( base, DropDownMenu.parents[edgePos][align]) self.BT = buttonThrower if buttonThrower else base.buttonThrowers[ 0].node() self.menu = self.parent.attachNewNode('dropdownmenu-%s' % id(self)) self.font = font if font else TextNode.getDefaultFont() self.baselineOffset = baselineOffset if isinstance(scale, (float, int)): scale = (scale, 1.0, scale) self.scale = scale self.itemHeight = itemHeight self.sidePad = sidePad self.edgePos = edgePos self.alignment = align self.effect = effect self.leftPad = leftPad self.underscoreThickness = underscoreThickness self.separatorHeight = separatorHeight self.BGColor = BGColor self.BGBorderColor = BGBorderColor self.separatorColor = separatorColor self.frameColorHover = frameColorHover self.frameColorPress = frameColorPress self.textColorReady = textColorReady self.textColorHover = textColorHover self.textColorPress = textColorPress self.textColorDisabled = textColorDisabled self.draggable = draggable self.onMove = onMove self.dropDownMenu = self.whoseDropDownMenu = None self.gapFromEdge = gapFromEdge = .008 texMargin = self.font.getTextureMargin() * self.scale[0] * .25 b = DirectButton(parent=NodePath(''), text='^|g_', text_font=self.font, scale=self.scale) fr = b.node().getFrame() b.getParent().removeNode() baselineToCenter = (fr[2] + fr[3]) * self.scale[0] LH = (fr[3] - fr[2]) * self.itemHeight * self.scale[2] baselineToTop = (fr[3] * self.itemHeight * self.scale[2] / LH) / (1. + self.baselineOffset) baselineToBot = LH / self.scale[2] - baselineToTop self.height = LH + .01 l, r, b, t = 0, 5, -self.height, 0 self.menuBG = DirectFrame(parent=self.menu, frameColor=BGColor, frameSize=(l, r, b, t), state=DGG.NORMAL, suppressMouse=1) if self.draggable: self.setDraggable(1) LSborder = LineSegs() LSborder.setThickness(2) LSborder.setColor(0, 0, 0, 1) LSborder.moveTo(l, 0, b) LSborder.drawTo(r, 0, b) self.menuBG.attachNewNode(LSborder.create()) self.itemsParent = self.menu.attachNewNode('menu items parent') x = sidePad * self.scale[0] + gapFromEdge for t, menuItemsGenerator in items: underlinePos = t.find('_') t = t.replace('_', '') b = DirectButton( parent=self.itemsParent, text=t, text_font=self.font, pad=(sidePad, 0), scale=self.scale, pos=(x, 0, -baselineToTop * self.scale[2] - gapFromEdge), text_fg=textColorReady, # text color when mouse over text2_fg=textColorHover, # text color when pressed text1_fg=textColorPress, # framecolor when pressed frameColor=frameColorPress, command=self.__createMenu, extraArgs=[True, menuItemsGenerator], text_align=TextNode.ALeft, relief=DGG.FLAT, rolloverSound=0, clickSound=0) b['extraArgs'] += [b.getName()] b.stateNodePath[2].setColor( *frameColorHover) # framecolor when mouse over b.stateNodePath[0].setColor(0, 0, 0, 0) # framecolor when ready fr = b.node().getFrame() b['frameSize'] = (fr[0], fr[1], -baselineToBot, baselineToTop) self.accept(DGG.ENTER + b.guiId, self.__createMenu, [False, menuItemsGenerator, b.getName()]) if underlinePos > -1: tn = TextNode('') tn.setFont(self.font) tn.setText(t[:underlinePos + 1]) tnp = NodePath(tn.getInternalGeom()) underlineXend = tnp.getTightBounds()[1][0] tnp.removeNode() tn.setText(t[underlinePos]) tnp = NodePath(tn.getInternalGeom()) b3 = tnp.getTightBounds() underlineXstart = underlineXend - (b3[1] - b3[0])[0] tnp.removeNode() LSunder = LineSegs() LSunder.setThickness(underscoreThickness) LSunder.moveTo(underlineXstart + texMargin, 0, -.7 * baselineToBot) LSunder.drawTo(underlineXend - texMargin, 0, -.7 * baselineToBot) underline = b.stateNodePath[0].attachNewNode(LSunder.create()) underline.setColor(Vec4(*textColorReady), 1) underline.copyTo(b.stateNodePath[1], 10).setColor(Vec4(*textColorPress), 1) underline.copyTo(b.stateNodePath[2], 10).setColor(Vec4(*textColorHover), 1) self.accept('alt-' + t[underlinePos].lower(), self.__createMenu, [True, menuItemsGenerator, b.getName()]) x += (fr[1] - fr[0]) * self.scale[0] self.width = x - 2 * gapFromEdge self.align(align) self.setEdgePos(edgePos) self.minZ = base.a2dBottom + self.height if edgePos == DropDownMenu.PBottom else None viewPlaneNode = PlaneNode('cut menu') viewPlaneNode.setPlane(Plane(Vec3(0, 0, -1), Point3(0, 0, -LH))) self.clipPlane = self.menuBG.attachNewNode(viewPlaneNode)
def __init__(self, game, v_id, pos, vel, length, width, height, axisDis, wheelDis, radius, wheelH): self.initCordPos = numpy.array([pos[0], pos[1]]) '''self.length=length self.width=width self.height=height self.axisDis=axisDis self.wheelDis=wheelDis self.radius=radius self.wheelH=wheelH''' self.id = v_id line = game.segLine lineLen = 0 prevPoint = line[0] self.initNum = 0 for point in line: norm = numpy.linalg.norm(point - prevPoint) if pos[0] >= lineLen and pos[0] < lineLen + norm: ldirec = (point - prevPoint) / norm rdirec = numpy.array([ldirec[1], -ldirec[0]]) post = prevPoint + (pos[0] - lineLen) * ldirec + rdirec * pos[1] self.initPos = Vec3(post[0], post[1], pos[2]) break lineLen = lineLen + norm prevPoint = point self.initNum = self.initNum + 1 chassis = setChassis(game, self.initPos, vel, length, width, height) BulletVehicle.__init__(self, game.world, chassis.node()) self.setCoordinateSystem(ZUp) game.world.attachVehicle(self) ### if length < 17: v_type = 'car' elif length < 19: v_type = 'suv' elif length < 25: v_type = 'truck' else: v_type = 'bus' self.yugoNP = loader.loadModel('models/low_poly_cars_set/' + v_type + '.obj') nn = str(numpy.random.randint(3)) tex = loader.loadTexture('models/low_poly_cars_set/tex/' + v_type + '_' + nn + '.png') self.yugoNP.setTexture(tex, 1) ### # self.yugoNP = loader.loadModel('models/yugo/yugo.egg') min, max = self.yugoNP.getTightBounds() size = max - min self.yugoNP.setSx(width / size[0]) self.yugoNP.setSy(length / size[1]) self.yugoNP.setSz(width / size[0]) min, max = self.yugoNP.getTightBounds() self.yugoNP.setPos(-(min + max) / 2) self.yugoNP.setZ(-min[2]) self.yugoNP.reparentTo(chassis) # Right front wheel np = loader.loadModel('models/yugo/yugotireR.egg') np.reparentTo(game.worldNP) self.addWheel(Point3(wheelDis / 2, axisDis / 2, wheelH), True, np, radius) # Left front wheel np = loader.loadModel('models/yugo/yugotireL.egg') np.reparentTo(game.worldNP) self.addWheel(Point3(-wheelDis / 2, axisDis / 2, wheelH), True, np, radius) # Right rear wheel np = loader.loadModel('models/yugo/yugotireR.egg') np.reparentTo(game.worldNP) self.addWheel(Point3(wheelDis / 2, -axisDis / 2, wheelH), False, np, radius) # Left rear wheel np = loader.loadModel('models/yugo/yugotireL.egg') np.reparentTo(game.worldNP) self.addWheel(Point3(-wheelDis / 2, -axisDis / 2, wheelH), False, np, radius) # Steering info self.steering = 0.0 # degree self.steeringClamp = 45.0 # degree self.steeringIncrement = 10.0 # degree per second
def load(self): self.notify.debug('load') DistributedMinigame.DistributedMinigame.load(self) self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_IceGame.ogg') self.gameBoard = loader.loadModel('phase_4/models/minigames/ice_game_icerink') background = loader.loadModel('phase_4/models/minigames/ice_game_2d') background.reparentTo(self.gameBoard) self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0) self.gameBoard.setScale(1.0) self.setupSimulation() index = 0 for avId in self.avIdList: self.setupTire(avId, index) self.setupForceArrow(avId) index += 1 for index in xrange(len(self.avIdList), 4): self.setupTire(-index, index) self.setupForceArrow(-index) self.showForceArrows(realPlayersOnly=True) self.westWallModel = NodePath() if not self.westWallModel.isEmpty(): self.westWallModel.reparentTo(self.gameBoard) self.westWallModel.setPos(IceGameGlobals.MinWall[0], IceGameGlobals.MinWall[1], 0) self.westWallModel.setScale(4) self.eastWallModel = NodePath() if not self.eastWallModel.isEmpty(): self.eastWallModel.reparentTo(self.gameBoard) self.eastWallModel.setPos(IceGameGlobals.MaxWall[0], IceGameGlobals.MaxWall[1], 0) self.eastWallModel.setScale(4) self.eastWallModel.setH(180) self.arrowKeys = ArrowKeys.ArrowKeys() self.target = loader.loadModel('phase_3/models/misc/sphere') self.target.setScale(0.01) self.target.reparentTo(self.gameBoard) self.target.setPos(0, 0, 0) self.scoreCircle = loader.loadModel('phase_4/models/minigames/ice_game_score_circle') self.scoreCircle.setScale(0.01) self.scoreCircle.reparentTo(self.gameBoard) self.scoreCircle.setZ(IceGameGlobals.TireRadius / 2.0) self.scoreCircle.setAlphaScale(0.5) self.scoreCircle.setTransparency(1) self.scoreCircle.hide() self.treasureModel = loader.loadModel('phase_4/models/minigames/ice_game_barrel') self.penaltyModel = loader.loadModel('phase_4/models/minigames/ice_game_tnt2') self.penaltyModel.setScale(0.75, 0.75, 0.7) szId = self.getSafezoneId() obstacles = IceGameGlobals.Obstacles[szId] index = 0 cubicObstacle = IceGameGlobals.ObstacleShapes[szId] for pos in obstacles: newPos = Point3(pos[0], pos[1], IceGameGlobals.TireRadius) newObstacle = self.createObstacle(newPos, index, cubicObstacle) self.obstacles.append(newObstacle) index += 1 self.countSound = loader.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg') self.treasureGrabSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_vine_game_bananas.ogg') self.penaltyGrabSound = loader.loadSfx('phase_4/audio/sfx/MG_cannon_fire_alt.ogg') self.tireSounds = [] for tireIndex in xrange(4): tireHit = loader.loadSfx('phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg') wallHit = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg') obstacleHit = loader.loadSfx('phase_4/audio/sfx/Golf_Hit_Barrier_2.ogg') self.tireSounds.append({'tireHit': tireHit, 'wallHit': wallHit, 'obstacleHit': obstacleHit}) self.arrowRotateSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_ice_force_rotate.ogg') self.arrowUpSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_ice_force_increase_3sec.ogg') self.arrowDownSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_ice_force_decrease_3sec.ogg') self.scoreCircleSound = loader.loadSfx('phase_4/audio/sfx/MG_sfx_ice_scoring_1.ogg')
def enterScoring(self): sortedByDistance = [] for avId in self.avIdList: np = self.getTireNp(avId) pos = np.getPos() pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoreMovie = Sequence() curScale = 0.01 curTime = 0 self.scoreCircle.setScale(0.01) self.scoreCircle.show() self.notify.debug('newScores = %s' % self.newScores) circleStartTime = 0 for index in xrange(len(sortedByDistance)): distance = sortedByDistance[index][1] avId = sortedByDistance[index][0] scorePanelIndex = self.avIdList.index(avId) time = (distance - curScale) / IceGameGlobals.ExpandFeetPerSec if time < 0: time = 0.01 scaleXY = distance + IceGameGlobals.TireRadius self.notify.debug('circleStartTime = %s' % circleStartTime) self.scoreMovie.append(Parallel(LerpScaleInterval(self.scoreCircle, time, Point3(scaleXY, scaleXY, 1.0)), SoundInterval(self.scoreCircleSound, duration=time, startTime=circleStartTime))) circleStartTime += time startScore = self.scorePanels[scorePanelIndex].getScore() destScore = self.newScores[scorePanelIndex] self.notify.debug('for avId %d, startScore=%d, newScores=%d' % (avId, startScore, destScore)) def increaseScores(t, scorePanelIndex = scorePanelIndex, startScore = startScore, destScore = destScore): oldScore = self.scorePanels[scorePanelIndex].getScore() diff = destScore - startScore newScore = int(startScore + diff * t) if newScore > oldScore: base.playSfx(self.countSound) self.scorePanels[scorePanelIndex].setScore(newScore) self.scores[scorePanelIndex] = newScore duration = (destScore - startScore) * IceGameGlobals.ScoreCountUpRate tireNp = self.tireDict[avId]['tireNodePath'] self.scoreMovie.append(Parallel(LerpFunctionInterval(increaseScores, duration), Sequence(LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)), LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1))))) curScale += distance self.scoreMovie.append(Func(self.sendUpdate, 'reportScoringMovieDone', [])) self.scoreMovie.start()
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 range(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
# Filename: TutorialGlobals.py # Created by: blach (21Oct15) from panda3d.core import Point3 SUIT_POINTS = [ Point3(0, 50, -0.5), Point3(-42.22, 50, -0.5), Point3(42.22, 50, -0.5) ] SUIT_SPAWN_POINT = 0
def getExplosionTrack(self): loseActor = self.getLoseActor() spinningSound = loader.loadSfx('phase_3.5/audio/sfx/Cog_Death.ogg') deathSound = loader.loadSfx( 'phase_3.5/audio/sfx/ENC_cogfall_apart.ogg') explosionInterval = Sequence( Func(loseActor.reparentTo, render), Func(self.stash), ActorInterval(loseActor, 'lose', duration=6.1), Func(loseActor.hide)) deathSoundTrack = Sequence( Wait(0.6), SoundInterval(spinningSound, duration=1.2, startTime=1.5, volume=0.2), SoundInterval(spinningSound, duration=3.0, startTime=0.6, volume=0.8), SoundInterval(deathSound, volume=0.32)) smallGears = EffectsManager.createParticleEffect( file='gearExplosionSmall') singleGear = EffectsManager.createParticleEffect('GearExplosion', numParticles=1) smallGearExplosion = EffectsManager.createParticleEffect( 'GearExplosion', numParticles=10) bigGearExplosion = EffectsManager.createParticleEffect( 'BigGearExplosion', numParticles=30) gearPoint = Point3(loseActor.getX(), loseActor.getY(), loseActor.getZ()) smallGears.setDepthWrite(False) singleGear.setDepthWrite(False) smallGearExplosion.setDepthWrite(False) bigGearExplosion.setDepthWrite(False) explosionTrack = Sequence() explosionTrack.append(Wait(5.4)) explosionTrack.append(createKapowExplosionTrack(loseActor)) gears1Track = Sequence( Wait(2.0), ParticleInterval(smallGears, loseActor, worldRelative=0, duration=4.3, cleanup=True)) gears2MTrack = Track((0.0, explosionTrack), (0.7, ParticleInterval(singleGear, loseActor, worldRelative=0, duration=5.7, cleanup=True)), (5.2, ParticleInterval(smallGearExplosion, loseActor, worldRelative=0, duration=1.2, cleanup=True)), (5.4, ParticleInterval(bigGearExplosion, loseActor, worldRelative=0, duration=1.0, cleanup=True))) return Sequence( Parallel(explosionInterval, deathSoundTrack, gears1Track, gears2MTrack), Func(self.cleanupLoseActor), Func(self.delete))
def __init__(self, panelData): dialogBox = loader.loadModel('phase_3/models/gui/dialog_box_gui.bam') DirectFrame.__init__(self, relief=None, geom=dialogBox, geom_color=CIGlobals.DialogColor, geom_scale=(1.75, 1, 0.75 * 1.1), geom_pos=Point3(0, 0, -0.05), pos=(0, 0, 0.661)) self.initialiseoptions(RewardPanel) self.setScale(0.8) # The data for the reward panel inside of a RPToonData object. self.panelData = panelData # Top wood panel saying Reward Panel gagShopNodes = loader.loadModel( 'phase_4/models/gui/gag_shop_purchase_gui.bam') # Original pos: (-0.02, 0, 0.3) scale = (1.55, 1, 1) self.titlePanel = OnscreenImage( parent=self, image=gagShopNodes.find('**/Goofys_Sign'), pos=(0, 0, 0.3), hpr=(1, 0, 0), scale=(1.3, 1, 0.9)) self.avatarNamePanel = DirectFrame(parent=self.titlePanel, pos=(0, 0.005, 0)) self.avatarText = OnscreenText(parent=self.avatarNamePanel, text='', font=CIGlobals.getMickeyFont(), fg=(0.698, 0.13, 0.13, 1), mayChange=1, scale=(0.1, 0.13, 0.1)) self.panelContentsTitle = OnscreenText(parent=self, text=GagPanelName, font=CIGlobals.getMickeyFont(), pos=(0, 0.24, 0), fg=(0.3725, 0.619, 0.627, 1), mayChange=1) self.playerInfo = DirectFrame(parent=self, relief=None, pos=(-0.5, 0, 0)) self.playerInfo.setBin('gui-popup', 0) self.bonusText = OnscreenText(parent=self.playerInfo, text='2X Cog Office Bonus!', font=CIGlobals.getToonFont(), pos=(0, 0.15, 0), scale=(0.055, 0.055, 0.055), align=TextNode.ACenter) self.bonusText.hide() ################################################################################## # GUI Elements relating to the Favorite Gag/Gag Popup Used for showing Gag Unlock# ################################################################################## self.favoriteGagText = OnscreenText(parent=self.playerInfo, text=FavoriteGag, font=CIGlobals.getMickeyFont(), pos=FavoriteGagTitlePos, fg=(1, 0.2, 0.2, 1), sort=0) glow = loader.loadModel('phase_4/models/minigames/particleGlow.bam') self.favoriteGagGlow = OnscreenImage(parent=self.playerInfo, image=glow, pos=FavoriteGagPos, color=GagGlowColor, scale=(0.8, 0.8, 0.8)) self.favoriteGagGlow.setBin('gui-popup', 10) # particleGlow.bam uses a material since it's normally part of render, not render2d. # Since render2d is still fixed-function, we have to explicitly enable shader generation # to correctly display the glow in render2d. self.favoriteGagGlow.setShaderAuto() invIcons = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam') gag = invIcons.find( GagGlobals.InventoryIconByName.get(GagGlobals.Foghorn)) self.favoriteGag = OnscreenImage(parent=self.playerInfo, image=gag, pos=FavoriteGagPos, scale=(1.65, 1.65, 1.65)) self.favoriteGag.setBin('gui-popup', 20) self.favoriteGagName = OnscreenText(parent=self.playerInfo, text=GagGlobals.Foghorn, font=CIGlobals.getToonFont(), pos=FavoriteGagNamePos, mayChange=1) ################################################################################ # GUI elements showing gag experience on the right-side of the gag exp panel # ################################################################################ self.gagExpFrame = DirectFrame(parent=self, relief=None, pos=(0.085, 0, 0.15)) self.trackLabels = [] self.trackIncLabels = [] self.trackBars = [] self.trackBarsOffset = 0 for i in range(len(GagGlobals.TrackNameById.values())): track = GagGlobals.TrackNameById.values()[i] color = GagGlobals.TrackColorByName.get(track) label = DirectLabel(parent=self.gagExpFrame, relief=None, text=track.upper(), text_scale=0.05, text_align=TextNode.ARight, pos=(0.13, 0, -0.09 * i), text_pos=(0, -0.02)) incrementLabel = DirectLabel(parent=self.gagExpFrame, relief=None, text='', text_scale=0.05, text_align=TextNode.ALeft, pos=(0.65, 0, -0.09 * i), text_pos=(0, -0.02)) progressBar = DirectWaitBar( parent=self.gagExpFrame, relief=DGG.SUNKEN, frameSize=(-1, 1, -0.15, 0.15), borderWidth=(0.02, 0.02), scale=0.25, frameColor=(color[0] * 0.7, color[1] * 0.7, color[2] * 0.7, 1), barColor=(color[0], color[1], color[2], 1), text='0/0', text_scale=0.18, text_fg=(0, 0, 0, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05), pos=(0.4, 0, -0.09 * i)) self.trackLabels.append(label) self.trackIncLabels.append(incrementLabel) self.trackBars.append(progressBar) ################################################################################ # GUI elements showing progress updates on quests # ################################################################################ self.questFrame = DirectFrame(parent=self, relief=None) self.questPosters = [] self.congratsLeft = OnscreenText(parent=self.playerInfo, pos=(-0.1, 0.125, -0.1), text='', scale=0.06, align=TextNode.ARight) self.congratsLeft.setR(-30) self.congratsRight = OnscreenText(parent=self.playerInfo, pos=(0.1, 0.125, 0.1), text='', scale=0.06, align=TextNode.ALeft) self.congratsRight.setR(30) glow.removeNode() invIcons.removeNode() gagShopNodes.removeNode() dialogBox.removeNode()
def attached(self): self.world.register_collider(self) self.world.register_updater_later(self) self.node.set_pos(self.pos) self.solid.apply_impulse(Vec3(*self.vector) * 12, Point3(*self.pos)) self.solid.setIntoCollideMask(NO_COLLISION_BITS)
def createCommonObject(self, type, commonId, pos, hpr, sizeX=0, sizeY=0, moveDistance=0): if commonId == None: commonId = self.commonId self.commonId += 1 vPos = Point3(float(pos[0]), float(pos[1]), float(pos[2])) vHpr = Vec3(float(hpr[0]), float(hpr[1]), float(hpr[2])) rHpr = Vec3(float(hpr[0]), float(hpr[1]), float(hpr[2])) self.placerNode.setHpr(vHpr) self.placerNode.setPos(vPos) if type == 0: model, box = self.createBox(self.world, self.space, 10.0, 5.0, 5.0, 5.0) box.setPosition(vPos) self.placerNode.setHpr(vHpr) box.setQuaternion(self.placerNode.getQuat()) self.commonObjectDict[commonId] = (commonId, type, box) elif type == 1: model, cross = self.createCross(self.world, self.space, 1.0, 3.0, 12.0, 2.0, 2) motor = OdeHingeJoint(self.world) cross.setPosition(vPos) cross.setQuaternion(self.placerNode.getQuat()) ourAxis = render.getRelativeVector(self.placerNode, Vec3(0, 0, 1)) motor.setParamVel(1.5) motor.setParamFMax(500000000.0) boxsize = Vec3(1.0, 1.0, 1.0) motor.attach(0, cross) motor.setAnchor(vPos) motor.setAxis(ourAxis) self.cross = cross cross.enable() self.commonObjectDict[commonId] = (commonId, type, cross) elif type == 2: ourAxis = render.getRelativeVector(self.placerNode, Vec3(0, 0, 1)) model, box = self.createBox(self.world, self.space, 10.0, 5.0, 5.0, 5.0, 2) box.setPosition(vPos) box.setQuaternion(self.placerNode.getQuat()) motor = OdeSliderJoint(self.world) motor.attach(box, 0) motor.setAxis(ourAxis) motor.setParamVel(3.0) motor.setParamFMax(5000000.0) motor.setParamHiStop(10.0) motor.setParamLoStop(-10.0) timeData = (0.0, 5.0) forceData = (3.0, -3.0) eventData = (1, 2) self.commonObjectDict[commonId] = (commonId, type, box, motor, timeData, forceData, eventData, model) elif type == 3: vPos = Point3(float(pos[0]), float(pos[1]), float(pos[2])) vHpr = Vec3(float(hpr[0]), float(hpr[1]), float(hpr[2])) self.placerNode.setHpr(vHpr) self.placerNode.setPos(vPos) self.subPlacerNode.setPos(0, 0, 0) if self.canRender: myModel = loader.loadModel( 'phase_6/models/golf/golf_windmill_b') else: myModel = loader.loadModel( 'phase_6/models/golf/golf_windmill_b.bam') myModel.reparentTo(self.root) myModel.setPos(vPos) myModel.setHpr(vHpr) millFan = myModel.find('**/windmillFan0') millBase = myModel.find('**/arm') rod = myModel.find('**/rod') rod.wrtReparentTo(millBase) self.windmillFanNodePath = millFan self.windmillBaseNodePath = millBase millData = OdeTriMeshData(millBase) millGeom = OdeTriMeshGeom(self.space, millData) self.meshDataList.append(millData) millGeom.setPosition(self.subPlacerNode.getPos(self.root)) millGeom.setQuaternion(self.subPlacerNode.getQuat()) millGeom.setCollideBits(BitMask32(251658240)) millGeom.setCategoryBits(BitMask32(8388608)) self.space.setCollideId(millGeom, 8) vPos = Point3(float(pos[0]), float(pos[1]), float(pos[2]) + 5) vHpr = Vec3(float(hpr[0]), float(hpr[1] + 90), float(hpr[2]) - 90) self.placerNode.setHpr(vHpr) self.placerNode.setPos(vPos) self.subPlacerNode.setPos(-1, 0, 0.0) model, cross = self.createPinWheel(self.world, self.space, 10.0, 1.6, 4.0, 0.6, 5, 3.7, 1.2, 1, millFan, (0, 0, 90), (-4.6, -0.5, -0.25), 20) self.placerNode.setHpr(vHpr) self.placerNode.setPos(vPos) self.subPlacerNode.setPos(-1, 0, 0.0) motor = OdeHingeJoint(self.world) cross.setPosition(self.subPlacerNode.getPos(self.root)) cross.setQuaternion(self.placerNode.getQuat()) ourAxis = self.root.getRelativeVector(self.subPlacerNode, Vec3(0, 0, 1)) motor.setParamVel(1.0) motor.setParamFMax(50000.0) boxsize = Vec3(1.0, 1.0, 1.0) motor.attach(0, cross) motor.setAnchor(self.subPlacerNode.getPos(self.root)) motor.setAxis(ourAxis) self.cross = cross cross.enable() self.commonObjectDict[commonId] = (commonId, type, cross) elif type == 4: ourAxis = self.root.getRelativeVector(self.placerNode, Vec3(0, 1, 0)) model, box = self.createBox(self.world, self.space, 50.0, sizeX, sizeY, 1.0, 2) box.setPosition(vPos) box.setQuaternion(self.placerNode.getQuat()) motor = OdeSliderJoint(self.world) motor.attach(box, 0) motor.setAxis(ourAxis) motor.setParamVel(moveDistance / 4.0) motor.setParamFMax(25000.0) motor.setParamHiStop(moveDistance) motor.setParamLoStop(0) timeData = (0.0, 1.0, 5.0, 6.0) forceData = (-moveDistance / 4.0, moveDistance / 4.0, moveDistance / 4.0, -moveDistance / 4.0) eventData = (-1, 1, -2, 2) radius = moveDistance + sizeY * 0.5 self.commonObjectDict[commonId] = (commonId, type, box, motor, timeData, forceData, eventData, model, radius) return [ type, commonId, (pos[0], pos[1], pos[2]), (hpr[0], hpr[1], hpr[2]), sizeX, sizeY, moveDistance ]
def setupStartOfMatch(self): self.putAllTiresInStartingPositions() szId = self.getSafezoneId() self.numTreasures = IceGameGlobals.NumTreasures[szId] if self.treasures: for treasure in self.treasures: treasure.destroy() self.treasures = [] index = 0 treasureMargin = IceGameGlobals.TireRadius + 1.0 while len(self.treasures) < self.numTreasures: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug('yPos=%s' % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newTreasure = IceTreasure.IceTreasure(self.treasureModel, pos, index, self.doId, penalty=False) goodSpot = True for obstacle in self.obstacles: if newTreasure.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break if goodSpot: for treasure in self.treasures: if newTreasure.nodePath.getDistance(treasure.nodePath) < treasureMargin: goodSpot = False break if goodSpot: self.treasures.append(newTreasure) index += 1 else: newTreasure.destroy() self.numPenalties = IceGameGlobals.NumPenalties[szId] if self.penalties: for penalty in self.penalties: penalty.destroy() self.penalties = [] index = 0 while len(self.penalties) < self.numPenalties: xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5) yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5) self.notify.debug('yPos=%s' % yPos) pos = Point3(xPos, yPos, IceGameGlobals.TireRadius) newPenalty = IceTreasure.IceTreasure(self.penaltyModel, pos, index, self.doId, penalty=True) goodSpot = True for obstacle in self.obstacles: if newPenalty.nodePath.getDistance(obstacle) < treasureMargin: goodSpot = False break if goodSpot: for treasure in self.treasures: if newPenalty.nodePath.getDistance(treasure.nodePath) < treasureMargin: goodSpot = False break if goodSpot: for penalty in self.penalties: if newPenalty.nodePath.getDistance(penalty.nodePath) < treasureMargin: goodSpot = False break if goodSpot: self.penalties.append(newPenalty) index += 1 else: newPenalty.destroy()
def __createMenu(self, clicked, menuItemsGenerator, DBname, crap=None): itself = self.dropDownMenu and self.whoseDropDownMenu == DBname if not (clicked or self.dropDownMenu) or (not clicked and itself): return self.__removeMenu() if clicked and itself: return # removes any context menu if clicked: self.__removePopupMenu() self.dropDownMenu = PopupMenu( items=menuItemsGenerator(), parent=self.parent, buttonThrower=self.BT, font=self.font, baselineOffset=self.baselineOffset, scale=self.scale, itemHeight=self.itemHeight, leftPad=self.leftPad, separatorHeight=self.separatorHeight, underscoreThickness=self.underscoreThickness, BGColor=self.BGColor, BGBorderColor=self.BGBorderColor, separatorColor=self.separatorColor, frameColorHover=self.frameColorHover, frameColorPress=self.frameColorPress, textColorReady=self.textColorReady, textColorHover=self.textColorHover, textColorPress=self.textColorPress, textColorDisabled=self.textColorDisabled, minZ=self.minZ) self.acceptOnce(self.dropDownMenu.BTprefix + 'destroyed', setattr, [self, 'dropDownMenu', None]) self.whoseDropDownMenu = DBname item = self.menu.find('**/%s' % DBname) fr = item.node().getFrame() #~ if self.edgePos==DropDownMenu.PLeft: #~ x=max(fr[1],self.dropDownMenu.menu.getX(item)) #~ z=fr[2] #~ elif self.edgePos==DropDownMenu.PRight: #~ x=min(fr[0],self.dropDownMenu.menu.getX(item)) #~ z=fr[2]-self.dropDownMenu.maxWidth #~ elif self.edgePos in (DropDownMenu.PBottom,DropDownMenu.PTop): #~ x=fr[1]-self.dropDownMenu.maxWidth if self.alignment==DropDownMenu.ARight else fr[0] #~ z=fr[2] if self.edgePos==DropDownMenu.PTop else fr[3]+self.dropDownMenu.height if self.edgePos == DropDownMenu.PLeft: x = max(fr[1], self.dropDownMenu.menu.getX(item)) z = fr[3] - (self.height - self.gapFromEdge) / self.scale[2] elif self.edgePos == DropDownMenu.PRight: x = min(fr[0], self.dropDownMenu.menu.getX(item)) z = fr[3] - (self.height - self.gapFromEdge ) / self.scale[2] - self.dropDownMenu.maxWidth elif self.edgePos in (DropDownMenu.PBottom, DropDownMenu.PTop): x = fr[ 1] - self.dropDownMenu.maxWidth if self.alignment == DropDownMenu.ARight else fr[ 0] z = fr[3] - (self.height - self.gapFromEdge) / self.scale[ 2] if self.edgePos == DropDownMenu.PTop else fr[2] + ( self.height) / self.scale[2] + self.dropDownMenu.height self.dropDownMenu.menu.setPos(item, x, 0, z) if self.effect == DropDownMenu.EFade: self.dropDownMenu.menu.colorScaleInterval( .3, Vec4(1), Vec4(1, 1, 1, 0), blendType='easeIn').start() elif self.effect == DropDownMenu.ESlide: pos = self.dropDownMenu.menu.getPos() if self.edgePos == DropDownMenu.PTop: startPos = Point3(0, 0, self.dropDownMenu.height * self.scale[2]) elif self.edgePos == DropDownMenu.PBottom: startPos = Point3(0, 0, -self.dropDownMenu.height * self.scale[2]) elif self.edgePos == DropDownMenu.PLeft: startPos = Point3(-self.dropDownMenu.maxWidth * self.scale[0], 0, 0) elif self.edgePos == DropDownMenu.PRight: startPos = Point3(self.dropDownMenu.maxWidth * self.scale[0], 0, 0) self.dropDownMenu.menu.posInterval(.3, pos, pos + startPos, blendType='easeIn').start() self.dropDownMenu.menu.setClipPlane(self.clipPlane) elif self.effect == DropDownMenu.EStretch: if self.edgePos == DropDownMenu.PTop: startHpr = Vec3(0, -90, 0) elif self.edgePos == DropDownMenu.PBottom: dz = self.dropDownMenu.height * self.scale[2] for c in asList(self.dropDownMenu.menu.getChildren()): c.setZ(c.getZ() + dz) self.dropDownMenu.menu.setZ(self.dropDownMenu.menu, -dz) startHpr = Vec3(0, 90, 0) elif self.edgePos == DropDownMenu.PLeft: startHpr = Vec3(90, 0, 0) elif self.edgePos == DropDownMenu.PRight: dx = self.dropDownMenu.maxWidth * self.scale[0] for c in asList(self.dropDownMenu.menu.getChildren()): c.setX(c.getX() - dx) self.dropDownMenu.menu.setX(self.dropDownMenu.menu, dx) startHpr = Vec3(-90, 0, 0) self.dropDownMenu.menu.hprInterval(.3, Vec3(0), startHpr, blendType='easeIn').start()
def handleOpenDoor(self, door): self._guiMgr.setMessage(TTLocalizer.CogdoMazeGameDoorOpens) self._guiMgr.showQuestArrow(self.toon, door, Point3(0, 0, self.toon.getHeight() + 2))
def __init__(self, items, parent=None, buttonThrower=None, onDestroy=None, font=None, baselineOffset=.0, scale=.05, itemHeight=1., leftPad=.0, separatorHeight=.5, underscoreThickness=1, BGColor=(0, 0, 0, .7), BGBorderColor=(1, .85, .4, 1), separatorColor=(1, 1, 1, 1), frameColorHover=(1, .85, .4, 1), frameColorPress=(0, 1, 0, 1), textColorReady=(1, 1, 1, 1), textColorHover=(0, 0, 0, 1), textColorPress=(0, 0, 0, 1), textColorDisabled=(.5, .5, .5, 1), minZ=None, useMouseZ=True): ''' items : a collection of menu items Item format : ( 'Item text', 'path/to/image', command ) OR ( 'Item text', 'path/to/image', command, arg1,arg2,.... ) If you don't want to use an image, pass 0. To create disabled item, pass 0 for the command : ( 'Item text', 'path/to/image', 0 ) so, you can easily switch between enabled or disabled : ( 'Item text', 'path/to/image', command if commandEnabled else 0 ) OR ( 'Item text', 'path/to/image', (0,command)[commandEnabled] ) To create submenu, pass a sequence of submenu items for the command. To create disabled submenu, pass an empty sequence for the command. To enable hotkey, insert an underscore before the character, e.g. hotkey of 'Item te_xt' is 'x' key. To add shortcut key text at the right side of the item, append it at the end of the item text, separated by "more than" sign, e.g. 'Item text>Ctrl-T'. To insert separator line, pass 0 for the whole item. parent : where to attach the menu, defaults to aspect2d buttonThrower : button thrower whose thrown events are blocked temporarily when the menu is displayed. If not given, the default button thrower is used onDestroy : user function which will be called after the menu is fully destroyed font : text font baselineOffset : text's baseline Z offset scale : text scale itemHeight : spacing between items, defaults to 1 leftPad : blank space width before text separatorHeight : separator line height, relative to itemHeight underscoreThickness : underscore line thickness BGColor, BGBorderColor, separatorColor, frameColorHover, frameColorPress, textColorReady, textColorHover, textColorPress, textColorDisabled are some of the menu components' color minZ : minimum Z position to restrain menu's bottom from going offscreen (-1..1). If it's None, it will be set a little above the screen's bottom. ''' self.parent = parent if parent else aspect2d self.onDestroy = onDestroy self.BT = buttonThrower if buttonThrower else base.buttonThrowers[ 0].node() self.menu = NodePath('menu-%s' % id(self)) self.parentMenu = None self.submenu = None self.BTprefix = self.menu.getName() + '>' self.submenuCreationTaskName = 'createSubMenu-' + self.BTprefix self.submenuRemovalTaskName = 'removeSubMenu-' + self.BTprefix self.font = font if font else TextNode.getDefaultFont() self.baselineOffset = baselineOffset if isinstance(scale, (float, int)): scale = (scale, 1.0, scale) self.scale = scale self.itemHeight = itemHeight self.leftPad = leftPad self.separatorHeight = separatorHeight self.underscoreThickness = underscoreThickness self.BGColor = BGColor self.BGBorderColor = BGBorderColor self.separatorColor = separatorColor self.frameColorHover = frameColorHover self.frameColorPress = frameColorPress self.textColorReady = textColorReady self.textColorHover = textColorHover self.textColorPress = textColorPress self.textColorDisabled = textColorDisabled self.minZ = minZ self.mpos = Point2(base.mouseWatcherNode.getMouse()) self.itemCommand = [] self.hotkeys = {} self.numItems = 0 self.sel = -1 self.selByKey = False bgPad = self.bgPad = .0125 texMargin = self.font.getTextureMargin() * self.scale[0] * .25 b = DirectButton(parent=NodePath(''), text='^|g_', text_font=self.font, scale=self.scale) fr = b.node().getFrame() b.getParent().removeNode() baselineToCenter = (fr[2] + fr[3]) * self.scale[0] LH = (fr[3] - fr[2]) * self.itemHeight * self.scale[2] imageHalfHeight = .5 * (fr[3] - fr[2]) * self.itemHeight * .85 arrowHalfHeight = .5 * (fr[3] - fr[2]) * self.itemHeight * .5 baselineToTop = (fr[3] * self.itemHeight * self.scale[2] / LH) / (1. + self.baselineOffset) baselineToBot = LH / self.scale[2] - baselineToTop itemZcenter = (baselineToTop - baselineToBot) * .5 separatorHalfHeight = .5 * separatorHeight * LH LSseparator = LineSegs() LSseparator.setColor(.5, .5, .5, .2) arrowVtx = [ (0, itemZcenter), (-2 * arrowHalfHeight, itemZcenter + arrowHalfHeight), (-arrowHalfHeight, itemZcenter), (-2 * arrowHalfHeight, itemZcenter - arrowHalfHeight), ] tri = Triangulator() vdata = GeomVertexData('trig', GeomVertexFormat.getV3(), Geom.UHStatic) vwriter = GeomVertexWriter(vdata, 'vertex') for x, z in arrowVtx: vi = tri.addVertex(x, z) vwriter.addData3f(x, 0, z) tri.addPolygonVertex(vi) tri.triangulate() prim = GeomTriangles(Geom.UHStatic) for i in range(tri.getNumTriangles()): prim.addVertices(tri.getTriangleV0(i), tri.getTriangleV1(i), tri.getTriangleV2(i)) prim.closePrimitive() geom = Geom(vdata) geom.addPrimitive(prim) geomNode = GeomNode('arrow') geomNode.addGeom(geom) realArrow = NodePath(geomNode) z = -baselineToTop * self.scale[2] - bgPad maxWidth = .1 / self.scale[0] shortcutTextMaxWidth = 0 anyImage = False anyArrow = False anyShortcut = False arrows = [] shortcutTexts = [] loadPrcFileData('', 'text-flatten 0') for item in items: if item: t, imgPath, f = item[:3] haveSubmenu = type(f) in SEQUENCE_TYPES anyArrow |= haveSubmenu anyImage |= isinstance(imgPath, bool) or bool(imgPath) disabled = not len(f) if haveSubmenu else not callable(f) args = item[3:] underlinePos = t.find('_') t = t.replace('_', '') shortcutSepPos = t.find('>') if shortcutSepPos > -1: if haveSubmenu: print( "\nA SHORTCUT KEY POINTING TO A SUBMENU IS NON-SENSE, DON'T YOU AGREE ?" ) else: shortcutText = NodePath( OnscreenText( parent=self.menu, text=t[shortcutSepPos + 1:], font=self.font, scale=1, fg=(1, 1, 1, 1), align=TextNode.ARight, )) shortcutTextMaxWidth = max( shortcutTextMaxWidth, abs(shortcutText.getTightBounds()[0][0])) anyShortcut = True t = t[:shortcutSepPos] else: shortcutText = '' EoLcount = t.count('\n') arrowZpos = -self.font.getLineHeight() * EoLcount * .5 if disabled: b = NodePath( OnscreenText( parent=self.menu, text=t, font=self.font, scale=1, fg=textColorDisabled, align=TextNode.ALeft, )) # don't pass the scale and position to OnscreenText constructor, # to maintain correctness between the OnscreenText and DirectButton items # due to the new text generation implementation b.setScale(self.scale) b.setZ(z) maxWidth = max(maxWidth, b.getTightBounds()[1][0] / self.scale[0]) if shortcutText: shortcutText.reparentTo(b) shortcutText.setColor(Vec4(*textColorDisabled), 1) shortcutText.setZ(arrowZpos) shortcutTexts.append(shortcutText) else: b = DirectButton( parent=self.menu, text=t, text_font=self.font, scale=self.scale, pos=(0, 0, z), text_fg=textColorReady, # text color when mouse over text2_fg=textColorHover, # text color when pressed text1_fg=textColorHover if haveSubmenu else textColorPress, # framecolor when pressed frameColor=frameColorHover if haveSubmenu else frameColorPress, commandButtons=[DGG.LMB, DGG.RMB], command=(lambda: 0) if haveSubmenu else self.__runCommand, extraArgs=[] if haveSubmenu else [f, args], text_align=TextNode.ALeft, relief=DGG.FLAT, rolloverSound=0, clickSound=0, pressEffect=0) b.stateNodePath[2].setColor( *frameColorHover) # framecolor when mouse over b.stateNodePath[0].setColor(0, 0, 0, 0) # framecolor when ready bframe = Vec4(b.node().getFrame()) if EoLcount: bframe.setZ(EoLcount * 10) b['frameSize'] = bframe maxWidth = max(maxWidth, bframe[1]) if shortcutText: for snpi, col in ((0, textColorReady), (1, textColorPress), (2, textColorHover)): sct = shortcutText.copyTo(b.stateNodePath[snpi], sort=10) sct.setColor(Vec4(*col), 1) sct.setZ(arrowZpos) shortcutTexts.append(sct) shortcutText.removeNode() if isinstance(imgPath, bool): if imgPath: if disabled: fg = textColorDisabled else: fg = textColorReady tick = NodePath( OnscreenText( parent=b, text=u"\u2714", font=self.font, scale=1, fg=fg, align=TextNode.ALeft, )) tick.setX(-2 * imageHalfHeight - leftPad) elif imgPath: img = loader.loadTexture(imgPath, okMissing=True) if img is not None: if disabled: if imgPath in PopupMenu.grayImages: img = PopupMenu.grayImages[imgPath] else: pnm = PNMImage() img.store(pnm) pnm.makeGrayscale(.2, .2, .2) img = Texture() img.load(pnm) PopupMenu.grayImages[imgPath] = img img.setMinfilter(Texture.FTLinearMipmapLinear) img.setWrapU(Texture.WMClamp) img.setWrapV(Texture.WMClamp) CM = CardMaker('') CM.setFrame(-2 * imageHalfHeight - leftPad, -leftPad, itemZcenter - imageHalfHeight, itemZcenter + imageHalfHeight) imgCard = b.attachNewNode(CM.generate()) imgCard.setTexture(img) if underlinePos > -1: oneLineText = t[:underlinePos + 1] oneLineText = oneLineText[oneLineText.rfind('\n') + 1:] tn = TextNode('') tn.setFont(self.font) tn.setText(oneLineText) tnp = NodePath(tn.getInternalGeom()) underlineXend = tnp.getTightBounds()[1][0] tnp.removeNode() tn.setText(t[underlinePos]) tnp = NodePath(tn.getInternalGeom()) b3 = tnp.getTightBounds() underlineXstart = underlineXend - (b3[1] - b3[0])[0] tnp.removeNode() underlineZpos = -.7 * baselineToBot - self.font.getLineHeight( ) * t[:underlinePos].count('\n') LSunder = LineSegs() LSunder.setThickness(underscoreThickness) LSunder.moveTo(underlineXstart + texMargin, 0, underlineZpos) LSunder.drawTo(underlineXend - texMargin, 0, underlineZpos) if disabled: underline = b.attachNewNode(LSunder.create()) underline.setColor(Vec4(*textColorDisabled), 1) else: underline = b.stateNodePath[0].attachNewNode( LSunder.create()) underline.setColor(Vec4(*textColorReady), 1) underline.copyTo(b.stateNodePath[1], 10).setColor( Vec4(*textColorHover if haveSubmenu else textColorPress), 1) underline.copyTo(b.stateNodePath[2], 10).setColor(Vec4(*textColorHover), 1) hotkey = t[underlinePos].lower() if hotkey in self.hotkeys: self.hotkeys[hotkey].append(self.numItems) else: self.hotkeys[hotkey] = [self.numItems] self.accept(self.BTprefix + hotkey, self.__processHotkey, [hotkey]) self.accept(self.BTprefix + 'alt-' + hotkey, self.__processHotkey, [hotkey]) if haveSubmenu: if disabled: arrow = realArrow.instanceUnderNode(b, '') arrow.setColor(Vec4(*textColorDisabled), 1) arrow.setZ(arrowZpos) else: arrow = realArrow.instanceUnderNode( b.stateNodePath[0], 'r') arrow.setColor(Vec4(*textColorReady), 1) arrow.setZ(arrowZpos) arrPress = realArrow.instanceUnderNode( b.stateNodePath[1], 'p') arrPress.setColor(Vec4(*textColorHover), 1) arrPress.setZ(arrowZpos) arrHover = realArrow.instanceUnderNode( b.stateNodePath[2], 'h') arrHover.setColor(Vec4(*textColorHover), 1) arrHover.setZ(arrowZpos) # weird, if sort order is 0, it's obscured by the frame for a in (arrPress, arrHover): a.reparentTo(a.getParent(), sort=10) if not disabled: extraArgs = [self.numItems, f if haveSubmenu else 0] self.accept(DGG.ENTER + b.guiId, self.__hoverOnItem, extraArgs) self.accept(DGG.EXIT + b.guiId, self.__offItem) #~ self.itemCommand.append((None,0) if haveSubmenu else (f,args)) self.itemCommand.append((f, args)) if self.numItems == 0: self.firstButtonIdx = int(b.guiId[2:]) self.numItems += 1 z -= LH + self.font.getLineHeight() * self.scale[2] * EoLcount else: # SEPARATOR LINE z += LH - separatorHalfHeight - baselineToBot * self.scale[2] LSseparator.moveTo(0, 0, z) LSseparator.drawTo(self.scale[0] * .5, 0, z) LSseparator.drawTo(self.scale[0], 0, z) z -= separatorHalfHeight + baselineToTop * self.scale[2] maxWidth += 7 * arrowHalfHeight * ( anyArrow or anyShortcut) + .2 + shortcutTextMaxWidth arrowXpos = maxWidth - arrowHalfHeight realArrow.setX(arrowXpos) if anyImage: leftPad += 2 * imageHalfHeight + leftPad for sct in shortcutTexts: sct.setX(maxWidth - 2 * (arrowHalfHeight * anyArrow + .2)) for c in asList(self.menu.findAllMatches('**/DirectButton*')): numLines = c.node().getFrame()[2] c.node().setFrame( Vec4( -leftPad, maxWidth, -baselineToBot - (numLines * .1 * self.itemHeight if numLines >= 10 else 0), baselineToTop)) loadPrcFileData('', 'text-flatten 1') try: minZ = self.menu.getChild(0).getRelativePoint( b, Point3(0, 0, b.node().getFrame()[2]))[2] except: minZ = self.menu.getChild(0).getRelativePoint( self.menu, Point3( 0, 0, b.getTightBounds()[0][2]))[2] - baselineToBot * .5 try: top = self.menu.getChild(0).node().getFrame()[3] except: top = self.menu.getChild(0).getZ() + baselineToTop l, r, b, t = -leftPad - bgPad / self.scale[ 0], maxWidth + bgPad / self.scale[0], minZ - bgPad / self.scale[ 2], top + bgPad / self.scale[2] menuBG = DirectFrame(parent=self.menu.getChild(0), frameSize=(l, r, b, t), frameColor=BGColor, state=DGG.NORMAL, suppressMouse=1) menuBorder = self.menu.getChild(0).attachNewNode('border') borderVtx = ( (l, 0, b), (l, 0, .5 * (b + t)), (l, 0, t), (.5 * (l + r), 0, t), (r, 0, t), (r, 0, .5 * (b + t)), (r, 0, b), (.5 * (l + r), 0, b), (l, 0, b), ) LSborderBG = LineSegs() LSborderBG.setThickness(4) LSborderBG.setColor(0, 0, 0, .7) LSborderBG.moveTo(*(borderVtx[0])) for v in borderVtx[1:]: LSborderBG.drawTo(*v) # fills the gap at corners for v in range(0, 7, 2): LSborderBG.moveTo(*(borderVtx[v])) menuBorder.attachNewNode(LSborderBG.create()) LSborder = LineSegs() LSborder.setThickness(2) LSborder.setColor(*BGBorderColor) LSborder.moveTo(*(borderVtx[0])) for v in borderVtx[1:]: LSborder.drawTo(*v) menuBorder.attachNewNode(LSborder.create()) for v in range(1, 8, 2): LSborderBG.setVertexColor(v, Vec4(0, 0, 0, .1)) LSborder.setVertexColor(v, Vec4(.3, .3, .3, .5)) menuBorderB3 = menuBorder.getTightBounds() menuBorderDims = menuBorderB3[1] - menuBorderB3[0] menuBG.wrtReparentTo(self.menu, sort=-1) self.menu.reparentTo(self.parent) x = -menuBorderB3[0][0] * self.scale[0] for c in asList(self.menu.getChildren()): c.setX(x) self.maxWidth = maxWidth = menuBorderDims[0] self.height = menuBorderDims[2] maxWidthR2D = maxWidth * self.menu.getChild(0).getSx(render2d) separatorLines = self.menu.attachNewNode(LSseparator.create(), 10) separatorLines.setSx(maxWidth) for v in range(1, LSseparator.getNumVertices(), 3): LSseparator.setVertexColor(v, Vec4(*separatorColor)) x = clamp(-.98, .98 - maxWidthR2D, self.mpos[0] - maxWidthR2D * .5) minZ = (-.98 if self.minZ is None else self.minZ) z = clamp( minZ + menuBorderDims[2] * self.scale[2] * self.parent.getSz(render2d), .98, self.mpos[1] if useMouseZ else -1000) self.menu.setPos(render2d, x, 0, z) self.menu.setTransparency(1) self.origBTprefix = self.BT.getPrefix() self.BT.setPrefix(self.BTprefix) self.accept(self.BTprefix + 'escape', self.destroy) for e in ('mouse1', 'mouse3'): self.accept(self.BTprefix + e, self.destroy, [True]) self.accept(self.BTprefix + 'arrow_down', self.__nextItem) self.accept(self.BTprefix + 'arrow_down-repeat', self.__nextItem) self.accept(self.BTprefix + 'arrow_up', self.__prevItem) self.accept(self.BTprefix + 'arrow_up-repeat', self.__prevItem) self.accept(self.BTprefix + 'enter', self.__runSelItemCommand) self.accept(self.BTprefix + 'space', self.__runSelItemCommand)
def __init__(self): self.base = ShowBase() self.thrust = 0.5 self.wind = 0.2 self.UP = Vec3(0, 0, 1) # might as well just make this a variable # set up camera self.base.disableMouse() self.base.camera.setPos(20, -20, 5) self.base.camera.lookAt(0, 0, 5) # Set up the collision traverser. If we bind it to base.cTrav, then Panda will handle # management of this traverser (for example, by calling traverse() automatically for us once per frame) self.base.cTrav = CollisionTraverser() # Now let's set up some collision bits for our masks self.ground_bit = 1 self.ball_bit = 2 self.base.setBackgroundColor(0.64, 0, 0) # First, we build a card to represent the ground cm = CardMaker('ground-card') cm.setFrame(-60, 60, -60, 60) card = self.base.render.attachNewNode(cm.generate()) card.lookAt(0, 0, -1) # align upright #tex = loader.loadTexture('maps/envir-ground.jpg') tex = loader.loadTexture('models/textures/rock12.bmp') card.setTexture(tex) # Then we build a collisionNode which has a plane solid which will be the ground's collision # representation groundColNode = card.attachNewNode(CollisionNode('ground-cnode')) groundColPlane = CollisionPlane(Plane(Vec3(0, -1, 0), Point3(0, 0, 0))) groundColNode.node().addSolid(groundColPlane) # Now, set the ground to the ground mask groundColNode.setCollideMask(BitMask32().bit(self.ground_bit)) # Why aren't we adding a collider? There is no need to tell the collision traverser about this # collisionNode, as it will automatically be an Into object during traversal. # enable forces self.base.enableParticles() node = NodePath("PhysicsNode") node.reparentTo(self.base.render) # may want to have force dependent on mass eventually, # but at the moment assume all balls same weight self.force_mag = 200 # gravity gravity_fn = ForceNode('world-forces') gravity_fnp = self.base.render.attachNewNode(gravity_fn) gravity_force = LinearVectorForce(0.0, 0.0, -9.81) gravity_fn.addForce(gravity_force) self.base.physicsMgr.addLinearForce(gravity_force) # wind wind_fn = ForceNode('world-forces') wind_fnp = self.base.render.attachNewNode(wind_fn) wind_force = LinearVectorForce(1.0, 0.5, 0.0) wind_fn.addForce(wind_force) self.base.physicsMgr.addLinearForce(wind_force) # spurt out of fountain, bounce self.spurt = ForceNode("spurt") spurt_np = self.base.render.attachNewNode(self.spurt) # create a list for our ball actors, not sure if I need this, but seems likely self.ball_actors = [] # make a teapot teapot = loader.loadModel('teapot.egg') tex = loader.loadTexture('maps/color-grid.rgb') #teapot.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition) teapot.setTexture(tex) teapot.reparentTo(self.base.render) teapot.setPos(-5, 10, 10) # create the first ball: #ball = self.create_a_ball() #self.enliven_ball(ball) smiley = loader.loadModel('smiley.egg') lerper = NodePath('lerper') smiley.setTexProjector(TextureStage.getDefault(), NodePath(), lerper) smiley.reparentTo(self.base.render) smiley.setPos(5, 10, 10) i = lerper.posInterval(5, VBase3(0, 1, 0)) i.loop() # Tell the messenger system we're listening for smiley-into-ground messages and invoke our callback self.base.accept('ball_cnode-into-ground-cnode', self.ground_callback) ball_fountain = taskMgr.doMethodLater(.5, self.spurt_balls, 'tickTask')
# Decompiled from: Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] # Embedded file name: direct.directtools.DirectGlobals from panda3d.core import Vec3, Point3, BitMask32 UNPICKABLE = [ 'x-disc-visible', 'y-disc-visible', 'z-disc-visible', 'GridBack', 'unpickable' ] X_AXIS = Vec3(1, 0, 0) Y_AXIS = Vec3(0, 1, 0) Z_AXIS = Vec3(0, 0, 1) NEG_X_AXIS = Vec3(-1, 0, 0) NEG_Y_AXIS = Vec3(0, -1, 0) NEG_Z_AXIS = Vec3(0, 0, -1) ZERO_VEC = ORIGIN = Vec3(0) UNIT_VEC = Vec3(1) ZERO_POINT = Point3(0) DIRECT_FLASH_DURATION = 1.5 MANIPULATION_MOVE_DELAY = 0.65 Q_EPSILON = 1e-10 DIRECT_NO_MOD = 0 DIRECT_SHIFT_MOD = 1 DIRECT_CONTROL_MOD = 2 DIRECT_ALT_MOD = 4 SKIP_NONE = 0 SKIP_HIDDEN = 1 SKIP_BACKFACE = 2 SKIP_CAMERA = 4 SKIP_UNPICKABLE = 8 SKIP_WIDGET = 16 SKIP_ALL = SKIP_HIDDEN | SKIP_BACKFACE | SKIP_CAMERA | SKIP_UNPICKABLE | SKIP_WIDGET EDIT_TYPE_UNMOVABLE = 1
def __defineConstants(self): self.TOON_SPEED = 8.0 self.TOON_Z = 0 self.MinSuitSpeedRange = [0.8 * self.TOON_SPEED, 0.6 * self.TOON_SPEED] self.MaxSuitSpeedRange = [1.1 * self.TOON_SPEED, 2.0 * self.TOON_SPEED] self.FASTER_SUIT_CURVE = 1 self.SLOWER_SUIT_CURVE = self.getDifficulty() < 0.5 self.slowerSuitPeriods = {2000: {4: [128, 76], 8: [128, 99, 81, 68], 12: [128, 108, 93, 82, 74, 67], 16: [128, 112, 101, 91, 83, 76, 71, 66]}, 1000: {4: [110, 69], 8: [110, 88, 73, 62], 12: [110, 95, 83, 74, 67, 61], 16: [110, 98, 89, 81, 75, 69, 64, 60]}, 5000: {4: [96, 63], 8: [96, 79, 66, 57], 12: [96, 84, 75, 67, 61, 56], 16: [96, 87, 80, 73, 68, 63, 59, 55]}, 4000: {4: [86, 58], 8: [86, 71, 61, 53], 12: [86, 76, 68, 62, 56, 52], 16: [86, 78, 72, 67, 62, 58, 54, 51]}, 3000: {4: [78, 54], 8: [78, 65, 56, 49], 12: [78, 69, 62, 57, 52, 48], 16: [78, 71, 66, 61, 57, 54, 51, 48]}, 9000: {4: [71, 50], 8: [71, 60, 52, 46], 12: [71, 64, 58, 53, 49, 45], 16: [71, 65, 61, 57, 53, 50, 47, 45]}} self.slowerSuitPeriodsCurve = {2000: {4: [128, 65], 8: [128, 78, 66, 64], 12: [128, 88, 73, 67, 64, 64], 16: [128, 94, 79, 71, 67, 65, 64, 64]}, 1000: {4: [110, 59], 8: [110, 70, 60, 58], 12: [110, 78, 66, 61, 59, 58], 16: [110, 84, 72, 65, 61, 59, 58, 58]}, 5000: {4: [96, 55], 8: [96, 64, 56, 54], 12: [96, 71, 61, 56, 54, 54], 16: [96, 76, 65, 59, 56, 55, 54, 54]}, 4000: {4: [86, 51], 8: [86, 59, 52, 50], 12: [86, 65, 56, 52, 50, 50], 16: [86, 69, 60, 55, 52, 51, 50, 50]}, 3000: {4: [78, 47], 8: [78, 55, 48, 47], 12: [78, 60, 52, 48, 47, 47], 16: [78, 63, 55, 51, 49, 47, 47, 47]}, 9000: {4: [71, 44], 8: [71, 51, 45, 44], 12: [71, 55, 48, 45, 44, 44], 16: [71, 58, 51, 48, 45, 44, 44, 44]}} self.fasterSuitPeriods = {2000: {4: [54, 42], 8: [59, 52, 47, 42], 12: [61, 56, 52, 48, 45, 42], 16: [61, 58, 54, 51, 49, 46, 44, 42]}, 1000: {4: [50, 40], 8: [55, 48, 44, 40], 12: [56, 52, 48, 45, 42, 40], 16: [56, 53, 50, 48, 45, 43, 41, 40]}, 5000: {4: [47, 37], 8: [51, 45, 41, 37], 12: [52, 48, 45, 42, 39, 37], 16: [52, 49, 47, 44, 42, 40, 39, 37]}, 4000: {4: [44, 35], 8: [47, 42, 38, 35], 12: [48, 45, 42, 39, 37, 35], 16: [49, 46, 44, 42, 40, 38, 37, 35]}, 3000: {4: [41, 33], 8: [44, 40, 36, 33], 12: [45, 42, 39, 37, 35, 33], 16: [45, 43, 41, 39, 38, 36, 35, 33]}, 9000: {4: [39, 32], 8: [41, 37, 34, 32], 12: [42, 40, 37, 35, 33, 32], 16: [43, 41, 39, 37, 35, 34, 33, 32]}} self.fasterSuitPeriodsCurve = {2000: {4: [62, 42], 8: [63, 61, 54, 42], 12: [63, 63, 61, 56, 50, 42], 16: [63, 63, 62, 60, 57, 53, 48, 42]}, 1000: {4: [57, 40], 8: [58, 56, 50, 40], 12: [58, 58, 56, 52, 46, 40], 16: [58, 58, 57, 56, 53, 49, 45, 40]}, 5000: {4: [53, 37], 8: [54, 52, 46, 37], 12: [54, 53, 52, 48, 43, 37], 16: [54, 54, 53, 51, 49, 46, 42, 37]}, 4000: {4: [49, 35], 8: [50, 48, 43, 35], 12: [50, 49, 48, 45, 41, 35], 16: [50, 50, 49, 48, 46, 43, 39, 35]}, 3000: {4: [46, 33], 8: [47, 45, 41, 33], 12: [47, 46, 45, 42, 38, 33], 16: [47, 46, 46, 45, 43, 40, 37, 33]}, 9000: {4: [43, 32], 8: [44, 42, 38, 32], 12: [44, 43, 42, 40, 36, 32], 16: [44, 44, 43, 42, 40, 38, 35, 32]}} self.CELL_WIDTH = MazeData.CELL_WIDTH self.MAX_FRAME_MOVE = self.CELL_WIDTH / 2 startOffset = 3 self.startPosHTable = [[Point3(0, startOffset, self.TOON_Z), 0], [Point3(0, -startOffset, self.TOON_Z), 180], [Point3(startOffset, 0, self.TOON_Z), 270], [Point3(-startOffset, 0, self.TOON_Z), 90]] self.camOffset = Vec3(0, -19, 45)
def doBillboardEffect(self): billboardEffect = BillboardEffect.make( Vec3(0, 0, 1), True, False, self.billboardOffset, base.cam, Point3(0, 0, 0)) self.contents.setEffect(billboardEffect)
def __showToonHitBySuit(self, avId, timestamp): toon = self.getAvatar(avId) if toon == None: return rng = self.toonRNGs[self.avIdList.index(avId)] curPos = toon.getPos(render) oldTrack = self.toonHitTracks[avId] if oldTrack.isPlaying(): oldTrack.finish() toon.setPos(curPos) toon.setZ(self.TOON_Z) parentNode = render.attachNewNode('mazeFlyToonParent-' + `avId`) parentNode.setPos(toon.getPos()) toon.reparentTo(parentNode) toon.setPos(0,0,0) startPos = parentNode.getPos() dropShadow = toon.dropShadow.copyTo(parentNode) dropShadow.setScale(toon.dropShadow.getScale(render)) trajectory = Trajectory.Trajectory( 0, Point3(0,0,0), Point3(0,0,50), gravMult=1.0) flyDur = trajectory.calcTimeOfImpactOnPlane(0.0) while 1: endTile = [rng.randint(2, self.maze.width-1), rng.randint(2, self.maze.height-1)] if self.maze.isWalkable(endTile[0], endTile[1]): break endWorldCoords = self.maze.tile2world(endTile[0], endTile[1]) endPos = Point3(endWorldCoords[0], endWorldCoords[1], startPos[2]) def flyFunc(t, trajectory, startPos = startPos, endPos = endPos, dur = flyDur, moveNode = parentNode, flyNode = toon): u = t/dur moveNode.setX(startPos[0] + u * (endPos[0]-startPos[0])) moveNode.setY(startPos[1] + u * (endPos[1]-startPos[1])) flyNode.setPos(trajectory.getPos(t)) flyTrack = Sequence( LerpFunctionInterval(flyFunc, fromData=0.0, toData=flyDur, duration=flyDur, extraArgs=[trajectory]), name=toon.uniqueName('hitBySuit-fly')) if avId != self.localAvId: cameraTrack = Sequence() else: self.camParent.reparentTo(parentNode) startCamPos = camera.getPos() destCamPos = camera.getPos() zenith = trajectory.getPos(flyDur/2.0)[2] destCamPos.setZ(zenith*1.3) destCamPos.setY(destCamPos[1]*0.3) def camTask(task, zenith = zenith, flyNode = toon, startCamPos = startCamPos, camOffset = destCamPos - startCamPos): u = flyNode.getZ()/zenith camera.setPos(startCamPos + camOffset*u) camera.lookAt(toon) return Task.cont camTaskName = 'mazeToonFlyCam-' + `avId` taskMgr.add(camTask, camTaskName, priority=20) def cleanupCamTask(self = self, toon = toon, camTaskName = camTaskName, startCamPos = startCamPos): taskMgr.remove(camTaskName) self.camParent.reparentTo(toon) camera.setPos(startCamPos) camera.lookAt(toon) cameraTrack = Sequence( Wait(flyDur), Func(cleanupCamTask), name='hitBySuit-cameraLerp') geomNode = toon.getGeomNode() startHpr = geomNode.getHpr() destHpr = Point3(startHpr) hRot = rng.randrange(1, 8) if rng.choice([0, 1]): hRot = -hRot destHpr.setX(destHpr[0] + hRot*360) spinHTrack = Sequence( LerpHprInterval(geomNode, flyDur, destHpr, startHpr=startHpr), Func(geomNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinH')) parent = geomNode.getParent() rotNode = parent.attachNewNode('rotNode') geomNode.reparentTo(rotNode) rotNode.setZ(toon.getHeight()/2.0) oldGeomNodeZ = geomNode.getZ() geomNode.setZ(-toon.getHeight()/2.0) startHpr = rotNode.getHpr() destHpr = Point3(startHpr) pRot = rng.randrange(1,3) if rng.choice([0, 1]): pRot = -pRot destHpr.setY(destHpr[1] + pRot*360) spinPTrack = Sequence( LerpHprInterval(rotNode, flyDur, destHpr, startHpr=startHpr), Func(rotNode.setHpr, startHpr), name=toon.uniqueName('hitBySuit-spinP')) i = self.avIdList.index(avId) soundTrack = Sequence( Func(base.playSfx, self.sndTable['hitBySuit'][i]), Wait(flyDur * (2.0/3.0)), SoundInterval(self.sndTable['falling'][i], duration=flyDur * (1.0/3.0)), name=toon.uniqueName('hitBySuit-soundTrack')) def preFunc(self = self, avId = avId, toon = toon, dropShadow = dropShadow): forwardSpeed = toon.forwardSpeed rotateSpeed = toon.rotateSpeed if avId == self.localAvId: self.orthoWalk.stop() else: toon.stopSmooth() if forwardSpeed or rotateSpeed: toon.setSpeed(forwardSpeed, rotateSpeed) toon.dropShadow.hide() def postFunc(self = self, avId = avId, oldGeomNodeZ = oldGeomNodeZ, dropShadow = dropShadow, parentNode = parentNode): if avId == self.localAvId: base.localAvatar.setPos(endPos) if hasattr(self, 'orthoWalk'): if self.gameFSM.getCurrentState().getName() == 'play': self.orthoWalk.start() dropShadow.removeNode() del dropShadow toon.dropShadow.show() geomNode = toon.getGeomNode() rotNode = geomNode.getParent() baseNode = rotNode.getParent() geomNode.reparentTo(baseNode) rotNode.removeNode() del rotNode geomNode.setZ(oldGeomNodeZ) toon.reparentTo(render) toon.setPos(endPos) parentNode.removeNode() del parentNode if avId != self.localAvId: toon.startSmooth() preFunc() hitTrack = Sequence(Parallel(flyTrack, cameraTrack, spinHTrack, spinPTrack, soundTrack), Func(postFunc), name=toon.uniqueName('hitBySuit')) self.toonHitTracks[avId] = hitTrack hitTrack.start(globalClockDelta.localElapsedTime(timestamp))
def pieHitsToon(self, toonId, timestamp, x, y, z): if toonId not in self.toonIds: return self.view.pieHitsToon(toonId, timestamp, Point3(x, y, z))
def makeDelaunayTriangulation(triangulator): """Takes a triangulation and turns it into a Delaunay triangulation""" # http://www.cs.uu.nl/geobook/interpolation.pdf # TODO: use this in a Triangulator object instead http://www.geom.uiuc.edu/~samuelp/del_project.html #return triangulator def getMinAngle(tri1, tri2): tri1vec1 = tri1[0] - tri1[1] tri1vec2 = tri1[1] - tri1[2] tri1vec3 = tri1[0] - tri1[2] # reverse the vector, so we don't get 180 degrees off by using the opposite vector tri1ang12 = abs(tri1vec1.relativeAngleDeg(-tri1vec2)) tri1ang23 = abs(tri1vec2.relativeAngleDeg(tri1vec3)) tri1ang13 = abs(tri1vec1.relativeAngleDeg(-tri1vec3)) minAng = min(tri1ang12, tri1ang23, tri1ang13) tri2vec1 = tri2[0] - tri2[1] tri2vec2 = tri2[1] - tri2[2] tri2vec3 = tri2[0] - tri2[2] tri2ang12 = abs(tri2vec1.relativeAngleDeg(-tri2vec2)) tri2ang23 = abs(tri2vec2.relativeAngleDeg(tri2vec3)) tri2ang13 = abs(tri2vec1.relativeAngleDeg(-tri2vec3)) if minAng > min(tri2ang12, tri2ang23, tri2ang13): minAng = min(tri2ang12, tri2ang23, tri2ang13) return minAng triLst = [] for i in range(0, triangulator.getNumTriangles()): v0 = triangulator.getVertex(triangulator.getTriangleV0(i)) v1 = triangulator.getVertex(triangulator.getTriangleV1(i)) v2 = triangulator.getVertex(triangulator.getTriangleV2(i)) triLst.append(Triangle(Point3(v0.x, v0.y, 0), Point3(v1.x, v1.y, 0), Point3(v2.x, v2.y, 0))) triLst = AdjacencyList(triLst) invalidFound = True while invalidFound: print "whild True" for i in range(0, len(triLst.adjLst)): needsReset = False currTri = triLst.adjLst[i] print "currTri\n", currTri if triLst.adjLst[i].n12: # if there's a neighbour on the 12 edge get it n1 = triLst.adjLst[triLst.adjLst[i].n12] else: n1 = None if triLst.adjLst[i].n23: # if there's a neighbour on the 23 edge get it n2 = triLst.adjLst[triLst.adjLst[i].n23] else: n2 = None if triLst.adjLst[i].n13: # if there's a neighbour on the 12 edge get it n3 = triLst.adjLst[triLst.adjLst[i].n13] else: n3 = None # TODO: arange these from highest to lowest according to their longest shared edge naybs = [n1, n2, n3] for n in naybs: if n is not None: sharedPts = currTri.getSharedPoints(n) # two points shared between the triangles notSharedPt = currTri.getNonSharedPoint(n) # one point in the current triangle, not in the other notSharedPtN = n.getNonSharedPoint(currTri) # one point in the other, not in the current print "nayb not None" # make sure this is a convex quadrilateral (else we would cut outside of the two triangles) # the non-shared point in the other triangle should be in the wedge formed by this triangle if isPointInWedge(notSharedPtN, [sharedPts[0], notSharedPt], [sharedPts[1], notSharedPt], inclusive=False): # don't include points on the edge # make two new triangles out of the polygon with a test-slice newCurr = copyAdjLstElement(currTri) newCurr.setTri(notSharedPt, notSharedPtN, sharedPts[0]) newN = copyAdjLstElement(n) newN.setTri(notSharedPt, notSharedPtN, sharedPts[1]) print "point in wedge old new curr\n", currTri.tri, "\n", n.tri minAngOld = getMinAngle(currTri.tri, n.tri) minAngNew = getMinAngle(newCurr.tri, newN.tri) if minAngNew > minAngOld: print "minAngNew > minAngOld" # maximize the minimum angle == Delaunay Triangulation triLst.adjLst[i] = newCurr triLst.adjLst[n.selfInd] = newN # we've changed the adjacency list # build a new one triLst = AdjacencyList(triLst.adjLst) # start over from the beginning needsReset = True break if needsReset: break # if we went through the whole list and didn't find an illegal triangle we're done if i == len(triLst.adjLst) - 1 and not needsReset: invalidFound = False return triLst