def __init__(self,manager,xml): self.surface = getWaterSurface(manager) self.surface.reparentTo(render) self.surface.hide(BitMask32.bit(1)) # Invisible to reflection camera (speedup) self.surface.hide(BitMask32.bit(2)) # Invisible to volumetric lighting camera (speedup) self.surface.hide(BitMask32.bit(3)) # Invisible to shadow cameras (speedup) self.surface.setShader(loader.loadShader(manager.get('paths').getConfig().find('shaders').get('path')+'/water.cg')) self.surface.setShaderInput('time', 0.0, 0.0, 0.0, 0.0) ntex = loader.loadTexture(manager.get('paths').getConfig().find('textures').get('path')+'/water-normal.png') ntex.setMinfilter(Texture.FTLinearMipmapLinear) self.surface.setShaderInput('normal', ntex) self.surface.setShaderInput('camera', base.cam) self.surface.setTransparency(TransparencyAttrib.MDual, 10) self.surface.setTwoSided(True) self.surface.setShaderInput('waveInfo', Vec4(0.4, 0.4, 0.4, 0)) self.surface.setShaderInput('param2', Vec4(-0.015,0.005, 0.05, 0.05)) self.surface.setShaderInput('param3', Vec4(0.7, 0.3, 0, 0)) self.surface.setShaderInput('param4', Vec4(2.0, 0.5, 0.5, 0.0)) #self.surface.setShaderInput('speed', Vec4(-.8, -.4, -.9, .3)) self.surface.setShaderInput('speed', Vec4(0.2, -1.2, -0.2, -0.7)) self.surface.setShaderInput('deepcolor', Vec4(0.0,0.3,0.5,1.0)) self.surface.setShaderInput('shallowcolor', Vec4(0.0,1.0,1.0,1.0)) self.surface.setShaderInput('reflectioncolor', Vec4(0.95,1.0,1.0,1.0)) self.surface.hide() self.wbuffer = base.win.makeTextureBuffer('water', 512, 512) self.wbuffer.setClearColorActive(True) self.wbuffer.setClearColor(base.win.getClearColor()) self.wcamera = base.makeCamera(self.wbuffer) if manager.get('sky') != None and manager.get('sky').model != None: self.sky = manager.get('sky').model.copyTo(self.wcamera) self.sky.setTwoSided(True) self.sky.setSz(self.sky, -1) self.sky.setClipPlaneOff(1) self.sky.show() self.sky.hide(BitMask32.bit(0)) # Hide for normal camera self.sky.hide(BitMask32.bit(2)) # Hide for volumetric lighting camera self.sky.hide(BitMask32.bit(3)) # Hide for shadow camera(s), if any else: self.sky = None self.wcamera.reparentTo(render) self.wcamera.node().setLens(base.camLens) self.wcamera.node().setCameraMask(BitMask32.bit(1)) self.surface.hide(BitMask32.bit(1)) wtexture = self.wbuffer.getTexture() wtexture.setWrapU(Texture.WMClamp) wtexture.setWrapV(Texture.WMClamp) wtexture.setMinfilter(Texture.FTLinearMipmapLinear) self.surface.setShaderInput('reflection', wtexture) self.wplane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) self.wplanenp = render.attachNewNode(PlaneNode('water', self.wplane)) tmpnp = NodePath('StateInitializer') tmpnp.setClipPlane(self.wplanenp) tmpnp.setAttrib(CullFaceAttrib.makeReverse()) self.wcamera.node().setInitialState(tmpnp.getState()) #self.fog = Fog('UnderwaterFog') #self.fog.setColor(0.0,0.3,0.5) self.fogEnabled = False
def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None): if textures: colortex = textures.get('color', None) depthtex = textures.get('depth', None) auxtex = textures.get('aux', None) if colortex == None: colortex = Texture('filter-base-color') colortex.setWrapU(Texture.WMClamp) colortex.setWrapV(Texture.WMClamp) texgroup = (depthtex, colortex, auxtex, None) (winx, winy) = self.getScaledSize(1, 1, 1) buffer = self.createBuffer('filter-base', winx, winy, texgroup) if buffer == None: return None cm = CardMaker('filter-base-quad') cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setTexture(colortex) quad.setColor(Vec4(1, 0.5, 0.5, 1)) cs = NodePath('dummy') cs.setState(self.camstate) if auxbits: cs.setAttrib(AuxBitplaneAttrib.make(auxbits)) self.camera.node().setInitialState(cs.getState()) quadcamnode = Camera('filter-quad-cam') lens = OrthographicLens() lens.setFilmSize(2, 2) lens.setFilmOffset(0, 0) lens.setNearFar(-1000, 1000) quadcamnode.setLens(lens) quadcam = quad.attachNewNode(quadcamnode) self.region.setCamera(quadcam) dr = buffer.getDisplayRegion(0) self.setStackedClears(dr, self.rclears, self.wclears) if auxtex: dr.setClearActive(GraphicsOutput.RTPAuxRgba0, 1) dr.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5, 0.5, 1.0, 0.0)) self.region.disableClears() if self.isFullscreen(): self.win.disableClears() dr.setCamera(self.camera) dr.setActive(1) self.buffers.append(buffer) self.sizes.append((1, 1, 1)) return quad
class LightBase(object): """ LightBase is a lightweight interface for rendering with Panda3d. It contains several key Panda3d objects that are required for rendering, like GraphicsEngine, GraphicsPipe, GraphicsOutput, a root NodePath (rootnode), cameras and lights. It provides also methods for manipulating and reading them out them.""" def __init__(self): self.init_graphics() self.setup_rootnode() self.output_list = [] self.gsg_list = [] self.cameras = None def init_graphics(self): """ Creates GraphicsEngine, GraphicsPipe, and loader """ # Get a handle to the graphics pipe selector selection = GraphicsPipeSelection.getGlobalPtr() # Check for DISPLAY if "DISPLAY" in os.environ: # Use the first option (should be glx) pipe_type = selection.getPipeTypes()[0] else: # Use the last option (should be some fallback module) pipe_type = selection.getPipeTypes()[-1] # Create the graphics pipe self.pipe = selection.makePipe(pipe_type) # Get the graphics engine self.engine = GraphicsEngine.getGlobalPtr() # Get the model loader object and assign it to the engine self.loader = Loader.Loader(self) self.engine.setDefaultLoader(self.loader.loader) @staticmethod def init_fbp(): """ Initial / default FrameBufferProperties """ fbp = FrameBufferProperties() fbp.setRgbColor(1) fbp.setColorBits(1) fbp.setAlphaBits(1) fbp.setDepthBits(1) return fbp @staticmethod def init_wp(window_type, size): """ Initial / default WindowProperties """ if window_type == 'onscreen': wp = WindowProperties.getDefault() wp.setSize(size[0], size[1]) elif window_type == 'offscreen': wp = WindowProperties.size(size[0], size[1]) return wp def make_window(self, size=None, name=None, sort=0, xflags=0, host_out=None): """ Create an onscreen window -- high-level interface for makeOutput""" # Handle size if size is None and host_out is not None: size = (host_out.getFbXSize(), host_out.getFbYSize()) elif size is None: raise ValueError("Size not available.") # Initialize WindowProperties wp = self.init_wp('onscreen', size) # Create window output = self.make_output('onscreen', name, sort, wp=wp, xflags=xflags, host_out=host_out) # Handle failure to create window (returns None) if output is None: raise StandardError("Window creation failed, not sure why.") return output def make_buffer(self, size=None, name=None, sort=0, xflags=0, host_out=None): """ Makes an offscreen buffer -- high-level interface for make_output""" # Handle size if size is None and host_out is not None: size = (host_out.getFbXSize(), host_out.getFbYSize()) elif size is None: raise ValueError("Size not available.") # Initialize WindowProperties wp = self.init_wp('offscreen', size) # Create the buffer output = self.make_output('offscreen', name, sort, wp=wp, xflags=xflags, host_out=host_out) # Handle case when offscreen buffer cannot be directly created # (currently this is what happens) if output is None: print("Direct offscreen buffer creation failed...") print("... falling back to onscreen --> offscreen method.") # Open an onscreen window first, just to get a GraphicsOutput # object which is needed to open an offscreen buffer. dummywin = self.make_window(size, 'dummy_onscreen_win', sort, xflags, host_out) # Now, make offscreen buffer through win output = self.make_output('offscreen', name, sort, xflags=xflags, host_out=dummywin) # Handle failure to create window (returns None) if output is None: raise StandardError("Failed to create offscreen buffer.") return output def make_texture_buffer(self, size=None, name=None, sort=0, xflags=0, mode=None, bitplane=None, host_out=None): """ Makes an offscreen buffer and adds a render texture """ # Make the offscreen buffer output = self.make_buffer(size, name, sort, xflags, host_out) # Add the texture tex = self.add_render_texture(output, mode, bitplane) # Cause necessary stuff to be created (buffers, textures etc) self.render_frame() return output, tex def make_output(self, window_type, name=None, sort=0, fbp=None, wp=None, xflags=0, host_out=None): """ Makes a GraphicsOutput object and stores it in self.output_list. This is the low-level interface.""" # Input handling / defaults if name is None: name = window_type + '_win' if fbp is None: # Initialize FramebufferProperties fbp = self.init_fbp() if wp is None and host_out is not None: # Initialize WindowProperties wp = self.init_wp(window_type, (host_out.getFbXSize(), host_out.getFbYSize())) elif wp is None: raise ValueError("Size not available in either wp or win.") flags = xflags | GraphicsPipe.BFFbPropsOptional # flags' window_type switch if window_type == 'onscreen': flags = flags | GraphicsPipe.BFRequireWindow elif window_type == 'offscreen': flags = flags | GraphicsPipe.BFRefuseWindow # Make the window / buffer engine = self.engine pipe = self.pipe if host_out is None: output = engine.makeOutput(pipe, name, sort, fbp, wp, flags) else: output = engine.makeOutput(pipe, name, sort, fbp, wp, flags, host_out.getGsg(), host_out) # Add output to this instance's list if output is not None: self.add_to_output_gsg_lists(output) # Set background color to black by default output.setClearColor((0.0, 0.0, 0.0, 0.0)) # Cause necessary stuff to be created (buffers, textures etc) self.render_frame() return output def add_to_output_gsg_lists(self, output): """ Adds the output and Gsg to the instance's running list. """ self.output_list.append(output) self.gsg_list.append(output.getGsg()) def remove_from_output_gsg_lists(self, output): """ Removes the output and Gsg from the instance's running list. """ self.output_list.remove(output) self.gsg_list.remove(output.getGsg()) @staticmethod def add_render_texture(output, mode=None, bitplane=None): """ Similar to GraphicsOutput's addRenderTexture. ** Possible mode values ** GraphicsOutput.RTMNone GraphicsOutput.RTMBindOrCopy GraphicsOutput.RTMCopyTexture GraphicsOutput.RTMCopyRam GraphicsOutput.RTMTriggeredCopyTexture GraphicsOutput.RTMTriggeredCopyRam ** Possible bitplane values ** GraphicsOutput.RTPStencil GraphicsOutput.RTPDepthStencil GraphicsOutput.RTPColor GraphicsOutput.RTPAuxRgba0 GraphicsOutput.RTPAuxRgba1 GraphicsOutput.RTPAuxRgba2 GraphicsOutput.RTPAuxRgba3 GraphicsOutput.RTPAuxHrgba0 GraphicsOutput.RTPAuxHrgba1 GraphicsOutput.RTPAuxHrgba2 GraphicsOutput.RTPAuxHrgba3 GraphicsOutput.RTPAuxFloat0 GraphicsOutput.RTPAuxFloat1 GraphicsOutput.RTPAuxFloat2 GraphicsOutput.RTPAuxFloat3 GraphicsOutput.RTPDepth GraphicsOutput.RTPCOUNT """ if mode is None: mode = GraphicsOutput.RTMBindOrCopy elif isinstance(mode, str): mode = getattr(GraphicsOutput, mode) if bitplane is None: bitplane = GraphicsOutput.RTPColor elif isinstance(bitplane, str): bitplane = getattr(GraphicsOutput, bitplane) tex = Texture() tex.setFormat(Texture.FLuminance) # Add the texture to the buffer output.addRenderTexture(tex, mode, bitplane) # Get a handle to the texture assert tex == output.getTexture(), "Texture wasn't created properly." return tex def close_output(self, output): """ Closes the indicated output and removes it from the list. """ output.setActive(False) # First, remove all of the cameras associated with display # regions on the window. num_regions = output.getNumDisplayRegions() for i in range(num_regions): dr = output.getDisplayRegion(i) dr.setCamera(NodePath()) # Remove this output from the list self.remove_from_output_gsg_lists(output) # Now we can actually close the window. engine = output.getEngine() engine.removeWindow(output) # Give the window a chance to actually close before continuing. engine.renderFrame() def close_all_outputs(self): """ Closes all of this instance's outputs """ # Close them each for output in self.output_list: self.close_output(output) # Clear the output list self.output_list = [] def make_camera(self, output, sort=0, dr_dims=(0, 1, 0, 1), aspect_ratio=None, clear_depth=False, clear_color=None, lens=None, cam_name='camera0', mask=None): """ Makes a new 3-d camera associated with the indicated window, and creates a display region in the indicated subrectangle. If stereo is True, then a stereo camera is created, with a pair of DisplayRegions. If stereo is False, then a standard camera is created. If stereo is None or omitted, a stereo camera is created if the window says it can render in stereo. If useCamera is not None, it is a NodePath to be used as the camera to apply to the window, rather than creating a new camera. """ # self.cameras is the parent node of all cameras: a node that # we can move around to move all cameras as a group. if self.cameras is None: # We make it a ModelNode with the PTLocal flag, so that a # wayward flatten operations won't attempt to mangle the # camera. self.cameras = self.rootnode.attachNewNode(ModelNode('cameras')) self.cameras.node().setPreserveTransform(ModelNode.PTLocal) # Make a new Camera node. cam_node = Camera(cam_name) if lens is None: lens = PerspectiveLens() if aspect_ratio is None: aspect_ratio = self.get_aspect_ratio(output) lens.setAspectRatio(aspect_ratio) lens.setNear(0.1) lens.setFar(1000.0) if lens is not None: cam_node.setLens(lens) camera = self.cameras.attachNewNode(cam_node) # Masks out part of scene from camera if mask is not None: if (isinstance(mask, int)): mask = BitMask32(mask) cam_node.setCameraMask(mask) # Make a display region dr = output.makeDisplayRegion(*dr_dims) # By default, we do not clear 3-d display regions (the entire # window will be cleared, which is normally sufficient). But # we will if clearDepth is specified. if clear_depth: dr.setClearDepthActive(1) if clear_color: dr.setClearColorActive(1) dr.setClearColor(clear_color) dr.setSort(sort) dr.setCamera(camera) dr.setActive(True) return camera @staticmethod def get_aspect_ratio(output): """ Returns the actual aspect ratio of the indicated (or main window), or the default aspect ratio if there is not yet a main window.""" aspect_ratio = 1 if output.hasSize(): aspect_ratio = float(output.getSbsLeftXSize()) / \ float(output.getSbsLeftYSize()) else: wp = output.getRequestedProperties() if not wp.hasSize(): wp = WindowProperties.getDefault() aspect_ratio = float(wp.getXSize()) / float(wp.getYSize()) return aspect_ratio @staticmethod def make_lights(light_spec=None, lname=None): """ Create one point light and an ambient light.""" if lname is None: lname = 'lights' lights = NodePath(lname) if light_spec is None: # Create point lights plight = PointLight('plight1') light = lights.attachNewNode(plight) plight.setColor((0.1, 0.1, 0.1, 1.0)) light.setPos((-2, -6, 4)) light.lookAt(0, 0, 0) # Create ambient light alight = AmbientLight('alight') alight.setColor((1, 1, 1, 1.0)) lights.attachNewNode(alight) else: for lspec in light_spec: light_type = lspec['type'] light_name = lspec['name'] assert light_type in ['AmbientLight', 'PointLight', 'DirectionalLight', 'SpotLight'], light_type if light_type == 'AmbientLight': light = AmbientLight(light_name) light.setColor(lspec['color']) lights.attachNewNode(light) elif light_type == 'PointLight': light = PointLight(light_name) lights.attachNewNode(light) light.setColor(lspec['color']) light.setPoint(lspec['pos']) elif light_type == 'DirectionalLight': light = DirectionalLight(light_name) lights.attachNewNode(light) light.setColor(lspec['color']) light.setPoint(lspec['pos']) light.setDirection(lspec['direction']) return lights def setup_rootnode(self): """ Creates the rootnode scene graph, the primary scene graph for rendering 3-d geometry. """ self.rootnode = NodePath('rootnode') self.rootnode.setAttrib(RescaleNormalAttrib.makeDefault()) self.rootnode.setTwoSided(0) self.backface_culling_enabled = 0 self.texture_enabled = 1 self.wireframe_enabled = 0 def wireframe_on(self): """ Toggle wireframe mode on.""" self.rootnode.setRenderModeWireframe(100) self.rootnode.setTwoSided(1) self.wireframe_enabled = 1 def wireframe_off(self): """ Toggle wireframe mode off.""" self.rootnode.clearRenderMode() self.rootnode.setTwoSided(not self.backface_culling_enabled) self.wireframe_enabled = 0 @staticmethod def trigger_copy(output): """ This signals the texture to be pushed to RAM after the next renderFrame""" output.trigger_copy() def render_frame(self): """ Render the frame.""" #self.engine.readyFlip() self.engine.renderFrame() # If you're trying to read the texture buffer, remember to # call self.triggerCopy() @staticmethod def get_tex_image(tex, freshape=True): """ Returns numpy arr containing image in tex """ # Remember to call self.triggerCopy() before # self.renderFrame(), or the next frame won't be pushed to RAM if not tex.hasRamImage(): arr = None else: size = (tex.getXSize(), tex.getYSize()) texdata = tex.getRamImage().getData() arr = np.fromstring(texdata, 'u1') if freshape: arr = np.reshape(arr, list(size) + [-1])[:, :, [2, 1, 0, 3]] return arr @staticmethod def screenshot(output, pth=None): """ Similar to ShowBase's screenshot """ if pth is None: filename = GraphicsOutput.makeScreenshotFilename() else: filename = Filename(pth) if isinstance(output, GraphicsOutput): f_success = output.saveScreenshot(filename) elif isinstance(output, Texture): if output.getZSize() > 1: f_success = output.write(filename, 0, 0, 1, 0) else: f_success = output.write(filename) else: raise TypeError('Unhandled output type: ' + type(output)) return f_success def destroy(self): """ self.__exitfunc() calls this automatically """ self.close_all_outputs() if getattr(self, 'loader', None): self.loader.destroy() self.loader = None if getattr(self, 'engine', None): self.engine.removeAllWindows() self.engine = None if getattr(self, 'pipe', None): self.pipe = None def __exitfunc(self): """ Customize pre-exit commands.""" self.destroy() def user_exit(self): """ The user has requested we exit the program. """ self.__exitfunc() sys.exit() @classmethod def destroy_windows(cls): """ General destroy windows method.""" GraphicsEngine.getGlobalPtr().removeAllWindows()
def __init__(self, manager, xml): self.surface = getWaterSurface(manager) self.surface.reparentTo(render) self.surface.hide(BitMask32.bit(1)) # Invisible to reflection camera (speedup) self.surface.hide(BitMask32.bit(2)) # Invisible to volumetric lighting camera (speedup) self.surface.hide(BitMask32.bit(3)) # Invisible to shadow cameras (speedup) self.surface.setShader( loader.loadShader(manager.get("paths").getConfig().find("shaders").get("path") + "/water.cg") ) self.surface.setShaderInput("time", 0.0, 0.0, 0.0, 0.0) ntex = loader.loadTexture(manager.get("paths").getConfig().find("textures").get("path") + "/water-normal.png") ntex.setMinfilter(Texture.FTLinearMipmapLinear) self.surface.setShaderInput("normal", ntex) self.surface.setShaderInput("camera", base.cam) self.surface.setTransparency(TransparencyAttrib.MDual, 10) self.surface.setTwoSided(True) self.surface.setShaderInput("waveInfo", Vec4(0.4, 0.4, 0.4, 0)) self.surface.setShaderInput("param2", Vec4(-0.015, 0.005, 0.05, 0.05)) self.surface.setShaderInput("param3", Vec4(0.7, 0.3, 0, 0)) self.surface.setShaderInput("param4", Vec4(2.0, 0.5, 0.5, 0.0)) # self.surface.setShaderInput('speed', Vec4(-.8, -.4, -.9, .3)) self.surface.setShaderInput("speed", Vec4(0.2, -1.2, -0.2, -0.7)) self.surface.setShaderInput("deepcolor", Vec4(0.0, 0.3, 0.5, 1.0)) self.surface.setShaderInput("shallowcolor", Vec4(0.0, 1.0, 1.0, 1.0)) self.surface.setShaderInput("reflectioncolor", Vec4(0.95, 1.0, 1.0, 1.0)) self.surface.hide() self.wbuffer = base.win.makeTextureBuffer("water", 512, 512) self.wbuffer.setClearColorActive(True) self.wbuffer.setClearColor(base.win.getClearColor()) self.wcamera = base.makeCamera(self.wbuffer) if manager.get("sky") != None and manager.get("sky").model != None: self.sky = manager.get("sky").model.copyTo(self.wcamera) self.sky.setTwoSided(True) self.sky.setSz(self.sky, -1) self.sky.setClipPlaneOff(1) self.sky.show() self.sky.hide(BitMask32.bit(0)) # Hide for normal camera self.sky.hide(BitMask32.bit(2)) # Hide for volumetric lighting camera self.sky.hide(BitMask32.bit(3)) # Hide for shadow camera(s), if any else: self.sky = None self.wcamera.reparentTo(render) self.wcamera.node().setLens(base.camLens) self.wcamera.node().setCameraMask(BitMask32.bit(1)) self.surface.hide(BitMask32.bit(1)) wtexture = self.wbuffer.getTexture() wtexture.setWrapU(Texture.WMClamp) wtexture.setWrapV(Texture.WMClamp) wtexture.setMinfilter(Texture.FTLinearMipmapLinear) self.surface.setShaderInput("reflection", wtexture) self.wplane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) self.wplanenp = render.attachNewNode(PlaneNode("water", self.wplane)) tmpnp = NodePath("StateInitializer") tmpnp.setClipPlane(self.wplanenp) tmpnp.setAttrib(CullFaceAttrib.makeReverse()) self.wcamera.node().setInitialState(tmpnp.getState()) # self.fog = Fog('UnderwaterFog') # self.fog.setColor(0.0,0.3,0.5) self.fogEnabled = False
class FishManager: notify = DirectNotifyGlobal.directNotify.newCategory("FishManager") def __init__(self, gameObject=None): base.loadingScreen.beginStep("FishManager", 2, 20) self.gameObject = gameObject if self.gameObject.distributedFishingSpot.onABoat: self.location = "ship" else: self.location = "dock" self.uncaughtFish = [] self.caughtFish = 0 self.deadFish = [] self.activeFish = None self.specialFishIndex = 0 self.fishHistogram = {} for fish in FishingGlobals.allFishData: self.fishHistogram[fish["id"]] = [0, fish["maxPossiblePerScene"]] self.hiddenFish = [] self.legendaryFishPool = [] self.hideNormalFishSequence = Sequence() self.objectsWithCaustics = NodePath("objectsWithCaustics") self.objectsWithCaustics.reparentTo(self.gameObject.fishingSpot) self.causticsTexture = loader.loadTexture("maps/pir_t_gam_fsh_caustics.jpg") self.causticsShader = loader.loadShader("models/shaders/fishingCausticsShader.sha") if base.win and base.win.getGsg(): intShaders = base.win.getGsg().getSupportsBasicShaders() else: intShaders = 0 if intShaders > 0: self.doShaders() else: self.doFixedFunction() if base.win and base.win.getGsg(): shaderModel = base.win.getGsg().getShaderModel() base.loadingScreen.tick() self.loadFish() base.loadingScreen.endStep("FishManager") def loadFish(self): rodSize = self.gameObject.getAvatarsBestRod() for depth in range(len(FishingGlobals.fishCountRangePerRodPerLevel[rodSize])): numberOfFishForThisLevel = random.randint( FishingGlobals.fishCountRangePerRodPerLevel[rodSize][depth][0], FishingGlobals.fishCountRangePerRodPerLevel[rodSize][depth][1], ) for fishIndex in range(numberOfFishForThisLevel): fishData = FishingGlobals.giveMeAFish(self.location, depth, self.fishHistogram) f = Fish(self, fishData, len(self.uncaughtFish)) self.fishHistogram[f.myData["id"]][0] += 1 f.fsm.request("Offscreen") self.uncaughtFish.append(f) self.legendaryFish = None def doShaders(self): self.objectsWithCaustics.setShader(self.causticsShader) self.objectsWithCaustics.setShaderInput("caustics", self.causticsTexture) self.objectsWithCaustics.setShaderInput( "causticsParams", Vec4(5.3300000000000001, 0.0234325112498, 0.010589092533, 0.20000000000000001) ) self.objectsWithCaustics.setShaderInput( "causticsParams2", Vec4(2.8795310000000001, -0.035686130000000003, 0.027589099999999998, 0.20000000000000001), ) self.objectsWithCaustics.setShaderInput( "causticsParams3", Vec4(3.7854611, 0.037037029999999999, 0.047619047619047616, 0.20000000000000001) ) self.objectsWithCaustics.setShaderInput( "fogInfo", Vec4(0.0, FishingGlobals.fogDarkness, 0.69999999999999996, 0.0) ) self.objectsWithCaustics.setShaderInput("fogColor", FishingGlobals.waterFogColor) self.objectsWithCaustics.setShaderInput( "causticsToWorldScale", Vec4(1.0 / 30.100000000000001, 1.0 / 30.100000000000001, 0.0, 0.0) ) self.objectsWithCaustics.setShaderInput("sunWorldLocation", Vec4(0.0, 0.0, 100.0, 1.0)) def doFixedFunction(self): fishFog = Fog("fishFogNode") fishFog.setMode(Fog.MLinear) fishFog.setColor(FishingGlobals.waterFogColor) fishFog.setLinearRange(0.0, 200.0) fishFogAttrib = FogAttrib.make(fishFog) self.objectsWithCaustics.setAttrib(fishFogAttrib) def codeReload(self): for fish in self.uncaughtFish: print fish.codeReload() def scareAwayNormalFish(self): for fish in self.uncaughtFish: if fish.fsm.getCurrentOrNextState() != "ScareAway": if fish.movingRight and fish.fsm.getCurrentOrNextState() != "TurnAround": fish.fsm.request("TurnAround", "ScareAway", False) else: fish.fsm.request("ScareAway") fish.fsm.getCurrentOrNextState() != "TurnAround" def startLegendaryFish(self, whichFish=None): self.notify.debug("start LegendaryFish %s" % str(whichFish)) fishData = FishingGlobals.getALegendaryFish(whichFish) self.legendaryFish = LegendaryFish(self, fishData, 0) self.activeFish = self.legendaryFish self.legendaryFish.fsm.request("AboutToBiteLure") def replaceFish(self, fish): depth = fish.myData["depth"] index = fish.index self.fishHistogram[fish.myData["id"]][0] -= 1 self.uncaughtFish.remove(fish) fish.destroy() fishData = FishingGlobals.giveMeAFish(self.location, depth, self.fishHistogram) f = Fish(self, fishData, index) f.fsm.request("Offscreen") self.fishHistogram[f.myData["id"]][0] += 1 f.pickPositionAndSwim() self.uncaughtFish.append(f) def destroy(self): for fish in self.uncaughtFish: fish.destroy() self.uncaughtFish = [] if self.legendaryFish: self.legendaryFish.destroy() self.legendaryFish = None def moveFish(self, direction): self.shutdown() self.specialFishIndex += direction self.specialFishIndex = max(min(len(FishingGlobals.allFishData) - 1, self.specialFishIndex), 0) self.startup() def startup(self): for fish in self.uncaughtFish: fish.pickPositionAndSwim() def shutdown(self): self.activeFish = None self.caughtFish = 0 self.deadFish = [] for fish in self.uncaughtFish: if fish.fsm.getCurrentOrNextState() != "Offscreen": fish.fsm.request("Offscreen") continue def reset(self): if self.activeFish and self.activeFish.fsm and self.activeFish.fsm.getCurrentOrNextState() != "Offscreen": self.activeFish.fsm.request("Offscreen") self.activeFish = None self.deadFish = [] self.loseInterest() def update(self, dt): lurePos = self.gameObject.lure.getPos() for i in range(len(self.uncaughtFish)): self.uncaughtFish[i].update(dt, i, lurePos) for fish in self.deadFish: self.uncaughtFish.remove(fish) fish.destroy() self.deadFish = [] def turnAllFish(self): for fish in self.uncaughtFish: if fish.fsm.getCurrentOrNextState() != "TurnAround": fish.fsm.request("TurnAround", "Swimming", not (fish.movingRight)) continue def enterReeling(self): pass def reloadCollisions(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: for fishData in FishingGlobals.allFishData: if fish.myData["model"] == fishData["model"]: fish.myData = fishData fish.reloadCollisions() continue continue def loseInterest(self): for fish in self.uncaughtFish: if fish.fsm.getCurrentOrNextState() == "Biting": fish.fsm.request("Swimming") continue def showAvoidanceCollisionVisuals(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: fish.showAvoidanceCollisionVisuals() def hideAvoidanceCollisionVisuals(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: fish.hideAvoidanceCollisionVisuals() def showAttractionCollisionVisuals(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: fish.showAttractionCollisionVisuals() def hideAttractionCollisionVisuals(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: fish.hideAttractionCollisionVisuals()
def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None): """ Causes the scene to be rendered into the supplied textures instead of into the original window. Puts a fullscreen quad into the original window to show the render-to-texture results. Returns the quad. Normally, the caller would then apply a shader to the quad. To elaborate on how this all works: * An offscreen buffer is created. It is set up to mimic the original display region - it is the same size, uses the same clear colors, and contains a DisplayRegion that uses the original camera. * A fullscreen quad and an orthographic camera to render that quad are both created. The original camera is removed from the original window, and in its place, the orthographic quad-camera is installed. * The fullscreen quad is textured with the data from the offscreen buffer. A shader is applied that tints the results pink. * Automatic shader generation NOT enabled. If you have a filter that depends on a render target from the auto-shader, you either need to set an auto-shader attrib on the main camera or scene, or, you need to provide these outputs in your own shader. * All clears are disabled on the original display region. If the display region fills the whole window, then clears are disabled on the original window as well. It is assumed that rendering the full-screen quad eliminates the need to do clears. Hence, the original window which used to contain the actual scene, now contains a pink-tinted quad with a texture of the scene. It is assumed that the user will replace the shader on the quad with a more interesting filter. """ if (textures): colortex = textures.get("color", None) depthtex = textures.get("depth", None) auxtex = textures.get("aux", None) if (colortex == None): colortex = Texture("filter-base-color") colortex.setWrapU(Texture.WMClamp) colortex.setWrapV(Texture.WMClamp) texgroup = (depthtex, colortex, auxtex, None) # Choose the size of the offscreen buffer. (winx, winy) = self.getScaledSize(1,1,1) buffer = self.createBuffer("filter-base", winx, winy, texgroup) if (buffer == None): return None cm = CardMaker("filter-base-quad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setTexture(colortex) quad.setColor(Vec4(1,0.5,0.5,1)) cs = NodePath("dummy") cs.setState(self.camstate) # Do we really need to turn on the Shader Generator? #cs.setShaderAuto() if (auxbits): cs.setAttrib(AuxBitplaneAttrib.make(auxbits)) self.camera.node().setInitialState(cs.getState()) quadcamnode = Camera("filter-quad-cam") lens = OrthographicLens() lens.setFilmSize(2, 2) lens.setFilmOffset(0, 0) lens.setNearFar(-1000, 1000) quadcamnode.setLens(lens) quadcam = quad.attachNewNode(quadcamnode) self.region.setCamera(quadcam) dr = buffer.getDisplayRegion(0) self.setStackedClears(dr, self.rclears, self.wclears) if (auxtex): dr.setClearActive(GraphicsOutput.RTPAuxRgba0, 1) dr.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5,0.5,1.0,0.0)) self.region.disableClears() if (self.isFullscreen()): self.win.disableClears() dr.setCamera(self.camera) dr.setActive(1) self.buffers.append(buffer) self.sizes.append((1, 1, 1)) return quad
def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None): """ Causes the scene to be rendered into the supplied textures instead of into the original window. Puts a fullscreen quad into the original window to show the render-to-texture results. Returns the quad. Normally, the caller would then apply a shader to the quad. To elaborate on how this all works: * An offscreen buffer is created. It is set up to mimic the original display region - it is the same size, uses the same clear colors, and contains a DisplayRegion that uses the original camera. * A fullscreen quad and an orthographic camera to render that quad are both created. The original camera is removed from the original window, and in its place, the orthographic quad-camera is installed. * The fullscreen quad is textured with the data from the offscreen buffer. A shader is applied that tints the results pink. * Automatic shader generation NOT enabled. If you have a filter that depends on a render target from the auto-shader, you either need to set an auto-shader attrib on the main camera or scene, or, you need to provide these outputs in your own shader. * All clears are disabled on the original display region. If the display region fills the whole window, then clears are disabled on the original window as well. It is assumed that rendering the full-screen quad eliminates the need to do clears. Hence, the original window which used to contain the actual scene, now contains a pink-tinted quad with a texture of the scene. It is assumed that the user will replace the shader on the quad with a more interesting filter. """ if (textures): colortex = textures.get("color", None) depthtex = textures.get("depth", None) auxtex = textures.get("aux", None) auxtex0 = textures.get("aux0", auxtex) auxtex1 = textures.get("aux1", None) else: auxtex0 = auxtex auxtex1 = None if (colortex == None): colortex = Texture("filter-base-color") colortex.setWrapU(Texture.WMClamp) colortex.setWrapV(Texture.WMClamp) texgroup = (depthtex, colortex, auxtex0, auxtex1) # Choose the size of the offscreen buffer. (winx, winy) = self.getScaledSize(1,1,1) buffer = self.createBuffer("filter-base", winx, winy, texgroup) if (buffer == None): return None cm = CardMaker("filter-base-quad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setTexture(colortex) quad.setColor(Vec4(1,0.5,0.5,1)) cs = NodePath("dummy") cs.setState(self.camstate) # Do we really need to turn on the Shader Generator? #cs.setShaderAuto() if (auxbits): cs.setAttrib(AuxBitplaneAttrib.make(auxbits)) self.camera.node().setInitialState(cs.getState()) quadcamnode = Camera("filter-quad-cam") lens = OrthographicLens() lens.setFilmSize(2, 2) lens.setFilmOffset(0, 0) lens.setNearFar(-1000, 1000) quadcamnode.setLens(lens) quadcam = quad.attachNewNode(quadcamnode) self.region.setCamera(quadcam) self.setStackedClears(buffer, self.rclears, self.wclears) if (auxtex0): buffer.setClearActive(GraphicsOutput.RTPAuxRgba0, 1) buffer.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5, 0.5, 1.0, 0.0)) if (auxtex1): buffer.setClearActive(GraphicsOutput.RTPAuxRgba1, 1) self.region.disableClears() if (self.isFullscreen()): self.win.disableClears() dr = buffer.makeDisplayRegion() dr.disableClears() dr.setCamera(self.camera) dr.setActive(1) self.buffers.append(buffer) self.sizes.append((1, 1, 1)) return quad
class FishManager: __module__ = __name__ notify = DirectNotifyGlobal.directNotify.newCategory('FishManager') def __init__(self, gameObject=None): base.loadingScreen.beginStep('FishManager', 2, 20) self.gameObject = gameObject if self.gameObject.distributedFishingSpot.onABoat: self.location = 'ship' else: self.location = 'dock' self.uncaughtFish = [] self.caughtFish = 0 self.deadFish = [] self.activeFish = None self.specialFishIndex = 0 self.fishHistogram = {} for fish in FishingGlobals.allFishData: self.fishHistogram[fish['id']] = [0, fish['maxPossiblePerScene']] self.hiddenFish = [] self.legendaryFishPool = [] self.hideNormalFishSequence = Sequence() self.objectsWithCaustics = NodePath('objectsWithCaustics') self.objectsWithCaustics.reparentTo(self.gameObject.fishingSpot) self.causticsTexture = loader.loadTexture( 'maps/pir_t_gam_fsh_caustics.jpg') self.causticsShader = loader.loadShader( 'models/shaders/fishingCausticsShader.sha') if base.win: if base.win.getGsg(): intShaders = base.win.getGsg().getSupportsBasicShaders() else: intShaders = 0 intShaders > 0 and self.doShaders() else: self.doFixedFunction() if base.win and base.win.getGsg(): shaderModel = base.win.getGsg().getShaderModel() base.loadingScreen.tick() self.loadFish() base.loadingScreen.endStep('FishManager') return def loadFish(self): rodSize = self.gameObject.getAvatarsBestRod() for depth in range( len(FishingGlobals.fishCountRangePerRodPerLevel[rodSize])): numberOfFishForThisLevel = random.randint( FishingGlobals.fishCountRangePerRodPerLevel[rodSize][depth][0], FishingGlobals.fishCountRangePerRodPerLevel[rodSize][depth][1]) for fishIndex in range(numberOfFishForThisLevel): fishData = FishingGlobals.giveMeAFish(self.location, depth, self.fishHistogram) f = Fish(self, fishData, len(self.uncaughtFish)) self.fishHistogram[f.myData['id']][0] += 1 f.fsm.request('Offscreen') self.uncaughtFish.append(f) self.legendaryFish = None return def doShaders(self): self.objectsWithCaustics.setShader(self.causticsShader) self.objectsWithCaustics.setShaderInput('caustics', self.causticsTexture) self.objectsWithCaustics.setShaderInput( 'causticsParams', Vec4(5.33, 0.0234325112498, 0.010589092533, 0.2)) self.objectsWithCaustics.setShaderInput( 'causticsParams2', Vec4(2.879531, -0.03568613, 0.0275891, 0.2)) self.objectsWithCaustics.setShaderInput( 'causticsParams3', Vec4(3.7854611, 0.03703703, 0.047619047619047616, 0.2)) self.objectsWithCaustics.setShaderInput( 'fogInfo', Vec4(0.0, FishingGlobals.fogDarkness, 0.7, 0.0)) self.objectsWithCaustics.setShaderInput('fogColor', FishingGlobals.waterFogColor) self.objectsWithCaustics.setShaderInput( 'causticsToWorldScale', Vec4(1.0 / 30.1, 1.0 / 30.1, 0.0, 0.0)) self.objectsWithCaustics.setShaderInput('sunWorldLocation', Vec4(0.0, 0.0, 100.0, 1.0)) def doFixedFunction(self): fishFog = Fog('fishFogNode') fishFog.setMode(Fog.MLinear) fishFog.setColor(FishingGlobals.waterFogColor) fishFog.setLinearRange(0.0, 200.0) fishFogAttrib = FogAttrib.make(fishFog) self.objectsWithCaustics.setAttrib(fishFogAttrib) def codeReload(self): for fish in self.uncaughtFish: print fish.codeReload() def scareAwayNormalFish(self): for fish in self.uncaughtFish: if fish.fsm.getCurrentOrNextState() != 'ScareAway': if fish.movingRight: fish.fsm.getCurrentOrNextState( ) != 'TurnAround' and fish.fsm.request( 'TurnAround', 'ScareAway', False) else: fish.fsm.request('ScareAway') def startLegendaryFish(self, whichFish=None): self.notify.debug('start LegendaryFish %s' % str(whichFish)) fishData = FishingGlobals.getALegendaryFish(whichFish) self.legendaryFish = LegendaryFish(self, fishData, 0) self.activeFish = self.legendaryFish self.legendaryFish.fsm.request('AboutToBiteLure') def replaceFish(self, fish): depth = fish.myData['depth'] index = fish.index self.fishHistogram[fish.myData['id']][0] -= 1 self.uncaughtFish.remove(fish) fish.destroy() fishData = FishingGlobals.giveMeAFish(self.location, depth, self.fishHistogram) f = Fish(self, fishData, index) f.fsm.request('Offscreen') self.fishHistogram[f.myData['id']][0] += 1 f.pickPositionAndSwim() self.uncaughtFish.append(f) def destroy(self): for fish in self.uncaughtFish: fish.destroy() self.uncaughtFish = [] if self.legendaryFish: self.legendaryFish.destroy() self.legendaryFish = None return def moveFish(self, direction): self.shutdown() self.specialFishIndex += direction self.specialFishIndex = max( min(len(FishingGlobals.allFishData) - 1, self.specialFishIndex), 0) self.startup() def startup(self): for fish in self.uncaughtFish: fish.pickPositionAndSwim() def shutdown(self): self.activeFish = None self.caughtFish = 0 self.deadFish = [] for fish in self.uncaughtFish: if fish.fsm.getCurrentOrNextState() != 'Offscreen': fish.fsm.request('Offscreen') return def reset(self): if self.activeFish and self.activeFish.fsm and self.activeFish.fsm.getCurrentOrNextState( ) != 'Offscreen': self.activeFish.fsm.request('Offscreen') self.activeFish = None self.deadFish = [] self.loseInterest() return def update(self, dt): lurePos = self.gameObject.lure.getPos() for i in range(len(self.uncaughtFish)): self.uncaughtFish[i].update(dt, i, lurePos) for fish in self.deadFish: self.uncaughtFish.remove(fish) fish.destroy() self.deadFish = [] def turnAllFish(self): for fish in self.uncaughtFish: if fish.fsm.getCurrentOrNextState() != 'TurnAround': fish.fsm.request('TurnAround', 'Swimming', not fish.movingRight) def enterReeling(self): pass def reloadCollisions(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: for fishData in FishingGlobals.allFishData: if fish.myData['model'] == fishData['model']: fish.myData = fishData fish.reloadCollisions() continue def loseInterest(self): for fish in self.uncaughtFish: if fish.fsm.getCurrentOrNextState() == 'Biting': fish.fsm.request('Swimming') def showAvoidanceCollisionVisuals(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: fish.showAvoidanceCollisionVisuals() def hideAvoidanceCollisionVisuals(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: fish.hideAvoidanceCollisionVisuals() def showAttractionCollisionVisuals(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: fish.showAttractionCollisionVisuals() def hideAttractionCollisionVisuals(self): if FishingGlobals.wantDebugCollisionVisuals: for fish in self.uncaughtFish: fish.hideAttractionCollisionVisuals()