class SkyDome1(Att_base): def __init__(self, scene, dynamic=True, rate=(0.005,0.05), texturescale=(1000,1000), scale=(40,40,10), texturefile=None): Att_base.__init__(self,False, "Sky Dome 1") self.skybox = loader.loadModel("../media/models/dome2") self.skybox.setCollideMask(BitMask32().allOff()) self.skybox.setTwoSided(False) self.skybox.setScale(scale[0],scale[1],scale[2]) self.skybox.setLightOff() if texturefile == None: texturefile = "../media/textures/concrete.jpg" texture = loader.loadTexture(texturefile) self.textureStage0 = TextureStage("stage0") self.textureStage0.setMode(TextureStage.MReplace) self.skybox.setTexture(self.textureStage0,texture,1) self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1]) self.skybox.reparentTo(scene) def setTextureScale(self, texturescale): self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1]) def Destroy(self): self.skybox.removeNode() def setPos(self, v): self.skybox.setPos(v) def show(self): self.skybox.show() def hide(self): self.skybox.hide()
class DetailTexturer(TerrainTexturer): """adds a texture + detail texture to TerrainTiles""" def load(self): self.ts1 = TextureStage('ts2') tex = self.loadTexture("snow.jpg") tex.setWrapU(Texture.WMMirror) tex.setWrapV(Texture.WMMirror) self.monoTexture = tex self.loadDetail() def loadDetail(self): self.detailTS = TextureStage('ts') tex = self.loadTexture("Detail_COLOR.jpg") tex.setWrapU(Texture.WMMirror) tex.setWrapV(Texture.WMMirror) self.detailTexture = tex self.textureBlendMode = self.detailTS.MHeight self.detailTS.setMode(self.textureBlendMode) def apply(self, input): """Apply textures and shaders to the input.""" input.setTexture(self.ts1, self.monoTexture) input.setTexScale(self.ts1, 5, 5) input.setTexture(self.detailTS, self.detailTexture) input.setTexScale(self.detailTS, 120, 120) def setDetailBlendMode(self, num): """Set the blending mode of the detail texture.""" if (not self.detailTexture): return self.textureBlendMode = num #for pos, tile in self.tiles.items(): # if tile.detailTS: # tile.detailTS.setMode(self.textureBlendMode) self.detailTS.setMode(self.textureBlendMode) def incrementDetailBlendMode(self): """Set the blending mode of the detail texture.""" if (not self.detailTexture): return self.textureBlendMode += 1 self.setDetailBlendMode(self.textureBlendMode) def decrementDetailBlendMode(self): """Set the blending mode of the detail texture.""" if (not self.detailTexture): return self.textureBlendMode -= 1 self.setDetailBlendMode(self.textureBlendMode)
class DetailTexturer(TerrainTexturer): """adds a texture + detail texture to TerrainTiles""" def load(self): self.ts1 = TextureStage('ts2') tex = self.loadTexture("snow.jpg") tex.setWrapU(Texture.WMMirror) tex.setWrapV(Texture.WMMirror) self.monoTexture = tex self.loadDetail() def loadDetail(self): self.detailTS = TextureStage('ts') tex = self.loadTexture("Detail_COLOR.jpg") tex.setWrapU(Texture.WMMirror) tex.setWrapV(Texture.WMMirror) self.detailTexture = tex self.textureBlendMode = self.detailTS.MHeight self.detailTS.setMode(self.textureBlendMode) def apply(self, input): """Apply textures and shaders to the input.""" input.setTexture(self.ts1, self.monoTexture) input.setTexScale(self.ts1, 5, 5) input.setTexture(self.detailTS, self.detailTexture) input.setTexScale(self.detailTS, 120, 120) def setDetailBlendMode(self, num): """Set the blending mode of the detail texture.""" if (not self.detailTexture): return self.textureBlendMode = num #for pos, tile in self.tiles.items(): # if tile.detailTS: # tile.detailTS.setMode(self.textureBlendMode) self.detailTS.setMode(self.textureBlendMode) def incrementDetailBlendMode(self): """Set the blending mode of the detail texture.""" if (not self.detailTexture): return self.textureBlendMode += 1 self.setDetailBlendMode(self.textureBlendMode) def decrementDetailBlendMode(self): """Set the blending mode of the detail texture.""" if (not self.detailTexture): return self.textureBlendMode -= 1 self.setDetailBlendMode(self.textureBlendMode)
def UpdateTexture(self): if(not self.model): self.LoadContent() (u, v) = BlockGeometryGenerator.BlockIdToUV(self.currentBlockIdToPlace + 1) # Add 1 to offset from Air Id = 0 ts = TextureStage('ts') ts.setMode(TextureStage.MReplace) self.model.clearTexture() self.model.setTexture(ts, self.blockTexture) self.model.setTexOffset(ts, u[0], v[0]) self.model.setTexScale(ts, 0.0625, 0.0625)
def SetGeomTexture(geom, geomId, node, blockTexture): """ Applies the texture to the visible geometry of the Chunk.""" ts = TextureStage('ts') ts.setMode(TextureStage.MDecal) ts.setTexcoordName('light') # Setup the block texture attrib = TextureAttrib.make(blockTexture) # Add the light overlay #attrib = attrib.addOnStage(ts, geom['lighttexture']) # Apply the texture to the node node.setGeomState(geomId, node.getGeomState(geomId).addAttrib(attrib))
def Texture(self): """Applies textures and if needed shaders to the terrain. Call this initially, and whenever you have changed the size of some important textures, or added/removed some textures or changed the lighting mode. This function is automatically called by Initialize().""" if self.TextureMap == "": self.TextureMap = None if self.LightMap == "": self.LightMap = None # Does it have a detail map? if len(self.AlphaMaps) > 0: self._textureDetailed() elif self.TextureMap != None: self.Root.setTexture(self.TextureMap, 1) if self.LightMap != None: ts = TextureStage("LightMap") ts.setMode(TextureStage.MModulate) ts.setSort(2) self.Root.setTexture(ts, self.LightMap, 2) elif self.LightMap != None: self.Root.setTexture(ts, self.LightMap, 1)
def Texture(self): """Applies textures and if needed shaders to the terrain. Call this initially, and whenever you have changed the size of some important textures, or added/removed some textures or changed the lighting mode. This function is automatically called by Initialize().""" if self.TextureMap == "": self.TextureMap = None if self.LightMap == "": self.LightMap = None # Does it have a detail map? if len(self.AlphaMaps) > 0: self._textureDetailed() elif self.TextureMap != None: self.Root.setTexture(self.TextureMap, 1) if self.LightMap != None: ts = TextureStage("LightMap") ts.setMode(TextureStage.MModulate) ts.setSort(2) self.Root.setTexture(ts, self.LightMap, 2) elif self.LightMap != None: self.Root.setTexture(ts, self.LightMap, 1)
class SkyDome1(Att_base): def __init__(self, scene, dynamic=True, rate=(0.005, 0.05), texturescale=(1000, 1000), scale=(40, 40, 10), texturefile=None): Att_base.__init__(self, False, "Sky Dome 1") self.skybox = loader.loadModel("../media/models/dome2") self.skybox.setCollideMask(BitMask32().allOff()) self.skybox.setTwoSided(False) self.skybox.setScale(scale[0], scale[1], scale[2]) self.skybox.setLightOff() if texturefile == None: texturefile = "../media/textures/concrete.jpg" texture = loader.loadTexture(texturefile) self.textureStage0 = TextureStage("stage0") self.textureStage0.setMode(TextureStage.MReplace) self.skybox.setTexture(self.textureStage0, texture, 1) self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1]) self.skybox.reparentTo(scene) def setTextureScale(self, texturescale): self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1]) def Destroy(self): self.skybox.removeNode() def setPos(self, v): self.skybox.setPos(v) def show(self): self.skybox.show() def hide(self): self.skybox.hide()
class RepairLeak(DirectButton, FSM.FSM): __module__ = __name__ def __init__(self, name, parent, leakscale, **kw): self.name = name pitchingGui = loader.loadModel( 'models/gui/pir_m_gui_srp_pitching_main') self.hole = pitchingGui.find('**/hole') if random.random() > 0.5: self.holeFilled = pitchingGui.find('**/pitch1') else: self.holeFilled = pitchingGui.find('**/pitch2') optiondefs = (('relief', None, None), ('geom', (self.hole, self.hole, self.hole, self.holeFilled), None), ('rolloverSound', None, None), ('clickSound', None, None)) self.defineoptions(kw, optiondefs) DirectButton.__init__(self, parent=parent, **kw) self.initialiseoptions(RepairLeak) FSM.FSM.__init__(self, 'leak_%sFSM' % self.name) self.onCleanup = None self.leakScale = leakscale self.pitchingGame = parent self._initVars() self._initVisuals() self._initIntervals() self.fadeSequence = None self.request('Idle') return def _initVars(self): self.timeActive = 0.0 self.pulseScale = 0.6 def _initVisuals(self): textureCard = loader.loadModel('models/minigames/pir_m_gam_srp_water') self.waterStream = textureCard.find('**/waterPlane') tex = textureCard.findTexture('pir_t_gui_srp_waterDrops') textureCard2 = loader.loadModel('models/minigames/pir_m_gam_srp_water') self.waterStream2 = textureCard2.find('**/waterPlane') tex2 = textureCard2.findTexture('pir_t_gui_srp_waterDrops') alphaCard = loader.loadModel( 'models/minigames/pir_m_gui_srp_waterDropsAlpha') self.alphaWaterStream = textureCard.find( '**/pir_t_gui_srp_waterDropsAlpha') alphatex = alphaCard.find( '**/pir_t_gui_srp_waterDropsAlpha').findTexture('*') self.alphaWaterStream2 = textureCard.find( '**/pir_t_gui_srp_waterDropsAlpha2') alphatex2 = alphaCard.find( '**/pir_t_gui_srp_waterDropsAlpha2').findTexture('*') alphaCard2 = loader.loadModel( 'models/minigames/pir_m_gui_srp_waterDropsAlpha') self.alphaWaterStream3 = textureCard.find( '**/pir_t_gui_srp_waterDropsAlpha') alphatex3 = alphaCard2.findTexture('*') self.alphaWaterStream4 = textureCard.find( '**/pir_t_gui_srp_waterDropsAlpha2') alphatex4 = alphaCard2.findTexture('*') tex.setWrapU(Texture.WMRepeat) tex.setWrapV(Texture.WMRepeat) alphatex.setWrapU(Texture.WMRepeat) alphatex.setWrapV(Texture.WMRepeat) tex2.setWrapU(Texture.WMRepeat) tex2.setWrapV(Texture.WMRepeat) alphatex3.setWrapU(Texture.WMRepeat) alphatex3.setWrapV(Texture.WMRepeat) self.setScale(2.5 * self.leakScale) self.waterStream.setScale(self.leakScale) self.waterStream.setPos(self.getX(), 0.0, -0.5 * self.leakScale + self.getZ()) self.waterStream2.setScale(self.leakScale * 0.8, self.leakScale, self.leakScale * 1.2) self.waterStream2.setPos(self.getX(), 0.0, -0.6 * self.leakScale + self.getZ()) self.waterStream.setColor(0.7, 0.85, 1.0, 1.0) self.waterStream2.setColor(0.5, 0.6, 0.9, 1.0) self.waterStream2.reparentTo(self.pitchingGame) self.waterStream.reparentTo(self.pitchingGame) self.waterStream2.setBin('fixed', 42) self.waterStream.setBin('fixed', 40) self.textureYOffset = random.random() self.textureYDelta = 0.25 + 0.025 / self.leakScale self.textureYOffset2 = random.random() self.textureYDelta2 = 0.25412354 + 0.058754645634 / self.leakScale self.textureYOffsetAlpha = 0.0 self.textureYDeltaAlpha = 0.25 + 0.025 / self.leakScale self.textureYOffsetAlpha2 = 0.0 self.textureYDeltaAlpha2 = 0.25412354 + 0.058754645634 / self.leakScale self.textureStage = self.waterStream.findTextureStage('*') self.textureStage2 = self.waterStream2.findTextureStage('*') self.textureStage3 = TextureStage('alphaLayer') self.textureStage3.setMode(TextureStage.MModulate) self.textureStage3.setSort(1) self.waterStream.setTexture(self.textureStage3, alphatex) self.textureStage4 = TextureStage('alphaLayer2') self.textureStage4.setMode(TextureStage.MModulate) self.textureStage4.setSort(2) self.waterStream.setTexture(self.textureStage4, alphatex2) trans = TransformState.makePos((0, 0.48, 0)) self.waterStream.setTexTransform(self.textureStage4, trans) self.textureStage5 = TextureStage('alphaLayer3') self.textureStage5.setMode(TextureStage.MModulate) self.textureStage5.setSort(1) self.waterStream2.setTexture(self.textureStage5, alphatex3) self.textureStage6 = TextureStage('alphaLayer4') self.textureStage6.setMode(TextureStage.MModulate) self.textureStage6.setSort(2) self.waterStream2.setTexture(self.textureStage6, alphatex4) trans = TransformState.makePos((0, 0.48, 0)) self.waterStream2.setTexTransform(self.textureStage6, trans) def repositionTo(self, newX, newZ): self.setPos(newX, 0.0, newZ) self.waterStream.setPos(self.getX(), 0.0, -0.5 * self.leakScale + self.getZ()) self.waterStream2.setPos(self.getX(), 0.0, -0.6 * self.leakScale + self.getZ()) def _initIntervals(self): pass def destroy(self): if self.fadeSequence is not None: self.fadeSequence.clearToInitial() self['extraArgs'] = None taskMgr.remove('RepairLeak_%s.update' % self.name) if self.onCleanup is not None: self.onCleanup(self) self.cleanup() self.waterStream.removeNode() self.waterStream2.removeNode() DirectButton.destroy(self) return def update(self, task): dt = globalClock.getDt() self.timeActive += dt self.textureYOffset += self.textureYDelta * dt trans = TransformState.makePos((0, self.textureYOffset, 0)) self.waterStream.setTexTransform(self.textureStage, trans) done = False if self.getCurrentOrNextState() == 'Active': if self.textureYOffsetAlpha < _activePosition: self.textureYOffsetAlpha += self.textureYDeltaAlpha * dt if self.textureYOffsetAlpha > _activePosition: self.textureYOffsetAlpha = _activePosition trans2 = TransformState.makePos( (0, self.textureYOffsetAlpha, 0)) self.waterStream.setTexTransform(self.textureStage3, trans2) if self.getCurrentOrNextState() == 'Patched': if self.textureYOffsetAlpha < _activePosition: self.textureYOffsetAlpha = 0.75 - self.textureYOffsetAlpha / 2.0 trans2 = TransformState.makePos( (0, self.textureYOffsetAlpha, 0)) self.waterStream.setTexTransform(self.textureStage3, trans2) elif self.textureYOffsetAlpha < 1.0: self.textureYOffsetAlpha += self.textureYDeltaAlpha * dt trans2 = TransformState.makePos( (0, self.textureYOffsetAlpha, 0)) self.waterStream.setTexTransform(self.textureStage3, trans2) self.textureYOffset2 += self.textureYDelta2 * dt trans = TransformState.makePos((0, self.textureYOffset2, 0)) self.waterStream2.setTexTransform(self.textureStage2, trans) if self.getCurrentOrNextState( ) == 'Active' and self.textureYOffsetAlpha2 < _activePosition: self.textureYOffsetAlpha2 += self.textureYDeltaAlpha2 * dt if self.textureYOffsetAlpha2 > _activePosition: self.textureYOffsetAlpha2 = _activePosition trans2 = TransformState.makePos( (0, self.textureYOffsetAlpha2, 0)) self.waterStream2.setTexTransform(self.textureStage5, trans2) if self.getCurrentOrNextState() == 'Patched': if self.textureYOffsetAlpha2 < _activePosition: self.textureYOffsetAlpha2 = 0.75 - self.textureYOffsetAlpha2 / 2.0 trans2 = TransformState.makePos( (0, self.textureYOffsetAlpha2, 0)) self.waterStream2.setTexTransform(self.textureStage5, trans2) if self.textureYOffsetAlpha2 < 1.0: self.textureYOffsetAlpha2 += self.textureYDeltaAlpha2 * dt trans2 = TransformState.makePos( (0, self.textureYOffsetAlpha2, 0)) self.waterStream2.setTexTransform(self.textureStage5, trans2) else: done = True done and self.waterStream.stash() self.waterStream2.stash() self.fadeSequence = Sequence( LerpColorScaleInterval(self, duration=2.0, colorScale=(1.0, 1.0, 1.0, 0.0)), Func(self.destroy)) self.fadeSequence.start() return Task.done else: return Task.cont def setCommandButtons(self): self.guiItem.addClickButton(MouseButton.one()) self.bind(DGG.B1PRESS, self.commandFunc) def enterIdle(self): self.stash() self.waterStream.stash() self.waterStream2.stash() self['state'] = DGG.DISABLED def exitIdle(self): pass def enterPatched(self): self['state'] = DGG.DISABLED self.setScale(0.85) def exitPatched(self): self.stash() self.waterStream.stash() self.waterStream2.stash() def enterActive(self): taskMgr.add(self.update, 'RepairLeak_%s.update' % self.name) self.unstash() self.waterStream.unstash() self.waterStream2.unstash() self['state'] = DGG.NORMAL def exitActive(self): self['state'] = DGG.DISABLED
def construct_scene(lbase, modelpath, bgpath, scale, pos, hpr, bgscale, bghp, texture=None, internal_canonical=False, check_penetration=False, light_spec=None, use_envmap=False, shader=None, world_coords=False): """ Constructs the scene per the parameters. """ # Default scene is lbase's rootnode if bgpath is not None: bgpath = mt.resolve_bg_path(bgpath) rootnode = lbase.rootnode # Modelpath points to the model .egg/.bam file if isstring(modelpath): modelpaths = [modelpath] scales = [scale] poses = [pos] hprs = [hpr] textures = [texture] else: modelpaths = modelpath scales = scale poses = pos hprs = hpr textures = texture texmodes = [] for _i, _t in enumerate(textures): if isinstance(_t, tuple): texfile, texmode = _t texmodes.append(texmode) textures[_i] = texfile else: texmodes.append(TexGenAttrib.MWorldNormal) assert hasattr(modelpaths, '__iter__') assert hasattr(scales, '__iter__') assert hasattr(poses, '__iter__') assert hasattr(hprs, '__iter__') assert hasattr(textures, '__iter__') assert len(modelpaths) == len(scales) == len(hprs) == len(poses) == len( textures), (len(modelpaths), len(scales), len(hprs), len(poses), len(textures)) modelpaths = map(mt.resolve_model_path, modelpaths) modelpaths = map(cm.autogen_egg, modelpaths) textures = map(mt.resolve_texture_path, textures) objnodes = [] for mpth, scale, hpr, pos, t, tm in zip(modelpaths, scales, hprs, poses, textures, texmodes): objnode = tools.read_file(lbase.loader.loadModel, mpth) if t is not None: #ts = TextureStage('ts') ts = TextureStage.get_default() ts.setMode(TextureStage.MReplace) tex = tools.read_file(lbase.loader.loadTexture, t) objnode.setTexGen(ts, tm) objnode.setTexture(tex, 6) robjnode = rootnode.attachNewNode('root_' + objnode.get_name()) objnode.reparentTo(robjnode) if internal_canonical: vertices = np.array(objnode.getTightBounds()) initial_scale_factor = max(abs(vertices[0] - vertices[1])) cscale = 1.2 / initial_scale_factor ppos = vertices.mean(0) * cscale objnode.setPos(-ppos[0], -ppos[1], -ppos[2]) objnode.setScale(cscale, cscale, cscale) if world_coords: refnodeX = rootnode.attachNewNode('world_coords_x') refnodeY = rootnode.attachNewNode('world_coords_y') refnodeZ = rootnode.attachNewNode('world_coords_z') robjnode.wrtReparentTo(refnodeZ) refnodeZ.setH(refnodeX, hpr[2]) robjnode.wrtReparentTo(refnodeY) refnodeY.setP(refnodeX, hpr[1]) robjnode.wrtReparentTo(refnodeX) refnodeX.setR(refnodeX, hpr[0]) robjnode.wrtReparentTo(rootnode) else: robjnode.setHpr(hpr[2], hpr[1], hpr[0]) robjnode.setScale(scale[0], scale[0], scale[0]) robjnode.setPos(pos[0], -pos[2], pos[1]) robjnode.setTwoSided(1) objnodes.append(robjnode) if check_penetration: for (i, n1) in enumerate(objnodes): for j, n2 in enumerate(objnodes[i + 1:]): p = is_penetrating(n1, n2) if p: for onode in objnodes: onode.removeNode() raise PenetrationError(i, j, n1, n2) # Environment map if bgpath and use_envmap: envtex = tools.read_file(lbase.loader.loadTexture, bgpath) # Map onto object ts = TextureStage('env') ts.setMode(TextureStage.MBlendColorScale) if not isinstance(use_envmap, list): use_envmap = [use_envmap] * len(objnodes) for _objnode, ue in zip(objnodes, use_envmap): if ue: if isstring(ue): envtex0 = tools.read_file(lbase.loader.loadTexture, mt.resolve_texture_path(ue)) else: envtex0 = envtex _objnode.setTexGen(ts, TexGenAttrib.MEyeSphereMap) _objnode.setTexture(ts, envtex0) if bgpath and not np.isinf(bghp[0]): bgtex = tools.read_file(lbase.loader.loadTexture, bgpath) # Set as background #plane = cm.autogen_egg(mt.resolve_model_path('plane2d')) bgnode = lbase.loader.loadModel('smiley') # Get material list bgnode.clearMaterial() bgnode.clearTexture() bgnode.setAttrib( CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) bgnode.setTexture(bgtex, 2) c = 5. bgnode.setScale(c * bgscale[0], c * bgscale[0], c * bgscale[0]) bgnode.setPos(0, 0, 0) #0) bgnode.setHpr(bghp[0], bghp[1], 0.) # Detach point light plight1 = lbase.rootnode.find('**/plight1') if plight1: plight1.detachNode() elif bgpath: bgnode = NodePath("empty-bgnode") imageObject = OnscreenImage(image=bgpath, pos=(0, 0, 0), scale=tuple(bgscale), parent=bgnode, base=lbase) else: bgnode = NodePath("empty-bgnode") bgnode.reparentTo(rootnode) if shader is not None: vshaderpath, fshaderpath = shader rootnode.setShaderAuto() shader = Shader.load(Shader.SLGLSL, vshaderpath, fshaderpath) rootnode.setShader(shader) if light_spec is not None: lbase.rootnode.clearLight() lights = LightBase.make_lights(light_spec=light_spec, lname='scene_lights') lights.reparentTo(rootnode) for light in lights.getChildren(): rootnode.setLight(light) return objnodes, bgnode
class SkyDome2(Att_base): def __init__(self, scene, dynamic=True, rate=Vec4(0.004, 0.002, 0.008, 0.010), skycolor=Vec4(0.25, 0.5, 1, 0), texturescale=Vec4(1,1,1,1), scale=(4000,4000,1000), texturefile=None): Att_base.__init__(self,False, "Sky Dome 2") self.skybox = loader.loadModel("./media/models/dome2") self.skybox.reparentTo(scene) self.skybox.setScale(scale[0],scale[1],scale[2]) self.skybox.setLightOff() if texturefile == None: texturefile = "./media/textures/clouds_bw.png" texture = loader.loadTexture(texturefile) self.textureStage0 = TextureStage("stage0") self.textureStage0.setMode(TextureStage.MReplace) self.skybox.setTexture(self.textureStage0,texture,1) #self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1]) self.rate = rate self.textureScale = texturescale self.skycolor = skycolor self.dynamic = dynamic if self.dynamic: self.skybox.setShader( loader.loadShader( './media/shaders/skydome2.sha' ) ) self.setShaderInput() def setRate(self, rate): self.rate = rate def setTextureScale(self, texturescale): self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1]) def Destroy(self): self.skybox.clearShader() self.skybox.removeNode() def setPos(self, v): self.skybox.setPos(v) def show(self): self.skybox.show() def hide(self): self.skybox.hide() def setStandardControl(self): self.att_rate = Att_Vecs(False,"Cloud Speed",4,self.rate,-1,1,3) self.att_scale = Att_Vecs(False, "Tex-scale", 4, self.textureScale, 0.01, 100.0, 2) self.att_skycolor = Att_color(False, "Sky Color", self.skycolor) self.att_rate.setNotifier(self.changeParams) self.att_scale.setNotifier(self.changeParams) self.att_skycolor.setNotifier(self.changeParams) def changeParams(self, object): self.rate = self.att_rate.getValue() self.skycolor = self.att_skycolor.getColor() self.textureScale = self.att_scale.getValue() self.setShaderInput() #def skyboxscalechange(self,object): # self.setTextureScale(self.att_scale.getValue()) def setShaderInput(self): self.skybox.setShaderInput("sky", self.skycolor) self.skybox.setShaderInput("clouds", self.rate) self.skybox.setShaderInput("ts", self.textureScale)
def construct_scene(lbase, modelpath, bgpath, scale, pos, hpr, bgscale, bghp, texture=None, internal_canonical=False, check_penetration=False, light_spec=None, use_envmap=False): """ Constructs the scene per the parameters. """ # Default scene is lbase's rootnode if bgpath is not None: bgpath = mt.resolve_bg_path(bgpath) rootnode = lbase.rootnode # Modelpath points to the model .egg/.bam file if isinstance(modelpath, str): modelpaths = [modelpath] scales = [scale] poses = [pos] hprs = [hpr] textures = [texture] else: modelpaths = modelpath scales = scale poses = pos hprs = hpr textures = texture texmodes = [] for _i, _t in enumerate(textures): if isinstance(_t, tuple): texfile, texmode = _t texmodes.append(texmode) textures[_i] = texfile else: texmodes.append(TexGenAttrib.MWorldNormal) assert hasattr(modelpaths, '__iter__') assert hasattr(scales, '__iter__') assert hasattr(poses, '__iter__') assert hasattr(hprs, '__iter__') assert hasattr(textures, '__iter__') assert len(modelpaths) == len(scales) == len(hprs) == len(poses) == len(textures), (len(modelpaths), len(scales), len(hprs), len(poses), len(textures)) modelpaths = map(mt.resolve_model_path, modelpaths) modelpaths = map(cm.autogen_egg, modelpaths) textures = map(mt.resolve_texture_path, textures) objnodes = [] for mpth, scale, hpr, pos, t, tm in zip(modelpaths, scales, hprs, poses, textures, texmodes): objnode = tools.read_file(lbase.loader.loadModel, mpth) if t is not None: #ts = TextureStage('ts') ts = TextureStage.get_default() ts.setMode(TextureStage.MReplace) tex = tools.read_file(lbase.loader.loadTexture, t) objnode.setTexGen(ts, tm) objnode.setTexture(tex, 6) robjnode = rootnode.attachNewNode('root_' + objnode.get_name()) objnode.reparentTo(robjnode) if internal_canonical: vertices = np.array(objnode.getTightBounds()) initial_scale_factor = max(abs(vertices[0]-vertices[1])) cscale = 1.2/initial_scale_factor ppos = vertices.mean(0) * cscale objnode.setPos(-ppos[0], -ppos[1], -ppos[2]) objnode.setScale(cscale, cscale, cscale) robjnode.setScale(scale[0], scale[0], scale[0]) robjnode.setPos(pos[0], -pos[2], pos[1]) robjnode.setHpr(hpr[2], hpr[1], hpr[0]) robjnode.setTwoSided(1) objnodes.append(robjnode) if check_penetration: for (i, n1) in enumerate(objnodes): for j, n2 in enumerate(objnodes[i+1:]): p = is_penetrating(n1, n2) if p: for onode in objnodes: onode.removeNode() raise PenetrationError(i, j, n1, n2) # Environment map if bgpath and use_envmap: envtex = tools.read_file(lbase.loader.loadTexture, bgpath) # Map onto object ts = TextureStage('env') ts.setMode(TextureStage.MBlendColorScale) if not isinstance(use_envmap, list): use_envmap = [use_envmap] * len(objnodes) for _objnode, ue in zip(objnodes, use_envmap): if ue: if isinstance(ue, str): envtex0 = tools.read_file(lbase.loader.loadTexture, mt.resolve_texture_path(ue)) else: envtex0 = envtex _objnode.setTexGen(ts, TexGenAttrib.MEyeSphereMap) _objnode.setTexture(ts, envtex0) if bgpath and not np.isinf(bghp[0]): bgtex = tools.read_file(lbase.loader.loadTexture, bgpath) # Set as background #plane = cm.autogen_egg(mt.resolve_model_path('plane2d')) bgnode = lbase.loader.loadModel('smiley') # Get material list bgnode.clearMaterial() bgnode.clearTexture() bgnode.setAttrib(CullFaceAttrib.make( CullFaceAttrib.MCullCounterClockwise)) bgnode.setTexture(bgtex, 2) c = 5. bgnode.setScale(c * bgscale[0], c * bgscale[0], c * bgscale[0]) bgnode.setPos(0, 0, 0) #0) bgnode.setHpr(bghp[0], bghp[1], 0.) # Detach point light plight1 = lbase.rootnode.find('**/plight1') if plight1: plight1.detachNode() elif bgpath: bgnode = NodePath("empty-bgnode") imageObject = OnscreenImage(image = bgpath, pos = (0, 0, 0), scale=tuple(bgscale), parent=bgnode, base=lbase) else: bgnode = NodePath("empty-bgnode") bgnode.reparentTo(rootnode) if light_spec is not None: lbase.rootnode.clearLight() lights = LightBase.make_lights(light_spec=light_spec, lname='scene_lights') lights.reparentTo(rootnode) for light in lights.getChildren(): rootnode.setLight(light) return objnodes, bgnode
class RepairLeak(DirectButton, FSM.FSM): def __init__(self, name, parent, leakscale, **kw): self.name = name pitchingGui = loader.loadModel('models/gui/pir_m_gui_srp_pitching_main') self.hole = pitchingGui.find('**/hole') if random.random() > 0.5: self.holeFilled = pitchingGui.find('**/pitch1') else: self.holeFilled = pitchingGui.find('**/pitch2') optiondefs = (('relief', None, None), ('geom', (self.hole, self.hole, self.hole, self.holeFilled), None), ('rolloverSound', None, None), ('clickSound', None, None)) self.defineoptions(kw, optiondefs) DirectButton.__init__(self, parent = parent) self.initialiseoptions(RepairLeak) FSM.FSM.__init__(self, 'leak_%sFSM' % self.name) self.onCleanup = None self.leakScale = leakscale self.pitchingGame = parent self._initVars() self._initVisuals() self._initIntervals() self.fadeSequence = None self.request('Idle') def _initVars(self): self.timeActive = 0.0 self.pulseScale = 0.59999999999999998 def _initVisuals(self): textureCard = loader.loadModel('models/minigames/pir_m_gam_srp_water') self.waterStream = textureCard.find('**/waterPlane') tex = textureCard.findTexture('pir_t_gui_srp_waterDrops') textureCard2 = loader.loadModel('models/minigames/pir_m_gam_srp_water') self.waterStream2 = textureCard2.find('**/waterPlane') tex2 = textureCard2.findTexture('pir_t_gui_srp_waterDrops') alphaCard = loader.loadModel('models/minigames/pir_m_gui_srp_waterDropsAlpha') self.alphaWaterStream = textureCard.find('**/pir_t_gui_srp_waterDropsAlpha') alphatex = alphaCard.find('**/pir_t_gui_srp_waterDropsAlpha').findTexture('*') self.alphaWaterStream2 = textureCard.find('**/pir_t_gui_srp_waterDropsAlpha2') alphatex2 = alphaCard.find('**/pir_t_gui_srp_waterDropsAlpha2').findTexture('*') alphaCard2 = loader.loadModel('models/minigames/pir_m_gui_srp_waterDropsAlpha') self.alphaWaterStream3 = textureCard.find('**/pir_t_gui_srp_waterDropsAlpha') alphatex3 = alphaCard2.findTexture('*') self.alphaWaterStream4 = textureCard.find('**/pir_t_gui_srp_waterDropsAlpha2') alphatex4 = alphaCard2.findTexture('*') tex.setWrapU(Texture.WMRepeat) tex.setWrapV(Texture.WMRepeat) alphatex.setWrapU(Texture.WMRepeat) alphatex.setWrapV(Texture.WMRepeat) tex2.setWrapU(Texture.WMRepeat) tex2.setWrapV(Texture.WMRepeat) alphatex3.setWrapU(Texture.WMRepeat) alphatex3.setWrapV(Texture.WMRepeat) self.setScale(2.5 * self.leakScale) self.waterStream.setScale(self.leakScale) self.waterStream.setPos(self.getX(), 0.0, -0.5 * self.leakScale + self.getZ()) self.waterStream2.setScale(self.leakScale * 0.80000000000000004, self.leakScale, self.leakScale * 1.2) self.waterStream2.setPos(self.getX(), 0.0, -0.59999999999999998 * self.leakScale + self.getZ()) self.waterStream.setColor(0.69999999999999996, 0.84999999999999998, 1.0, 1.0) self.waterStream2.setColor(0.5, 0.59999999999999998, 0.90000000000000002, 1.0) self.waterStream2.reparentTo(self.pitchingGame) self.waterStream.reparentTo(self.pitchingGame) self.waterStream2.setBin('fixed', 42) self.waterStream.setBin('fixed', 40) self.textureYOffset = random.random() self.textureYDelta = 0.25 + 0.025000000000000001 / self.leakScale self.textureYOffset2 = random.random() self.textureYDelta2 = 0.25412353999999998 + 0.058754645634 / self.leakScale self.textureYOffsetAlpha = 0.0 self.textureYDeltaAlpha = 0.25 + 0.025000000000000001 / self.leakScale self.textureYOffsetAlpha2 = 0.0 self.textureYDeltaAlpha2 = 0.25412353999999998 + 0.058754645634 / self.leakScale self.textureStage = self.waterStream.findTextureStage('*') self.textureStage2 = self.waterStream2.findTextureStage('*') self.textureStage3 = TextureStage('alphaLayer') self.textureStage3.setMode(TextureStage.MModulate) self.textureStage3.setSort(1) self.waterStream.setTexture(self.textureStage3, alphatex) self.textureStage4 = TextureStage('alphaLayer2') self.textureStage4.setMode(TextureStage.MModulate) self.textureStage4.setSort(2) self.waterStream.setTexture(self.textureStage4, alphatex2) trans = TransformState.makePos((0, 0.47999999999999998, 0)) self.waterStream.setTexTransform(self.textureStage4, trans) self.textureStage5 = TextureStage('alphaLayer3') self.textureStage5.setMode(TextureStage.MModulate) self.textureStage5.setSort(1) self.waterStream2.setTexture(self.textureStage5, alphatex3) self.textureStage6 = TextureStage('alphaLayer4') self.textureStage6.setMode(TextureStage.MModulate) self.textureStage6.setSort(2) self.waterStream2.setTexture(self.textureStage6, alphatex4) trans = TransformState.makePos((0, 0.47999999999999998, 0)) self.waterStream2.setTexTransform(self.textureStage6, trans) def repositionTo(self, newX, newZ): self.setPos(newX, 0.0, newZ) self.waterStream.setPos(self.getX(), 0.0, -0.5 * self.leakScale + self.getZ()) self.waterStream2.setPos(self.getX(), 0.0, -0.59999999999999998 * self.leakScale + self.getZ()) def _initIntervals(self): pass def destroy(self): if self.fadeSequence is not None: self.fadeSequence.clearToInitial() self['extraArgs'] = None taskMgr.remove('RepairLeak_%s.update' % self.name) if self.onCleanup is not None: self.onCleanup(self) self.cleanup() self.waterStream.removeNode() self.waterStream2.removeNode() DirectButton.destroy(self) def update(self, task): dt = globalClock.getDt() self.timeActive += dt self.textureYOffset += self.textureYDelta * dt trans = TransformState.makePos((0, self.textureYOffset, 0)) self.waterStream.setTexTransform(self.textureStage, trans) done = False if self.getCurrentOrNextState() == 'Active' and self.textureYOffsetAlpha < _activePosition: self.textureYOffsetAlpha += self.textureYDeltaAlpha * dt if self.textureYOffsetAlpha > _activePosition: self.textureYOffsetAlpha = _activePosition trans2 = TransformState.makePos((0, self.textureYOffsetAlpha, 0)) self.waterStream.setTexTransform(self.textureStage3, trans2) if self.getCurrentOrNextState() == 'Patched': if self.textureYOffsetAlpha < _activePosition: self.textureYOffsetAlpha = 0.75 - self.textureYOffsetAlpha / 2.0 trans2 = TransformState.makePos((0, self.textureYOffsetAlpha, 0)) self.waterStream.setTexTransform(self.textureStage3, trans2) elif self.textureYOffsetAlpha < 1.0: self.textureYOffsetAlpha += self.textureYDeltaAlpha * dt trans2 = TransformState.makePos((0, self.textureYOffsetAlpha, 0)) self.waterStream.setTexTransform(self.textureStage3, trans2) self.textureYOffset2 += self.textureYDelta2 * dt trans = TransformState.makePos((0, self.textureYOffset2, 0)) self.waterStream2.setTexTransform(self.textureStage2, trans) if self.getCurrentOrNextState() == 'Active' and self.textureYOffsetAlpha2 < _activePosition: self.textureYOffsetAlpha2 += self.textureYDeltaAlpha2 * dt if self.textureYOffsetAlpha2 > _activePosition: self.textureYOffsetAlpha2 = _activePosition trans2 = TransformState.makePos((0, self.textureYOffsetAlpha2, 0)) self.waterStream2.setTexTransform(self.textureStage5, trans2) if self.getCurrentOrNextState() == 'Patched': if self.textureYOffsetAlpha2 < _activePosition: self.textureYOffsetAlpha2 = 0.75 - self.textureYOffsetAlpha2 / 2.0 trans2 = TransformState.makePos((0, self.textureYOffsetAlpha2, 0)) self.waterStream2.setTexTransform(self.textureStage5, trans2) if self.textureYOffsetAlpha2 < 1.0: self.textureYOffsetAlpha2 += self.textureYDeltaAlpha2 * dt trans2 = TransformState.makePos((0, self.textureYOffsetAlpha2, 0)) self.waterStream2.setTexTransform(self.textureStage5, trans2) else: done = True if done: self.waterStream.stash() self.waterStream2.stash() self.fadeSequence = Sequence(LerpColorScaleInterval(self, duration = 2.0, colorScale = (1.0, 1.0, 1.0, 0.0)), Func(self.destroy)) self.fadeSequence.start() return Task.done else: return Task.cont def setCommandButtons(self): self.guiItem.addClickButton(MouseButton.one()) self.bind(DGG.B1PRESS, self.commandFunc) def enterIdle(self): self.stash() self.waterStream.stash() self.waterStream2.stash() self['state'] = DGG.DISABLED def exitIdle(self): pass def enterPatched(self): self['state'] = DGG.DISABLED self.setScale(0.84999999999999998) def exitPatched(self): self.stash() self.waterStream.stash() self.waterStream2.stash() def enterActive(self): taskMgr.add(self.update, 'RepairLeak_%s.update' % self.name) self.unstash() self.waterStream.unstash() self.waterStream2.unstash() self['state'] = DGG.NORMAL def exitActive(self): self['state'] = DGG.DISABLED
class SkyDome2(Att_base): def __init__(self, scene, dynamic=True, rate=Vec4(0.004, 0.002, 0.008, 0.010), skycolor=Vec4(0.25, 0.5, 1, 0), texturescale=Vec4(1, 1, 1, 1), scale=(4000, 4000, 1000), texturefile=None): Att_base.__init__(self, False, "Sky Dome 2") self.skybox = loader.loadModel("./media/models/dome2") self.skybox.reparentTo(scene) self.skybox.setScale(scale[0], scale[1], scale[2]) self.skybox.setLightOff() if texturefile == None: texturefile = "./media/textures/clouds_bw.png" texture = loader.loadTexture(texturefile) self.textureStage0 = TextureStage("stage0") self.textureStage0.setMode(TextureStage.MReplace) self.skybox.setTexture(self.textureStage0, texture, 1) #self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1]) self.rate = rate self.textureScale = texturescale self.skycolor = skycolor self.dynamic = dynamic if self.dynamic: self.skybox.setShader( loader.loadShader('./media/shaders/skydome2.sha')) self.setShaderInput() def setRate(self, rate): self.rate = rate def setTextureScale(self, texturescale): self.skybox.setTexScale(self.textureStage0, texturescale[0], texturescale[1]) def Destroy(self): self.skybox.clearShader() self.skybox.removeNode() def setPos(self, v): self.skybox.setPos(v) def show(self): self.skybox.show() def hide(self): self.skybox.hide() def setStandardControl(self): self.att_rate = Att_Vecs(False, "Cloud Speed", 4, self.rate, -1, 1, 3) self.att_scale = Att_Vecs(False, "Tex-scale", 4, self.textureScale, 0.01, 100.0, 2) self.att_skycolor = Att_color(False, "Sky Color", self.skycolor) self.att_rate.setNotifier(self.changeParams) self.att_scale.setNotifier(self.changeParams) self.att_skycolor.setNotifier(self.changeParams) def changeParams(self, object): self.rate = self.att_rate.getValue() self.skycolor = self.att_skycolor.getColor() self.textureScale = self.att_scale.getValue() self.setShaderInput() #def skyboxscalechange(self,object): # self.setTextureScale(self.att_scale.getValue()) def setShaderInput(self): self.skybox.setShaderInput("sky", self.skycolor) self.skybox.setShaderInput("clouds", self.rate) self.skybox.setShaderInput("ts", self.textureScale)
class Star(SphericalBody): ''' Class star contain attributes of the star and a list of all the planets orbiting the star. ''' def __init__(self, position, radius, player=None): ''' Constructor for class star: creates a dead star object, initializing the star's attributes with the given parameters. @param position : Point3D, the position of the center of the star @param radius : float, star radius @param player: Player, the owner of the star @param activated: boolean, determine whether star is activated by the player or not @param stage: Integer, is the stage in which the star is in; consists of 6 stages @param counter: Timer, is the count-down timer for the star's life ''' super(Star, self).__init__(position, radius, False, player) self.lifetime = 0 self._planets = [] self.stage = 0 self.timer_task = None self.t = Timer(self) self.__initSceneGraph() def __initSceneGraph(self): # Parent node for relative position (no scaling) self.point_path = render.attachNewNode("star_node") self.point_path.setPos(self.position) #For transforming the object with scaling, colors, shading, etc. # Hosting the actual 3d model object. #Models & textures self.flare_ts = TextureStage('flare') self.flare_ts.setMode(TextureStage.MModulateGlow) self.model_path = loader.loadModel("models/stars/planet_sphere") self.model_path.setTexture(SphericalBody.star_dead_tex, 1) self.model_path.reparentTo(self.point_path) self.model_path.setScale(self.radius) self.model_path.setPythonTag('pyStar', self); # Collision sphere for object picking #----------------------------------------------------- # As described in the Tut-Chessboard.py sample: "If this model was # any more complex than a single polygon, you should set up a collision # sphere around it instead." cnode = CollisionNode("coll_sphere_node") cnode.setTag('star', str(id(self))) #We use no displacement (0,0,0) and no scaling factor (1) cnode.addSolid(CollisionSphere(0,0,0,1)) cnode.setIntoCollideMask(BitMask32.bit(1)) self.cnode_path = self.model_path.attachNewNode(cnode) #For temporary testing, display collision sphere. # self.cnode_path.show() self.quad_path = None def activateHighlight(self, thin): if thin: tex = base.loader.loadTexture("models/billboards/thin_ring.png") else: tex = base.loader.loadTexture("models/billboards/ring.png") cm = CardMaker('highlight') cm.setFrameFullscreenQuad() # so that the center acts as the origin (from -1 to 1) self.quad_path = self.point_path.attachNewNode(cm.generate()) self.quad_path.setTransparency(TransparencyAttrib.MAlpha) self.highlight_ts = TextureStage('flare') self.quad_path.setTexture(self.highlight_ts, tex) if thin: self.quad_path.setColor(Vec4(1.0, 1.0, 1.0, 1)) else: self.quad_path.setColor(Vec4(1.0, 0.3, 0.2, 1)) self.quad_path.setScale(12) self.quad_path.setPos(Vec3(0,0,0)) self.quad_path.setBillboardPointEye() def deactivateHighlight(self): if self.quad_path: self.quad_path.detachNode() self.quad_path = None def select(self, player): ''' @param player, the player who has selected This method observes the events on the star and calls the related methods and notifies the corresponding objects based on the state of the star ''' player.selected_planet = None if(player.ge_amount != 0 and self.activated == False and \ player.selected_star == self): player.ge_amount = player.ge_amount - 1 self.activateStar(player) self.notify("updateGE") else: # from gameEngine.gameEngine import all_stars # for star in all_stars: # if(star != self): # star.deactivateHighlight() from gameEngine.gameEngine import all_planets for planet in all_planets: planet.deactivateHighlight() '''TODO: fix the conflict problem with highlight and star flare ''' #self.activateHighlight(False) player.selected_star = self def activateStar(self, player): ''' Activates a constructed dead star object, starting the lifetime counter with the assigned default value while the Game Engine calls the graphic engine to display the corresponding animation. @param player, the player who has activated the star ''' self.lifetime = LIFETIME self.stage = 1 self.activated = True self.radius = MAX_STAR_RADIUS self.player = player self.timer_task = taskMgr.doMethodLater(1, self.trackStarLife, 'starLifeTick') player.selected_star = self # point_light = PointLight("starLight") # point_light.setColor(Vec4(1.0, 1.0, 1.0, 1.0)) # pt_node = render.attachNewNode(point_light) ## pt_node.setHpr(60, 0, 90) # pt_node.setPos(Vec3(0, 0, -40.0)) # render.setLight(pt_node) point_light = PointLight("starLight") point_light.setColor(Vec4(1.0, 1.0, 1.0, 1.0)) point_light.setPoint(Point3(0, 0, 0)) pt_node = self.point_path.attachNewNode(point_light) # pt_node.setHpr(60, 0, 90) render.setLight(pt_node) '''TODO : display star birth animation ''' star_created_sound = base.loader.loadSfx("sound/effects/star/starCreation1.wav") star_created_sound.setVolume(0.6) star_created_sound.play() # base.sfxManagerList[0].update() # SphericalBody.star_created_sound1.play() #SphericalBody.star_created_sound2.play() self.radius = MAX_STAR_RADIUS self.model_path.setScale(self.radius) self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage1_tex) self._activateSunflare() def _activateSunflare(self): self.deactivateHighlight() flare_tex = base.loader.loadTexture("models/billboards/sunflare.png") cm = CardMaker('flare') cm.setFrameFullscreenQuad() # so that the center acts as the origin (from -1 to 1) self.flare_path = self.point_path.attachNewNode(cm.generate()) self.flare_path.setTransparency(TransparencyAttrib.MAlpha) self.flare_path.setTexture(self.flare_ts,flare_tex) self.flare_path.setColor(Vec4(1.0, 1.0, 1.0, 1)) self.flare_path.setScale(50) self.flare_path.setPos(Vec3(0,0,0)) self.flare_path.setBillboardPointEye() self.flare_path.setLightOff() def trackStarLife(self, task): self.lifetime = self.lifetime - float(self.getNumberOfActivePlanets()+1)/(2) from graphicEngine import indicators indicators.drawStarProgressBar(self, self.lifetime) # self.updateTimer() if(self.lifetime <= LIFETIME - LIFETIME/6 and self.stage == 1): self.stage = 2 self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage2_tex) elif(self.lifetime <= LIFETIME - LIFETIME/3 and self.stage == 2): self.stage = 3 self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage3_tex) elif(self.lifetime <= LIFETIME - LIFETIME/2 and self.stage == 3): self.stage = 4 self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage4_tex) elif(self.lifetime <= LIFETIME - 2*LIFETIME/3 and self.stage == 4): self.stage = 5 self.model_path.setTexture(self.flare_ts, SphericalBody.star_stage5_tex) elif(self.lifetime <= 0 and self.stage == 5): self.lifetime = 0 self.stage = 6 self.model_path.setTexture(SphericalBody.star_stage6_tex, 1) self._consumeSolarSystem() # timer_destruction= taskMgr.doMethodLater(1, self._consumeSolarSystem, 'consumeSolarSystem') '''calls the escape solar system routine from the AI class''' from gameEngine.gameEngine import ai task = taskMgr.doMethodLater(AI_ESCAPE_WAIT_TIME, ai.escapeStar, 'AIescapeStar', extraArgs =[self], appendTask=True) return task.done return task.again def _consumeSolarSystem(self):#, task): for planet in self.planets(): planet.startCollapse() # def updateTimer(self): # self.notify("updateTime") def addPlanet(self, planet): ''' Adds a planet to the star system @param: planet object ''' if(len(self._planets) < MAX_NUMBER_OF_PLANETS): self._planets.append(planet) def removePlanet(self, planet): ''' removes a planet from the star system @param planet object ''' if len(self._planets) != 0: self._planets.remove(planet) def removeAllPlanets(self): ''' removes all the planets in the star system ''' del self._planets[:] def planets(self): ''' Generator that iterates over the hosted planets. ''' for planet in self._planets: yield planet def getPlanetAt(self, orbit): ''' Returns the planet at the desired orbit @param orbit is an integer ''' return self._planets[orbit] def getNextDeadPlanet(self): ''' returns next un-activated planet ''' for planet in self._planets: if not planet.activated: return planet return None def getlastPlanet(self): ''' returns the last planet in the solar system ''' if(self.getNumberOfPlanets()!=0): return self._planets[-1] def getOrbit(self, planet): return self._planets.index(planet) def getPlanet(self, planet): ''' Returns the index of the given planet from list of planets @param planet : the desired planet ''' return self._planets.index(planet) def getNumberOfPlanets(self): ''' Returns the number of dead planets currently around the star ''' return len(self._planets) def getNumberOfActivePlanets(self): ''' Returns the number of planets currently orbiting the star ''' total = 0 for planet in self.planets(): if(planet.activated): total = total + 1 return total
class Planet(SphericalBody): ''' Planet contains units and structures ''' def __init__(self, orbital_radius, orbital_angle, radius, parent_star, prev_planet=None, player=None): ''' Constructor for class planet. @param position: Point3D, position in space @param radius: float, body radius @param player: Player, the owner of the planet @param parent_star: Star, the specific star the planet is orbiting around @param prev_planet: previous planet in the star system, if None then the planet is the first ''' position = Point3(orbital_radius * math.cos(orbital_angle), orbital_radius * math.sin(orbital_angle), 0) super(Planet, self).__init__(position, radius, False, player) self.orbital_velocity = 0 self.max_orbital_velocity = 0 self.orbital_radius = orbital_radius self.orbital_angle = orbital_angle self.parent_star = parent_star self.prev_planet = prev_planet self.next_planet = None self._orbiting_units = [] self._surface_structures = [] self.__initSceneGraph() '''For the Player''' self.task_structure_timer = None self.task_unit_timer = None '''For the AI''' self.task_structure_timers = [] self.task_unit_timers = [] def __initSceneGraph(self): #load various texture stages of the planet self.forge_tex = TextureStage('forge') self.forge_tex.setMode(TextureStage.MDecal) self.nexus_tex = TextureStage('nexus') self.nexus_tex.setMode(TextureStage.MDecal) self.extractor_phylon_ge_tex = TextureStage('extractor_phylon_ge') self.extractor_phylon_ge_tex.setMode(TextureStage.MDecal) # Parent node for relative position (no scaling) self.point_path = self.parent_star.point_path.attachNewNode("planet_node") self.point_path.setPos(self.position) #Models & textures self.model_path = loader.loadModel("models/planets/planet_sphere") self.model_path.setTexture(SphericalBody.dead_planet_tex, 1) self.model_path.reparentTo(self.point_path) self.model_path.setScale(self.radius) self.model_path.setPythonTag('pyPlanet', self); cnode = CollisionNode("coll_sphere_node") cnode.setTag('planet', str(id(self))) #We use no displacement (0,0,0) and no scaling factor (1) cnode.addSolid(CollisionSphere(0,0,0,1)) cnode.setIntoCollideMask(BitMask32.bit(1)) # Reparenting the collision sphere so that it # matches the planet perfectly. self.cnode_path = self.model_path.attachNewNode(cnode) self.lines = LineNodePath(parent = self.parent_star.point_path, thickness = 4.0, colorVec = Vec4(1.0, 1.0, 1.0, 0.2)) self.quad_path = None def setTexture(self, structureType): ''' Used whenever a structure is built on the planet @ StructureType is a string specifying the type of the structure ''' if(structureType == "forge"): #SphericalBody.planet_forge_tex.setWrapU(Texture.WMInvalid) #SphericalBody.planet_forge_tex.setWrapV(Texture.WMInvalid) self.model_path.setTexture(self.forge_tex, SphericalBody.planet_forge_tex) #self.model_path.getTexture().setWrapU(Texture.WMClamp) #self.model_path.getTexture().setWrapV(Texture.WMClamp) self.model_path.setTexOffset(self.forge_tex, 0, 0) #self.model_path.setTexScale(self.forge_tex, -4, -2) elif(structureType == "nexus"): self.model_path.setTexture(self.nexus_tex, SphericalBody.planet_nexus_tex) self.model_path.setTexOffset(self.nexus_tex, 0, 10) elif(structureType == "extractor"): self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_extractor_tex) self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20) elif(structureType == "phylon"): self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_phylon_tex) self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20) elif(structureType == "generatorCore"): self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_generatorCore_tex) self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20) def activateHighlight(self, thin): if thin: flare_tex = base.loader.loadTexture("models/billboards/thin_ring.png") else: flare_tex = base.loader.loadTexture("models/billboards/ring.png") cm = CardMaker('quad') cm.setFrameFullscreenQuad() # so that the center acts as the origin (from -1 to 1) self.quad_path = self.point_path.attachNewNode(cm.generate()) self.quad_path.setTransparency(TransparencyAttrib.MAlpha) self.quad_path.setTexture(flare_tex) if thin: self.quad_path.setColor(Vec4(1,1,1, 1)) else: self.quad_path.setColor(Vec4(0.2, 0.3, 1.0, 1)) self.quad_path.setScale(5) self.quad_path.setPos(Vec3(0,0,0)) self.quad_path.setBillboardPointEye() def deactivateHighlight(self): if self.quad_path: self.quad_path.detachNode() self.quad_path = None def select(self, player): ''' This method observes the events on the planet and calls the related methods and notifies the corresponding objects based on the state of the planet @param player, the player who has selected ''' player.selected_star = None if(not self.activated and player.selected_planet == self): if((self.prev_planet == None or self.prev_planet.activated) and \ self.parent_star.activated and self.parent_star.player == player): self.activatePlanet(player) else: # from gameEngine.gameEngine import all_stars # for star in all_stars: # star.deactivateHighlight() from gameEngine.gameEngine import all_planets for planet in all_planets: if(self != planet or self.next_planet != planet or self.prev_planet != planet): planet.deactivateHighlight() if self.next_planet != None: self.next_planet.activateHighlight(True) if self.prev_planet != None: self.prev_planet.activateHighlight(True) self.activateHighlight(False) player.selected_planet = self from gameEngine.gameEngine import updateGUI updateGUI.refreshUnitsAndConstructions(self) def selectRight(self, player): ''' This method observes the events on the planet and calls the related methods and notifies the corresponding objects based on the state of the planet @param player, the player who has selected with right mouse click ''' move_occured = False for selected_unit in player.selected_units: if(selected_unit != None and selected_unit.player == player): '''movement is inside the solar system''' if(selected_unit.host_planet.parent_star == self.parent_star): if(selected_unit.host_planet == self.prev_planet): selected_unit.moveUnitNext() move_occured = True if(selected_unit.host_planet == self.next_planet): selected_unit.moveUnitPrev() move_occured = True else: '''movement is between solar systems in deep space''' if(self.next_planet == None and selected_unit.host_planet.next_planet == None): selected_unit.moveDeepSpace(self) move_occured = True if(len(player.selected_units)!=0 and move_occured): if(player.selected_units[0] != None and player.selected_units[0].move_unit != None): base.sfxManagerList[0].update() player.selected_units[0].move_unit.play() def activatePlanet(self, player): ''' Activates a constructed dead planet object, starting the orbital movement with the assigned value while the Game Engine calls the graphic engine to display the corresponding animation. @param player: Player, the player who controls the planet @precondition: MIN_PLANET_VELOCITY < orbital_velocity < MAX_PLANET_VELOCITY ''' self.activated = True player.planets.append(self) self.player = player planet_created_sound = base.loader.loadSfx("sound/effects/planet/planetCreation.wav") planet_created_sound.setVolume(0.3) planet_created_sound.play() # base.sfxManagerList[0].update() # SphericalBody.planet_created_sound.play() self.radius = MAX_PLANET_RADIUS self.model_path.setScale(self.radius) '''TODO : display planet creation animation ''' #rand = random.randrange(1,8,1) self.model_path.setTexture(SphericalBody.planet_activated_tex, 1) self.startSpin() # We want to avoid adding this task when the 'collapseOrbit' is already running if self.parent_star.lifetime != 0: taskMgr.add(self._accelerateOrbit, 'accelerateOrbit') self.orbit_path = shapes.makeArc(self.player.color, 360, int(self.orbital_radius)) self.orbit_path.reparentTo(self.parent_star.point_path) self.orbit_path.setScale(self.orbital_radius) from gameModel.ai import AI if(type(self.player) != AI): from gameEngine.gameEngine import updateGUI updateGUI.refreshUnitsAndConstructions(self) def startSpin(self): self.day_period = self.model_path.hprInterval(PLANET_SPIN_VELOCITY, Vec3(360, 0, 0)) self.day_period.loop() def startCollapse(self): try: if self.orbit_task: taskMgr.remove(self.orbit_task) except AttributeError: pass # no orbit on this planet (has not been activated) taskMgr.add(self._collapseOrbit, 'collapseOrbit') # taskMgr.setupTaskChain('collapseChain') # taskMgr.add(self._collapseOrbit, 'collapseOrbit')#, taskChain='collapseChain') # taskMgr.add(self._consume, 'consumePlanet', taskChain='collapseChain') # self.orbitTask = None def _consume(self): self._consumeUnits() self._consumeStructures() self.removeFromGame() def _accelerateOrbit(self, task): self.orbital_angle = self.orbital_angle + self.orbital_velocity self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi); self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle), self.orbital_radius * math.sin(self.orbital_angle), 0) self.position = self.point_path.getPos() self.orbital_velocity = self.orbital_velocity + 0.0001 if self.orbital_velocity > self.max_orbital_velocity: self.orbit_task = taskMgr.add(self._stepOrbit, 'stepOrbit') return task.done else: return task.cont def _stepOrbit(self, task): self.orbital_angle = self.orbital_angle + self.orbital_velocity self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi) self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle), self.orbital_radius * math.sin(self.orbital_angle), 0) self.position = self.point_path.getPos() return task.cont def _collapseOrbit(self, task): self.orbital_radius = self.orbital_radius - 0.23 self.orbital_angle = self.orbital_angle + self.orbital_velocity self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi) self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle), self.orbital_radius * math.sin(self.orbital_angle), 0) self.position = self.point_path.getPos() # if self.orbital_velocity < 0.01: if self.orbital_radius != 0: self.orbital_velocity = self.orbital_velocity + 0.01/(self.orbital_radius**2) try: self.orbit_path.setScale(self.orbital_radius) except AttributeError: pass # no orbit on this planet (has not been activated) if self.orbital_radius <= 0: self._consume() return task.done else: return task.cont def drawLines(self): # put some lighting on the line # for some reason the ambient and directional light in the environment drain out # all other colors in the scene # this is a temporary solution just so we can view the lines... the light can be removed and #a glow effect will be added later # alight = AmbientLight('alight') # alnp = render.attachNewNode(alight) # alight.setColor(Vec4(0.2, 0.2, 0.2, 1)) # render.setLight(alnp) self.lines.reset() self.lines.drawLines([((0,0, 0), (self.point_path.getX(), self.point_path.getY(), 0))]) self.lines.create() def drawConnections(self, task): # cur_pos = self.point_path.getPos() # paired_pos = pairedPlanetDraw.point_path.getPos() # paired_pos = self.point_path.getRelativePoint(pairedPlanetDraw.point_path, pairedPlanetDraw.point_path.getPos()) # print pairedPlanetDraw.point_path.getX(), pairedPlanetDraw.point_path.getY(), pairedPlanetDraw.point_path.getZ() self.connections.reset() if(self.next_planet): point_list = [] point_list.append((self.point_path.getPos(), self.next_planet.point_path.getPos())) self.connections.drawLines(point_list) self.connections.create() return task.cont def changePlayer(self, player): ''' Change the control of the planet from the self.player to the parameter player @param player: Player, the player who has captured the planet by swarms @precondition: the player must have used the capture ability of a swarm type unit on the planet ''' '''TODO: Use makeArc to change the color of the orbit''' ''' stop any constructions on the planet ''' if(self.task_structure_timer != None): taskMgr.remove(self.task_structure_timer) self.task_structure_timer = None if(self.task_unit_timer != None): taskMgr.remove(self.task_unit_timer) self.task_unit_timer = None if(self.task_structure_timers != None): taskMgr.remove(self.task_structure_timers) self.task_structure_timers = None if(self.task_unit_timers != None): taskMgr.remove(self.task_unit_timers) self.task_unit_timers = None ''' remove previous player's control from the planet ''' for structure in self.structures(): self.player.structures.remove(structure) ''' set control of the planet to the new player ''' for structure in self.structures(): player.structures.append(structure) ''' update the construction panel for the human player''' from gameModel.ai import AI ''' if human player is the previous owner ''' if(type(self.player) != AI): from gameEngine.gameEngine import updateGUI updateGUI.refreshUnitsAndConstructions(self) ''' give total control to new player ''' self.player = player ''' if human player is the new owner ''' if(type(player) != AI): from gameEngine.gameEngine import updateGUI updateGUI.refreshUnitsAndConstructions(self) def addOrbitingUnit(self, unit): ''' Add a unit to the hosted units by the planet @param unit: Orbiting unit object ''' self._orbiting_units.append(unit) def addOrbitingUnits(self, units): ''' Add a list of units to be hosted by the planet @param units: iterable of units ''' self._orbiting_units.extend(units) def removeOrbitingUnit(self, unit): ''' Remove the hosted unit from the planet @param unit: Orbiting unit object ''' self._orbiting_units.remove(unit) def removeOrbitingUnits(self, units): ''' Remove many hosted units from the planet @param units: List of unit objects ''' self._orbiting_units[:] = [u for u in self._orbiting_units if u not in units] def units(self): ''' Generator that iterates over the hosted units. ''' for unit in self._orbiting_units: yield unit def unitsOfPlayer(self, player): ''' Generator that iterates over the hosted units belonging to the player. @param player, the owner of the units ''' for unit in self._orbiting_units: if unit.player == player: yield unit def unitsOfEnemy(self, player): ''' Generator that iterates over the hosted units not belonging to the player. @param player, the owner of the units ''' for unit in self._orbiting_units: if unit.player != player: yield unit def unitsOfEnemyLowestEnergy(self, player): ''' Generator that iterates over the hosted units not belonging to the player sorted by lowest energy. @param player, the owner of the units ''' energyList = sorted(self._orbiting_units, key=lambda unit: unit.energy) for unit in energyList: if unit.player != player: yield unit def getNumberOfUnits(self): ''' Returns the number of hosted units from the planet ''' return len(self._orbiting_units) def getNumberOfUnitsOfPlayer(self, player): ''' Returns the number of hosted units from the planet that belongs to the player @param player, the owner of the units ''' num = 0 for unit in self._orbiting_units: if(unit.player == player): num = num + 1 return num def _task_unit_timers(self): ''' Generator that iterates over the hosted units construction tasks. ''' for task_unit in self.task_unit_timers: yield task_unit def _task_structure_timers(self): ''' Generator that iterates over the surface structure construction tasks. ''' for task_structure in self.task_structure_timers: yield task_structure def _consumeUnits(self): if(self.task_unit_timer!=None): taskMgr.remove(self.task_unit_timer) self.task_unit_timer = None for task in self.task_unit_timers: taskMgr.remove(task) del self.task_unit_timers[:] from gameModel.ai import AI for unit in self._orbiting_units: unit.player.units.remove(unit) if(type(unit.player) != AI): try: unit.player.selected_units.remove(unit) print "selected unit" except ValueError: pass unit.removeFromGame() del self._orbiting_units[:] def _consumeStructures(self): if(self.task_structure_timer!=None): taskMgr.remove(self.task_structure_timer) self.task_structure_timer = None for task in self.task_structure_timers: taskMgr.remove(task) del self.task_structure_timers[:] for structure in self._surface_structures: self.player.structures.remove(structure) del self._surface_structures[:] def addSurfaceStructure(self, structure): ''' Add a structure to the surface structures by the planet @param structure: Surface structure object ''' if(len(self._surface_structures) < MAX_NUMBER_OF_STRUCTURE): self._surface_structures.append(structure) def addSurfaceStructures(self, structures): ''' Add a list of structures to be hosted by the planet @param structures: iterable of structure ''' if(len(self._surface_structures) + len(structures) <= MAX_NUMBER_OF_STRUCTURE): self._surface_structures.extend(structures) def removeSurfaceStructure(self, structure): ''' Remove the surface structure from the planet @param structure: Surface structure object ''' self._surface_structures.remove(structure) def removeSurfaceStructures(self, structures): ''' Remove many surface structures from the planet @param structures: List of structure objects ''' self._surface_structures[:] = [s for s in self._surface_structures if s not in structures] def structures(self): ''' Generator that iterates over the surface structures. ''' for structure in self._surface_structures: yield structure def getNumberOfStructures(self): ''' Returns the number of surface structures from the planet ''' return len(self._surface_structures) def hasStructure(self, structure): ''' Returns true if a type of the structure already exists on the planet @structure: String, the desired structure type ''' from structures import Forge, Nexus, Extractor, Phylon, GeneratorCore,\ PlanetaryDefenseI, PlanetaryDefenseII, PlanetaryDefenseIII, PlanetaryDefenseIV for surface_structure in self._surface_structures: if(structure == "forge" and type(surface_structure) == Forge): return True elif(structure == "nexus" and type(surface_structure) == Nexus): return True elif(structure == "extractor" and type(surface_structure) == Extractor): return True elif(structure == "phylon" and type(surface_structure) == Phylon): return True elif(structure == "generatorCore" and type(surface_structure) == GeneratorCore): return True elif(structure == "pd1" and type(surface_structure) == PlanetaryDefenseI): return True elif(structure == "pd2" and type(surface_structure) == PlanetaryDefenseII): return True elif(structure == "pd3" and type(surface_structure) == PlanetaryDefenseIII): return True elif(structure == "pd4" and type(surface_structure) == PlanetaryDefenseIV): return True return False def removeFromGame(self): if(self.next_planet != None): self.next_planet.prev_planet = None self.point_path.removeNode() from player import Player if type(self.player) == Player and self.player.selected_planet == self: self.player.selected_planet = None if(self.player != None): self.player.planets.remove(self) self.parent_star.removePlanet(self)