Exemple #1
0
 def write(self, pth):
     """ Writes the image to disk """
     Globals.base.graphicsEngine.extract_texture_data(self, Globals.base.win.get_gsg())
     if self.get_texture_type() in [Texture.TT_3d_texture, Texture.TT_cube_map]:
         Texture.write(self, "#_" + pth, 0, 0, True, False)
     else:
         Texture.write(self, pth)
 def makeTextureMap(self):
     '''Citymania function that generates and sets the 4 channel texture map'''
     self.colorTextures = []
     for terrain in self.terrains:
         terrain.getRoot().clearTexture()
         heightmap = terrain.heightfield()
         colormap = PNMImage(heightmap.getXSize()-1, heightmap.getYSize()-1)
         colormap.addAlpha()
         slopemap = terrain.makeSlopeImage()
         for x in range(0, colormap.getXSize()):
             for y in range(0, colormap.getYSize()):
                 # Else if statements used to make sure one channel is used per pixel
                 # Also for some optimization
                 # Snow. We do things funky here as alpha will be 1 already.
                 if heightmap.getGrayVal(x, y) < 200:
                     colormap.setAlpha(x, y, 0)
                 else:
                     colormap.setAlpha(x, y, 1)
                 # Beach. Estimations from http://www.simtropolis.com/omnibus/index.cfm/Main.SimCity_4.Custom_Content.Custom_Terrains_and_Using_USGS_Data
                 if heightmap.getGrayVal(x,y) < 62:
                     colormap.setBlue(x, y, 1)
                 # Rock
                 elif slopemap.getGrayVal(x, y) > 170:
                     colormap.setRed(x, y, 1)
                 else:
                     colormap.setGreen(x, y, 1)
         colorTexture = Texture()
         colorTexture.load(colormap)
         colorTS = TextureStage('color')
         colorTS.setSort(0)
         colorTS.setPriority(1)
         self.colorTextures.append((colorTexture, colorTS))
    def createTexture(self, image):
        (width, height) = cv.GetSize(image)
	
        #Panda3D interpreta las imagenes al reves que OpenCV (verticalmente invertidas), por lo que es necesario tener esto en cuenta
        cv.Flip(image, image, 0)
	
        #OpenCV permite convertir la representacion interna de las imagenes a un formato descomprimido que puede ser guardado en un archivo.
        #Esto puede utilizarse desde Panda3D para tomar la imagen y utilizarla como una textura.
        imageString = image.tostring()
        #PTAUchar es una clase que permite tomar un bloque de datos y utilizarlo desde componentes de Panda3D (en particular es util para texturas)
        imagePointer = PTAUchar.emptyArray(0)
        imagePointer.setData(imageString)
        
        try:
            self.count += 1
            #Crea un nuevo objeto textura
            texture = Texture('image' + str(self.count))
            #Establece propiedades de la textura, como tamanio, tipo de datos y modelo de color. Las imagenes de OpenCV las estamos manejando
            #como RGB, donde cada canal es de 8bits (un numero entero)
            texture.setup2dTexture(width, height, Texture.TUnsignedByte, Texture.FRgb)
            #Indicamos que utilice el bloque de datos obtenido anteriormente como origen de datos para la textura
            texture.setRamImage(CPTAUchar(imagePointer), MovieTexture.CMOff)
        except:
            texture = None
        
        return texture
def getTextureRAM(mesh):
    total_image_area = 0
    for cimg in mesh.images:
        pilimg = cimg.pilimage

        if pilimg:
            total_image_area += pilimg.size[0] * pilimg.size[1] * len(pilimg.getbands())
        else:
            # PIL doesn't support DDS, so if loading failed, try and load it as a DDS with panda3d
            imgdata = cimg.data

            # if we can't even load the image's data, can't convert
            if imgdata is None:
                continue

            try:
                from panda3d.core import Texture
                from panda3d.core import StringStream
            except ImportError:
                # if panda3d isn't installed and PIL failed, can't convert
                continue

            t = Texture()
            try:
                success = t.readDds(StringStream(imgdata))
            except:
                success = 1
            if success == 0:
                # failed to load as DDS, so let's give up
                continue
            total_image_area += t.getXSize() * t.getYSize() * 3

    return total_image_area
class MatPlotLibDemo(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        base.setFrameRateMeter(True)

        m = loader.loadModel("models/smiley")
        m.reparent_to(render)
        m.set_pos(0, 5, 0)

        x_size, y_size = 640, 480
        xy_ratio = float(y_size) / float(x_size)
        self.plot = Plot(x_size, y_size)

        self.input_img = PNMImage(x_size, y_size)
        self.input_tex = Texture()
        self.input_tex.load(self.input_img)

        self.card = CardMaker('pygame_card')
        self.card.setUvRange(Point2(0, 1),  # ll
                             Point2(1, 1),  # lr
                             Point2(1, 0),  # ur
                             Point2(0, 0))  # ul
        self.screen = render.attach_new_node(self.card.generate())
        self.screen.set_scale(1, 1, xy_ratio)
        self.screen.set_pos(-0.5, 2, -0.5 * xy_ratio)
        self.screen.setTexture(self.input_tex)
        # FIXME: Apparently mpl's print_to_buffer() doesn't write
        # alpha values properly. 
        self.screen.setTransparency(TransparencyAttrib.MAlpha)

        taskMgr.add(self.update, "update plot")

    def update(self, task):
        self.input_tex.set_ram_image_as(self.plot.draw(), "RGBA")
        return task.cont
    def __init__(self):
        load_prc_file_data("", """
            textures-power-2 none
            window-type offscreen
            win-size 100 100
            gl-coordinate-system default
            notify-level-display error
            print-pipe-types #f
        """)

        ShowBase.__init__(self)

        dest_tex = Texture()
        dest_tex.setup_2d_texture(2048, 2048, Texture.T_unsigned_byte, Texture.F_rgba8)
        cshader = Shader.load_compute(Shader.SL_GLSL, "grain.compute.glsl")
        node = NodePath("")
        node.set_shader(cshader)
        node.set_shader_input("DestTex", dest_tex)
        attr = node.get_attrib(ShaderAttrib)
        self.graphicsEngine.dispatch_compute(
            (2048 // 16, 2048 // 16, 1), attr, self.win.get_gsg())

        base.graphicsEngine.extract_texture_data(dest_tex, base.win.get_gsg())

        # Convert to single channel
        img = PNMImage(2048, 2048, 1, 255)
        dest_tex.store(img)
        img.set_num_channels(1)

        tex = Texture()
        tex.load(img)
        tex.write("grain.txo.pz")
    def create(self):
        """ Creates the passes """
        self.cloudStartHeight = 900.0
        self.cloudEndHeight = 3300.0
        self.cloudResolution = 768
        self.cloudResolutionH = 128

        self.voxelGrid = Texture("CloudVoxelGrid")
        self.voxelGrid.setup3dTexture(self.cloudResolution, self.cloudResolution, self.cloudResolutionH, Texture.TFloat, Texture.FR16)
        self.voxelGrid.setWrapU(Texture.WMRepeat)
        self.voxelGrid.setWrapV(Texture.WMRepeat)
        self.voxelGrid.setWrapW(Texture.WMClamp)

        self.cloudNoise = Texture("CloudNoise")
        self.cloudNoise.setup3dTexture(64, 64, 64, Texture.TFloat, Texture.FR16)
        self.cloudNoise.setWrapU(Texture.WMRepeat)
        self.cloudNoise.setWrapV(Texture.WMRepeat)
        self.cloudNoise.setWrapW(Texture.WMRepeat)

        MemoryMonitor.addTexture("CloudVoxelGrid", self.voxelGrid)
        MemoryMonitor.addTexture("CloudNoise", self.cloudNoise)

        self._createInitialGrid()

        self.renderPass = CloudRenderPass()
        self.pipeline.getRenderPassManager().registerPass(self.renderPass)
        self.pipeline.getRenderPassManager().registerStaticVariable("cloudVoxelGrid", self.voxelGrid)
        self.pipeline.getRenderPassManager().registerStaticVariable("cloudStartHeight", self.cloudStartHeight)
        self.pipeline.getRenderPassManager().registerStaticVariable("cloudEndHeight", self.cloudEndHeight)
        self.pipeline.getRenderPassManager().registerStaticVariable("cloudNoise", self.cloudNoise)
        self.pipeline.getRenderPassManager().registerDefine("CLOUDS_ENABLED", 1)
Exemple #8
0
    def createMaskedTexture(self, name):
        name = self.prepTextureName(name)
        original_name = name[len('masked-'):]
        if self.textures.has_key(original_name):
            tc = self.textures[original_name]   # get the original texture
            bm = tc.image_file
            img_type = tc.image_type

            if img_type == 'DDS':
                mtex = TextureContainer(name, tc.panda_texture, tc.image_file, img_type)
                self.textures[name] = mtex
                return mtex
                
            if img_type != 'IMG':
                print 'ERROR in createMaskedTexture(): cant create masked texture from non IMG type image'
                return None
                
            # print type(bm)
            # print len(bm)
            
            # FIXME: this just copies the original right now! Need to implement the alpha-mask bit still
            m_img = self.maskImg(bm, tc.panda_texture.getXSize() * tc.panda_texture.getYSize())

            t = Texture()               # create empty texture object
            component_type = Texture.TUnsignedByte
            format = Texture.FRgba 
            t.setup2dTexture(tc.panda_texture.getXSize(),tc.panda_texture.getYSize(), component_type, format)
            t.setRamImage(m_img)
            
            mtex = TextureContainer(name, t, m_img, img_type)
            self.textures[name] = mtex
            return mtex
        else:
            print 'TextureManager::createMaskedTexture() failed, original texture:%s not found' % (original_name)
            return None
Exemple #9
0
    def __init__(self, N, sourceTex, normalizationFactor):
        """ Creates a new fft instance. The source texture has to specified
        from the begining, as the shaderAttributes are pregenerated for
        performance reasons """
        DebugObject.__init__(self, "GPU-FFT")

        self.size = N
        self.log2Size = int(math.log(N, 2))
        self.normalizationFactor = normalizationFactor

        # Create a ping and a pong texture, because we can't write to the
        # same texture while reading to it (that would lead to unexpected
        # behaviour, we could solve that by using an appropriate thread size,
        # but it works fine so far)
        self.pingTexture = Texture("FFTPing")
        self.pingTexture.setup2dTexture(
            self.size, self.size, Texture.TFloat, Texture.FRgba32)
        self.pongTexture = Texture("FFTPong")
        self.pongTexture.setup2dTexture(
            self.size, self.size, Texture.TFloat, Texture.FRgba32)
        self.sourceTex = sourceTex

        for tex in [self.pingTexture, self.pongTexture, sourceTex]:
            tex.setMinfilter(Texture.FTNearest)
            tex.setMagfilter(Texture.FTNearest)
            tex.setWrapU(Texture.WMClamp)
            tex.setWrapV(Texture.WMClamp)

        # Pregenerate weights & indices for the shaders
        self._computeWeighting()

        # Pre generate the shaders, we have 2 passes: Horizontal and Vertical
        # which both execute log2(N) times with varying radii
        self.horizontalFFTShader = BetterShader.loadCompute(
            "Shader/Water/HorizontalFFT.compute")
        self.horizontalFFT = NodePath("HorizontalFFT")
        self.horizontalFFT.setShader(self.horizontalFFTShader)
        self.horizontalFFT.setShaderInput(
            "precomputedWeights", self.weightsLookupTex)
        self.horizontalFFT.setShaderInput("N", LVecBase2i(self.size))

        self.verticalFFTShader = BetterShader.loadCompute(
            "Shader/Water/VerticalFFT.compute")
        self.verticalFFT = NodePath("VerticalFFT")
        self.verticalFFT.setShader(self.verticalFFTShader)
        self.verticalFFT.setShaderInput(
            "precomputedWeights", self.weightsLookupTex)
        self.verticalFFT.setShaderInput("N", LVecBase2i(self.size))

        # Create a texture where the result is stored
        self.resultTexture = Texture("Result")
        self.resultTexture.setup2dTexture(
            self.size, self.size, Texture.TFloat, Texture.FRgba16)
        self.resultTexture.setMinfilter(Texture.FTLinear)
        self.resultTexture.setMagfilter(Texture.FTLinear)

        # Prepare the shader attributes, so we don't have to regenerate them
        # every frame -> That is VERY slow (3ms per fft instance)
        self._prepareAttributes()
Exemple #10
0
 def __init__(self, name):
     """ Internal method to create a new image """
     RPObject.__init__(self, name)
     Texture.__init__(self, name)
     Image.REGISTERED_IMAGES.append(self)
     self.set_clear_color(0)
     self.clear_image()
     self.sort = RenderTarget.CURRENT_SORT
Exemple #11
0
    def add_render_texture(output, mode=None, bitplane=None):
        """Add render texture to `output`.

        Args:
            output (GraphicsOutput): Graphics output.

        Keyword Args:
            mode (GraphicsOutput.RenderTextureMode):
                | RTMNode
                | RTMBindOrCopy
                | RTMCopyTexture
                | RTMCopyRam
                | RTMTriggeredCopyTexture
                | RTMTriggeredCopyRam
            bitplane (DrawableRegion.RenderTexturePlane):
                | RTPStencil
                | RTPDepthStencil
                | RTPColor
                | RTPAuxRgba0
                | RTPAuxRgba1
                | RTPAuxRgba2
                | RTPAuxRgba3
                | RTPAuxHrgba0
                | RTPAuxHrgba1
                | RTPAuxHrgba2
                | RTPAuxHrgba3
                | RTPAuxFloat0
                | RTPAuxFloat1
                | RTPAuxFloat2
                | RTPAuxFloat3
                | RTPDepth
                | RTPCOUNT

        Return:
            (Texture): Texture object.

        """
        # Mode.
        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)
        # Bitplane.
        if bitplane is GraphicsOutput.RTPColor:
            fmt = Texture.FLuminance
        elif bitplane is GraphicsOutput.RTPDepth:
            fmt = Texture.FDepthComponent
        # Get a handle to the texture.
        tex = Texture()
        tex.setFormat(fmt)
        # Add the texture to the buffer.
        output.addRenderTexture(tex, mode, bitplane)
        tex.clearRamImage()
        return tex
 def _load_noise_tex(self):
     """ Loads the default 4x4 noise tex """
     random.seed(42)
     img = PNMImage(4, 4, 3)
     for x in range(16):
         img.set_xel(x%4, x//4, random.random(), random.random(), random.random())
     tex = Texture("Random4x4")
     tex.load(img)
     self._pipeline.stage_mgr.add_input("Noise4x4", tex)
    def initTransparencyPass(self):
        """ Creates the pass which renders the transparent objects into the scene """
        self.transparencyPass = TransparencyPass()
        self.pipeline.getRenderPassManager().registerPass(self.transparencyPass)

        # Create the atomic counter which stores the amount of rendered transparent
        # pixels. For now this a 1x1 texture, as atomic counters are not implemented.
        self.pixelCountBuffer = Texture("MaterialCountBuffer")
        self.pixelCountBuffer.setup2dTexture(1, 1, Texture.TInt, Texture.FR32i)

        # Creates the buffer which stores all transparent pixels. Pixels are inserted
        # into the buffer in the order they are rendered, using the pixelCountBuffer
        # to determine their index 
        self.materialDataBuffer = Texture("MaterialDataBuffer")
        self.materialDataBuffer.setupBufferTexture(self.maxPixelCount, Texture.TFloat, 
            Texture.FRgba32, GeomEnums.UH_static)

        # Creates the list head buffer, which stores the first transparent pixel for
        # each window pixel. The index stored in this buffer is the index into the 
        # materialDataBuffer
        self.listHeadBuffer = Texture("ListHeadBuffer")
        self.listHeadBuffer.setup2dTexture(self.pipeline.getSize().x, self.pipeline.getSize().y, 
            Texture.TInt, Texture.FR32i)

        # Creates the spinlock buffer, which ensures that writing to the listHeadBuffer
        # is sequentially
        self.spinLockBuffer = Texture("SpinLockBuffer")
        self.spinLockBuffer.setup2dTexture(self.pipeline.getSize().x, self.pipeline.getSize().y, 
            Texture.TInt, Texture.FR32i)

        # Set the buffers as input to the main scene. Maybe we can do this more elegant
        target = self.pipeline.showbase.render
        target.setShaderInput("pixelCountBuffer", self.pixelCountBuffer)
        target.setShaderInput("spinLockBuffer", self.spinLockBuffer)
        target.setShaderInput("materialDataBuffer", self.materialDataBuffer)
        target.setShaderInput("listHeadBuffer", self.listHeadBuffer)

        # Provides the buffers as global shader inputs
        self.pipeline.getRenderPassManager().registerStaticVariable("transpPixelCountBuffer", self.pixelCountBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable("transpSpinLockBuffer", self.spinLockBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable("transpListHeadBuffer", self.listHeadBuffer)
        self.pipeline.getRenderPassManager().registerStaticVariable("transpMaterialDataBuffer", self.materialDataBuffer)

        # Registers the transparency settings to the shaders
        self.pipeline.getRenderPassManager().registerDefine("USE_TRANSPARENCY", 1)
        self.pipeline.getRenderPassManager().registerDefine("MAX_TRANSPARENCY_LAYERS", 
            self.pipeline.settings.maxTransparencyLayers)

        self.pixelCountBuffer.setClearColor(Vec4(0, 0, 0, 0))
        self.spinLockBuffer.setClearColor(Vec4(0, 0, 0, 0))
        self.listHeadBuffer.setClearColor(Vec4(0, 0, 0, 0))

        MemoryMonitor.addTexture("MaterialCountBuffer", self.pixelCountBuffer)
        MemoryMonitor.addTexture("MaterialDataBuffer", self.materialDataBuffer)
        MemoryMonitor.addTexture("ListHeadBuffer", self.listHeadBuffer)
        MemoryMonitor.addTexture("SpinLockBuffer", self.spinLockBuffer)
Exemple #14
0
 def __apply_Textures(self, recipe, tex_dict):
     for i, ter_dict in enumerate(recipe['terrains']):
         tex_img = PNMImage()
         tex_img.read(Filename("{}/tex/{}".format(recipe['planet_path'], ter_dict['texture'])))
         tex = Texture()
         tex.load(tex_img)
         tex.setMinfilter(Texture.FTLinear)
         ts = TextureStage(str(i))
         ts.setSort(i)
         self.NP.setTexture(ts, tex, i*10)
Exemple #15
0
 def create_noise_textures(self):
     # Always generate the same random textures
     seed(42)
     img = PNMImage(4, 4, 3)
     for x in range(4):
         for y in range(4):
             img.set_xel(x, y, random(), random(), random())
     tex = Texture("Rand4x4")
     tex.load(img)
     self._target.set_shader_input("Noise4x4", tex)
 def __init__(self):
   Texture.__init__(self)
   
   self.axisx = 0 # offset distance to the right side of the sprite from the origin. X+ is to the right
   self.axisy = 0 # offset distance to the top side of the sprite from the origin. Y+ is up
   self.group = 0
   self.no = 0
   
   self.hit_boxes = []
   self.damage_boxes = []
Exemple #17
0
def filter_cubemap(orig_pth):

    if not os.path.isdir("Filtered/"):
        os.makedirs("Filtered/")

    # Copy original cubemap
    for i in range(6):
       shutil.copyfile(orig_pth.replace("#", str(i)), "Filtered/0-" + str(i) + ".png")

    mip = 0
    while True:
        print("Filtering mipmap", mip)
        mip += 1
        pth = "Filtered/" + str(mip - 1) + "-#.png"
        dst_pth = "Filtered/" + str(mip) + "-#.png"
        first_img = load_nth_face(pth, 0)
        size = first_img.get_x_size() // 2
        if size < 1:
            break
        blur_size = size * 0.002
        blur_size += mip * 0.85
        blur_size = int(blur_size)
        effective_size = size + 2 * blur_size
        faces = [load_nth_face(pth, i) for i in range(6)]

        cubemap = loader.loadCubeMap(pth)
        node = NodePath("")
        node.set_shader(compute_shader)
        node.set_shader_input("SourceCubemap", cubemap)
        node.set_shader_input("size", size)
        node.set_shader_input("blurSize", blur_size)
        node.set_shader_input("effectiveSize", effective_size)

        final_img = PNMImage(size, size, 3)

        for i in range(6):
            face_dest = dst_pth.replace("#", str(i))
            dst = Texture("Face-" + str(i))
            dst.setup_2d_texture(effective_size, effective_size,
                                 Texture.T_float, Texture.F_rgba16)

            # Execute compute shader
            node.set_shader_input("faceIndex", i)
            node.set_shader_input("DestTex", dst)
            attr = node.get_attrib(ShaderAttrib)
            base.graphicsEngine.dispatch_compute(( (effective_size+15) // 16,
                                                   (effective_size+15) // 16, 1),
                                                 attr, base.win.get_gsg())

            base.graphicsEngine.extract_texture_data(dst, base.win.get_gsg())
            img = PNMImage(effective_size, effective_size, 3)
            dst.store(img)
            img.gaussian_filter(blur_size)
            final_img.copy_sub_image(img, 0, 0, blur_size, blur_size, size, size)
            final_img.write(face_dest)
Exemple #18
0
 def setOwnerTextures(self):
     self.ownerview = True
     root = self.terrain.getRoot()
     root.clearShader()
     root.clearTexture()
     cityTexture = Texture()
     cityTexture.load(self.citymap)
     cityTS = TextureStage('citymap')
     cityTS.setSort(0)
     root.setTexture( self.gridTS, self.gridTexture ) 
     root.setTexScale(self.gridTS, self.terrain.xchunks, self.terrain.ychunks)
     root.setTexture(cityTS, cityTexture, 1)
Exemple #19
0
 def __get_Texture(self, ref_img):
     # Convert ref_img into texture.
     with TimeIt() as prep_timer:
         ref_tex = Texture()
         # Ensure ref image has an alpha channel.
         if not ref_img.hasAlpha():
             ref_img.addAlpha()
             ref_img.alphaFill(1.0)
         # Load tex and set format
         ref_tex.load(ref_img)
         ref_tex.setFormat(self.img_format)
     self.prepare_time += round(prep_timer.total_time, 3)
     return ref_tex
class ScatteringCubemapPass(RenderPass):

    """ This pass computes the scattering to a cubemap """

    def __init__(self):
        RenderPass.__init__(self)
        self.cubemapSize = 256

    def getID(self):
        return "ScatteringCubemapPass"

    def getRequiredInputs(self):
        return {

            # Scattering
            "transmittanceSampler": ["Variables.transmittanceSampler", "Variables.emptyTextureWhite"],
            "inscatterSampler": ["Variables.inscatterSampler", "Variables.emptyTextureWhite"],
            "scatteringOptions": ["Variables.scatteringOptions", "Variables.null"],

            "mainRender": "Variables.mainRender",
            "cameraPosition": "Variables.cameraPosition",
            "mainCam": "Variables.mainCam",

            "wsPositionTex": "DeferredScenePass.wsPosition",
            "wsNormalTex": "DeferredScenePass.wsNormal",
            "basecolorTex": "DeferredScenePass.data3",
            # "viewSpacePosition": "ViewSpacePass.position"

            "cloudsTex": ["CloudRenderPass.resultTex", "Variables.emptyTextureWhite"]
        }

    def create(self):

        self.cubemap = Texture("Scattering Cubemap")
        self.cubemap.setupCubeMap(self.cubemapSize, Texture.TFloat, Texture.FRgba16)
        self.cubemap.setMinfilter(Texture.FTLinearMipmapLinear)
        self.cubemap.setMagfilter(Texture.FTLinearMipmapLinear)
        self.cubemap.setKeepRamImage(False)

        self.target = RenderTarget("ScatteringCubemap")
        self.target.setSize(self.cubemapSize * 6, self.cubemapSize)
        self.target.addColorTexture()
        # self.target.addAuxTexture()
        # self.target.setAuxBits(16)
        # self.target.setColorBits(16)
        self.target.prepareOffscreenBuffer()
        self.target.setShaderInput("cubemapSize", self.cubemapSize)
        self.target.setShaderInput("cubemapDest", self.cubemap)

    def setShaders(self):
        shader = Shader.load(Shader.SLGLSL, 
            "Shader/DefaultPostProcess.vertex",
            "Shader/ScatteringCubemapPass.fragment")
        self.target.setShader(shader)
        return [shader]

    def getOutputs(self):
        return {
            "ScatteringCubemapPass.resultCubemap": lambda: self.cubemap,
        }
Exemple #21
0
def make_star(name='star', scale=1, color=Vec3(1), texture_size=64, debug=False):
    card_maker = CardMaker(name)
    card_maker.set_frame(-1, 1, -1, 1)
    node_path = NodePath(name)
    node = card_maker.generate()
    final_node_path = node_path.attach_new_node(node)
    final_node_path.set_billboard_point_eye()
    from panda3d.core import Filename
    shaders = Shader.load(Shader.SL_GLSL,
                          Filename('Shader/Star/vertex.glsl'),
                          Filename('Shader/Star/fragment.glsl'),
                          Filename(''),
                          Filename(''),
                          Filename(''))
    if not shaders:
        print("WARNING. STAR SHADER FAILED TO LOAD", type(shaders))
    else:
        final_node_path.set_shader_input('cameraSpherePos', 1, 1, 1)
        final_node_path.set_shader_input('sphereRadius', 1.0)
        final_node_path.set_shader_input('myCamera', base.camera)
        final_node_path.set_shader(shaders)
        final_node_path.set_shader_input('blackbody', color)
    material = Material()
    material.set_emission(VBase4(color, 1.0))
    final_node_path.set_material(material)
    xn = PerlinNoise3(0.5, 0.5, 0.5)
    #yn = PerlinNoise3(0.5, 0.5, 0.5)
    texture = Texture('star')
    texture.setup_3d_texture()
    for z in range(texture_size):
        p = PNMImage(texture_size, texture_size)
        for y in range(texture_size):
            for x in range(texture_size):
                p.set_gray(x, y, abs(xn.noise(x, y, z)))
        texture.load(p, z, 0)
    diffuse = texture
    diffuse.setMinfilter(Texture.FTLinearMipmapLinear)
    diffuse.setAnisotropicDegree(4)
    final_node_path.set_texture(diffuse)
    normal = sandbox.base.loader.loadTexture('data/empty_textures/empty_normal.png')
    normalts = TextureStage('normalts')
    final_node_path.set_texture(normalts, normal)
    specular = sandbox.base.loader.loadTexture('data/empty_textures/empty_specular.png')
    spects = TextureStage('spects')
    final_node_path.set_texture(spects, specular)
    roughness = sandbox.base.loader.loadTexture('data/empty_textures/empty_roughness.png')
    roughts= TextureStage('roughts')
    final_node_path.set_texture(roughts, roughness)
    return final_node_path
Exemple #22
0
def peek_tex_with_clear_color(component_type, format, clear_color):
    """ Creates a 1-pixel texture with the given settings and clear color,
    then peeks the value at this pixel and returns it. """

    tex = Texture("")
    tex.setup_1d_texture(1, component_type, format)
    tex.set_clear_color(clear_color)
    tex.make_ram_image()

    col = LColor()
    tex.peek().fetch_pixel(col, 0, 0)
    return col
Exemple #23
0
    def setupTexture(self):
        """
        This is the overlay/decal/etc. which contains the typed characters.

        The texture size and the font size are currently tied together.
        :return:
        """
        self.texImage = PNMImage(1024, 1024)
        self.texImage.addAlpha()
        self.texImage.fill(1.0)
        self.texImage.alphaFill(1.0)

        self.tex = Texture('typing')
        self.tex.setMagfilter(Texture.FTLinear)
        self.tex.setMinfilter(Texture.FTLinear)

        self.typingStage = TextureStage('typing')
        self.typingStage.setMode(TextureStage.MModulate)

        self.tex.load(self.texImage)

        # ensure we can quickly update subimages
        self.tex.setKeepRamImage(True)

        # temp for drawing chars
        self.chImage = PNMImage(*self.fontCharSize)
 def _createDofStorage(self):
     """ Creates the texture where the dof factor is stored in, so we
     don't recompute it each pass """
     self.dofStorage = Texture("DOFStorage")
     self.dofStorage.setup2dTexture(
         self.showbase.win.getXSize(), self.showbase.win.getYSize(),
         Texture.TFloat, Texture.FRg16)
Exemple #25
0
 def setupTexture(self):
     cm = CardMaker('quadMaker')
     cm.setColor(1.0, 1.0, 1.0, 1.0)
     aspect = base.camLens.getAspectRatio()
     htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
     htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)
     cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
     bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1)
     bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)
     cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))
     card = cm.generate()
     self.quad = NodePath(card)
     self.quad.reparentTo(self.parent_)
     self.guiTex = Texture('guiTex')
     self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
     self.guiTex.setMinfilter(Texture.FTLinear)
     self.guiTex.setKeepRamImage(True)
     self.guiTex.makeRamImage()
     self.guiTex.setWrapU(Texture.WMRepeat)
     self.guiTex.setWrapV(Texture.WMRepeat)
     ts = TextureStage('webTS')
     self.quad.setTexture(ts, self.guiTex)
     self.quad.setTexScale(ts, 1.0, -1.0)
     self.quad.setTransparency(0)
     self.quad.setTwoSided(True)
     self.quad.setColor(1.0, 1.0, 1.0, 1.0)
     self.calcMouseLimits()
Exemple #26
0
    def loadTexture(self, texname, container):
        
        # Note that we reference the texture files by name. This works under the 
        # assumption that texture names are unique!
        if self.findTexture(texname) == True:
            return  # texture already loaded before
        
        # print 'loading texture:', texname
        t_type = ''
        s3dentry = container.s3d_file_obj.getFile(texname)            
        if s3dentry != None:
            texfile = s3dentry.data
            (magic,) = struct.unpack('<2s', texfile[0:2])
            if magic == 'BM':
                t_type = 'IMG'      # raw 32 bit rgba (actually argb)
                # Generic BMP file
                # patch up the sometimes irregular bmp headers
                texfile = self.checkBmp(texfile, texname)
                if texfile == None:
                    return
                
                # turn bmp into a 32bit rgba true color image
                # returns a tuple of (img, width, height)
                img = self.createAlphaBMP(texfile, texname)
                texfile = img[0]   # so that the addTexture() at the bottom works
                                    
                t = Texture()               # create empty texture object
                component_type = Texture.TUnsignedByte
                format = Texture.FRgba 
                t.setup2dTexture(img[1], img[2], component_type, format)
                t.setRamImage(img[0])
                #t.load(ti)                  # load texture from pnmimage
                
            elif magic == 'DD':
                t_type = 'DDS'
                # DDS file
                dds = DDSFile(texfile)
                dds.patchHeader()
                # dds.dumpHeader()
                # dds.uncompressToBmp()
                # dds.save(texname+'.dds')
                    
                ts = StringStream(dds.buf)  # turn into an istream                   
                t = Texture()               # create texture object
                t.readDds(ts)               # load texture from dds ram image
            else:
                print 'Error unsupported texture: %s magic:%s referenced in fragment: %i' % (texname, magic, f.id)
                return
        else:
            print 'Error: texture %s not found in s3d archive' % (texname)
            return
            
        # t.setWrapU(Texture.WMClamp)
        # t.setWrapV(Texture.WMClamp)

        self.addTexture(texname, t, texfile, t_type)
    def _createLastFrameBuffers(self):
        """ Creates the buffers which store the last frame depth, as the render
        target matcher cannot handle this """

        self.lastFrameDepth = Texture("LastFrameDepth")
        self.lastFrameDepth.setup2dTexture(self.showbase.win.getXSize(), self.showbase.win.getYSize(),
            Texture.TFloat, Texture.FR32)
        BufferViewerGUI.registerTexture("LastFrameDepth", self.lastFrameDepth)
        self.renderPassManager.registerStaticVariable("lastFrameDepth", self.lastFrameDepth)
    def _createLastFrameBuffers(self):
        """ Creates the buffers which store the last frame depth, as the render
        target matcher cannot handle this """

        self.lastFrameDepth = Texture("LastFrameDepth")
        self.lastFrameDepth.setup2dTexture(Globals.resolution.x, Globals.resolution.y,
            Texture.TFloat, Texture.FR32)
        BufferViewerGUI.registerTexture("LastFrameDepth", self.lastFrameDepth)
        MemoryMonitor.addTexture("LastFrameDepth", self.lastFrameDepth)
        self.renderPassManager.registerStaticVariable("lastFrameDepth", self.lastFrameDepth)
    def debug3DTexture(self, tex, dest):

        """ Writes a 3D Texture to disk """

        effectiveHeight = (tex.getYSize()+1) * (tex.getZSize())
        effectiveHeight -= 1
        effectiveWidth = (tex.getXSize()+1)*3

        effectiveHeight = tex.getYSize()
        effectiveWidth = tex.getXSize()

        
        self.debug("Texture Size =",tex.getXSize(),"x",tex.getYSize(),"x",tex.getZSize())
        self.debug("EffectiveHeight = ", effectiveHeight, "Layers=",tex.getZSize())
        
        store = Texture("store")
        store.setup2dTexture(
            effectiveWidth, effectiveHeight, Texture.TFloat, Texture.FRgba16)

        TextureCleaner.clearTexture(store, Vec4(1,0,1,1))

        # Create a dummy node and apply the shader to it
        shader = BetterShader.loadCompute("Shader/Write3DTexture.compute")
        dummy = NodePath("dummy")
        dummy.setShader(shader)
        dummy.setShaderInput("source", tex)
        dummy.setShaderInput("height", tex.getYSize() + 1)
        dummy.setShaderInput("width", tex.getXSize() + 1)
        dummy.setShaderInput("layerCount", tex.getZSize())
        dummy.setShaderInput("destination", store)

        # Retrieve the underlying ShaderAttrib
        sattr = dummy.get_attrib(ShaderAttrib)

        # Dispatch the compute shader, right now!
        Globals.base.graphicsEngine.dispatch_compute(
            (tex.getXSize() / 16, tex.getYSize() / 16, tex.getZSize()), sattr, base.win.get_gsg())

        Globals.base.graphicsEngine.extract_texture_data(
                store, Globals.base.win.getGsg())


        store.write(dest)
def make_star(name='star', scale=1, color=Vec3(1), texture_size=64, debug=False):
    card_maker = CardMaker(name)
    card_maker.set_frame(-1, 1, -1, 1)
    node_path = NodePath(name)
    node = card_maker.generate()
    final_node_path = node_path.attach_new_node(node)
    final_node_path.set_billboard_point_eye()
    shaders = Shader.load(Shader.SLGLSL,
                          'Shader/Star/vertex.glsl',
                          'Shader/Star/fragment.glsl')
    final_node_path.set_shader_input(b'cameraSpherePos', 1, 1, 1)
    final_node_path.set_shader_input(b'sphereRadius', 1.0)
    final_node_path.set_shader_input(b'myCamera', base.camera)
    final_node_path.set_shader(shaders)
    final_node_path.set_shader_input(b'blackbody', color)
    material = Material()
    material.set_emission(VBase4(color, 1.0))
    final_node_path.set_material(material)
    xn = PerlinNoise3(0.5, 0.5, 0.5)
    #yn = PerlinNoise3(0.5, 0.5, 0.5)
    texture = Texture('star')
    texture.setup_3d_texture()
    for z in range(texture_size):
        p = PNMImage(texture_size, texture_size)
        for y in range(texture_size):
            for x in range(texture_size):
                p.set_gray(x, y, abs(xn.noise(x, y, z)))
        texture.load(p, z, 0)
    diffuse = texture
    diffuse.setMinfilter(Texture.FTLinearMipmapLinear)
    diffuse.setAnisotropicDegree(4)
    final_node_path.set_texture(diffuse)
    normal = base.loader.loadTexture('Data/Textures/EmptyNormalTexture.png')
    normalts = TextureStage('normalts')
    final_node_path.set_texture(normalts, normal)
    specular = base.loader.loadTexture('Data/Textures/EmptySpecularTexture.png')
    spects = TextureStage('spects')
    final_node_path.set_texture(spects, specular)
    roughness = base.loader.loadTexture('Data/Textures/EmptyRoughnessTexture.png')
    roughts= TextureStage('roughts')
    final_node_path.set_texture(roughts, roughness)
    return final_node_path
Exemple #31
0
    def reconfigure(self, fullrebuild, changed):
        """ Reconfigure is called whenever any configuration change is made. """

        configuration = self.configuration

        if (fullrebuild):

            self.cleanup()

            if (len(configuration) == 0):
                return

            if not self.manager.win.gsg.getSupportsBasicShaders():
                return False

            auxbits = 0
            needtex = set(["color"])
            needtexcoord = set(["color"])

            if ("CartoonInk" in configuration):
                needtex.add("aux")
                auxbits |= AuxBitplaneAttrib.ABOAuxNormal
                needtexcoord.add("aux")

            if ("AmbientOcclusion" in configuration):
                needtex.add("depth")
                needtex.add("ssao0")
                needtex.add("ssao1")
                needtex.add("ssao2")
                needtex.add("aux")
                auxbits |= AuxBitplaneAttrib.ABOAuxNormal
                needtexcoord.add("ssao2")

            if ("BlurSharpen" in configuration):
                needtex.add("blur0")
                needtex.add("blur1")
                needtexcoord.add("blur1")

            if ("Bloom" in configuration):
                needtex.add("bloom0")
                needtex.add("bloom1")
                needtex.add("bloom2")
                needtex.add("bloom3")
                auxbits |= AuxBitplaneAttrib.ABOGlow
                needtexcoord.add("bloom3")

            if ("ViewGlow" in configuration):
                auxbits |= AuxBitplaneAttrib.ABOGlow

            if ("VolumetricLighting" in configuration):
                needtex.add(configuration["VolumetricLighting"].source)

            for tex in needtex:
                self.textures[tex] = Texture("scene-" + tex)
                self.textures[tex].setWrapU(Texture.WMClamp)
                self.textures[tex].setWrapV(Texture.WMClamp)

            self.finalQuad = self.manager.renderSceneInto(
                textures=self.textures, auxbits=auxbits)
            if (self.finalQuad == None):
                self.cleanup()
                return False

            if ("BlurSharpen" in configuration):
                blur0 = self.textures["blur0"]
                blur1 = self.textures["blur1"]
                self.blur.append(
                    self.manager.renderQuadInto("filter-blur0",
                                                colortex=blur0,
                                                div=2))
                self.blur.append(
                    self.manager.renderQuadInto("filter-blur1",
                                                colortex=blur1))
                self.blur[0].setShaderInput("src", self.textures["color"])
                self.blur[0].setShader(Shader.make(BLUR_X, Shader.SL_Cg))
                self.blur[1].setShaderInput("src", blur0)
                self.blur[1].setShader(Shader.make(BLUR_Y, Shader.SL_Cg))

            if ("AmbientOcclusion" in configuration):
                ssao0 = self.textures["ssao0"]
                ssao1 = self.textures["ssao1"]
                ssao2 = self.textures["ssao2"]
                self.ssao.append(
                    self.manager.renderQuadInto("filter-ssao0",
                                                colortex=ssao0))
                self.ssao.append(
                    self.manager.renderQuadInto("filter-ssao1",
                                                colortex=ssao1,
                                                div=2))
                self.ssao.append(
                    self.manager.renderQuadInto("filter-ssao2",
                                                colortex=ssao2))
                self.ssao[0].setShaderInput("depth", self.textures["depth"])
                self.ssao[0].setShaderInput("normal", self.textures["aux"])
                self.ssao[0].setShaderInput(
                    "random", loader.loadTexture("maps/random.rgb"))
                self.ssao[0].setShader(
                    Shader.make(
                        SSAO_BODY %
                        configuration["AmbientOcclusion"].numsamples,
                        Shader.SL_Cg))
                self.ssao[1].setShaderInput("src", ssao0)
                self.ssao[1].setShader(Shader.make(BLUR_X, Shader.SL_Cg))
                self.ssao[2].setShaderInput("src", ssao1)
                self.ssao[2].setShader(Shader.make(BLUR_Y, Shader.SL_Cg))

            if ("Bloom" in configuration):
                bloomconf = configuration["Bloom"]
                bloom0 = self.textures["bloom0"]
                bloom1 = self.textures["bloom1"]
                bloom2 = self.textures["bloom2"]
                bloom3 = self.textures["bloom3"]
                if (bloomconf.size == "large"):
                    scale = 8
                    downsamplerName = "filter-down4"
                    downsampler = DOWN_4
                elif (bloomconf.size == "medium"):
                    scale = 4
                    downsamplerName = "filter-copy"
                    downsampler = COPY
                else:
                    scale = 2
                    downsamplerName = "filter-copy"
                    downsampler = COPY
                self.bloom.append(
                    self.manager.renderQuadInto("filter-bloomi",
                                                colortex=bloom0,
                                                div=2,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto(downsamplerName,
                                                colortex=bloom1,
                                                div=scale,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto("filter-bloomx",
                                                colortex=bloom2,
                                                div=scale,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto("filter-bloomy",
                                                colortex=bloom3,
                                                div=scale,
                                                align=scale))
                self.bloom[0].setShaderInput("src", self.textures["color"])
                self.bloom[0].setShader(Shader.make(BLOOM_I, Shader.SL_Cg))
                self.bloom[1].setShaderInput("src", bloom0)
                self.bloom[1].setShader(Shader.make(downsampler, Shader.SL_Cg))
                self.bloom[2].setShaderInput("src", bloom1)
                self.bloom[2].setShader(Shader.make(BLOOM_X, Shader.SL_Cg))
                self.bloom[3].setShaderInput("src", bloom2)
                self.bloom[3].setShader(Shader.make(BLOOM_Y, Shader.SL_Cg))

            texcoords = {}
            texcoordPadding = {}

            for tex in needtexcoord:
                if self.textures[tex].getAutoTextureScale() != ATSNone or \
                                           "HalfPixelShift" in configuration:
                    texcoords[tex] = "l_texcoord_" + tex
                    texcoordPadding["l_texcoord_" + tex] = tex
                else:
                    # Share unpadded texture coordinates.
                    texcoords[tex] = "l_texcoord"
                    texcoordPadding["l_texcoord"] = None

            texcoordSets = list(enumerate(texcoordPadding.keys()))

            text = "//Cg\n"
            text += "void vshader(float4 vtx_position : POSITION,\n"
            text += "  out float4 l_position : POSITION,\n"

            for texcoord, padTex in texcoordPadding.items():
                if padTex is not None:
                    text += "  uniform float4 texpad_tx%s,\n" % (padTex)
                    if ("HalfPixelShift" in configuration):
                        text += "  uniform float4 texpix_tx%s,\n" % (padTex)

            for i, name in texcoordSets:
                text += "  out float2 %s : TEXCOORD%d,\n" % (name, i)

            text += "  uniform float4x4 mat_modelproj)\n"
            text += "{\n"
            text += "  l_position = mul(mat_modelproj, vtx_position);\n"

            for texcoord, padTex in texcoordPadding.items():
                if padTex is None:
                    text += "  %s = vtx_position.xz * float2(0.5, 0.5) + float2(0.5, 0.5);\n" % (
                        texcoord)
                else:
                    text += "  %s = (vtx_position.xz * texpad_tx%s.xy) + texpad_tx%s.xy;\n" % (
                        texcoord, padTex, padTex)

                    if ("HalfPixelShift" in configuration):
                        text += "  %s += texpix_tx%s.xy * 0.5;\n" % (texcoord,
                                                                     padTex)

            text += "}\n"

            text += "void fshader(\n"

            for i, name in texcoordSets:
                text += "  float2 %s : TEXCOORD%d,\n" % (name, i)

            for key in self.textures:
                text += "  uniform sampler2D k_tx" + key + ",\n"

            if ("CartoonInk" in configuration):
                text += "  uniform float4 k_cartoonseparation,\n"
                text += "  uniform float4 k_cartooncolor,\n"
                text += "  uniform float4 texpix_txaux,\n"

            if ("BlurSharpen" in configuration):
                text += "  uniform float4 k_blurval,\n"

            if ("VolumetricLighting" in configuration):
                text += "  uniform float4 k_casterpos,\n"
                text += "  uniform float4 k_vlparams,\n"
            text += "  out float4 o_color : COLOR)\n"
            text += "{\n"
            text += "  o_color = tex2D(k_txcolor, %s);\n" % (
                texcoords["color"])
            if ("CartoonInk" in configuration):
                text += CARTOON_BODY % {"texcoord": texcoords["aux"]}
            if ("AmbientOcclusion" in configuration):
                text += "  o_color *= tex2D(k_txssao2, %s).r;\n" % (
                    texcoords["ssao2"])
            if ("BlurSharpen" in configuration):
                text += "  o_color = lerp(tex2D(k_txblur1, %s), o_color, k_blurval.x);\n" % (
                    texcoords["blur1"])
            if ("Bloom" in configuration):
                text += "  o_color = saturate(o_color);\n"
                text += "  float4 bloom = 0.5 * tex2D(k_txbloom3, %s);\n" % (
                    texcoords["bloom3"])
                text += "  o_color = 1-((1-bloom)*(1-o_color));\n"
            if ("ViewGlow" in configuration):
                text += "  o_color.r = o_color.a;\n"
            if ("VolumetricLighting" in configuration):
                text += "  float decay = 1.0f;\n"
                text += "  float2 curcoord = %s;\n" % (texcoords["color"])
                text += "  float2 lightdir = curcoord - k_casterpos.xy;\n"
                text += "  lightdir *= k_vlparams.x;\n"
                text += "  half4 sample = tex2D(k_txcolor, curcoord);\n"
                text += "  float3 vlcolor = sample.rgb * sample.a;\n"
                text += "  for (int i = 0; i < %s; i++) {\n" % (int(
                    configuration["VolumetricLighting"].numsamples))
                text += "    curcoord -= lightdir;\n"
                text += "    sample = tex2D(k_tx%s, curcoord);\n" % (
                    configuration["VolumetricLighting"].source)
                text += "    sample *= sample.a * decay;//*weight\n"
                text += "    vlcolor += sample.rgb;\n"
                text += "    decay *= k_vlparams.y;\n"
                text += "  }\n"
                text += "  o_color += float4(vlcolor * k_vlparams.z, 1);\n"

            if ("GammaAdjust" in configuration):
                gamma = configuration["GammaAdjust"]
                if gamma == 0.5:
                    text += "  o_color.rgb = sqrt(o_color.rgb);\n"
                elif gamma == 2.0:
                    text += "  o_color.rgb *= o_color.rgb;\n"
                elif gamma != 1.0:
                    text += "  o_color.rgb = pow(o_color.rgb, %ff);\n" % (
                        gamma)

            if ("Inverted" in configuration):
                text += "  o_color = float4(1, 1, 1, 1) - o_color;\n"
            text += "}\n"

            shader = Shader.make(text, Shader.SL_Cg)
            if not shader:
                return False
            self.finalQuad.setShader(shader)
            for tex in self.textures:
                self.finalQuad.setShaderInput("tx" + tex, self.textures[tex])

            self.task = taskMgr.add(self.update, "common-filters-update")

        if (changed == "CartoonInk") or fullrebuild:
            if ("CartoonInk" in configuration):
                c = configuration["CartoonInk"]
                self.finalQuad.setShaderInput(
                    "cartoonseparation",
                    LVecBase4(c.separation, 0, c.separation, 0))
                self.finalQuad.setShaderInput("cartooncolor", c.color)

        if (changed == "BlurSharpen") or fullrebuild:
            if ("BlurSharpen" in configuration):
                blurval = configuration["BlurSharpen"]
                self.finalQuad.setShaderInput(
                    "blurval", LVecBase4(blurval, blurval, blurval, blurval))

        if (changed == "Bloom") or fullrebuild:
            if ("Bloom" in configuration):
                bloomconf = configuration["Bloom"]
                intensity = bloomconf.intensity * 3.0
                self.bloom[0].setShaderInput("blend", bloomconf.blendx,
                                             bloomconf.blendy,
                                             bloomconf.blendz,
                                             bloomconf.blendw * 2.0)
                self.bloom[0].setShaderInput(
                    "trigger", bloomconf.mintrigger,
                    1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0,
                    0.0)
                self.bloom[0].setShaderInput("desat", bloomconf.desat)
                self.bloom[3].setShaderInput("intensity", intensity, intensity,
                                             intensity, intensity)

        if (changed == "VolumetricLighting") or fullrebuild:
            if ("VolumetricLighting" in configuration):
                config = configuration["VolumetricLighting"]
                tcparam = config.density / float(config.numsamples)
                self.finalQuad.setShaderInput("vlparams", tcparam,
                                              config.decay, config.exposure,
                                              0.0)

        if (changed == "AmbientOcclusion") or fullrebuild:
            if ("AmbientOcclusion" in configuration):
                config = configuration["AmbientOcclusion"]
                self.ssao[0].setShaderInput(
                    "params1", config.numsamples,
                    -float(config.amount) / config.numsamples, config.radius,
                    0)
                self.ssao[0].setShaderInput("params2", config.strength,
                                            config.falloff, 0, 0)

        self.update()
        return True
Exemple #32
0
mat.set_emission((1.0, 1.0, 1.0, 1))
mat.set_metallic(1.0)
mat.set_roughness(1.0)
card_np.set_material(mat)


texture_size = 256
texture_bands_x = 2
texture_bands_y = 2


# Base color, a.k.a. Modulate, a.k.a. albedo map
# Gets multiplied with mat.base_color
base_color_pnm = PNMImage(texture_size, texture_size)
base_color_pnm.fill(0.72, 0.45, 0.2)  # Copper
base_color_tex = Texture("BaseColor")
base_color_tex.load(base_color_pnm)
ts = TextureStage('BaseColor') # a.k.a. Modulate
ts.set_mode(TextureStage.M_modulate)
card_np.set_texture(ts, base_color_tex)


# Emission; Gets multiplied with mat.emission
emission_pnm = PNMImage(texture_size, texture_size)
emission_pnm.fill(0.0, 0.0, 0.0)
emission_tex = Texture("Emission")
emission_tex.load(emission_pnm)
ts = TextureStage('Emission')
ts.set_mode(TextureStage.M_emission)
card_np.set_texture(ts, emission_tex)
Exemple #33
0
def getPmPerceptualError(mesh, pm_filebuf, mipmap_tarfilebuf):
    perceptualdiff = which('perceptualdiff')
    if perceptualdiff is None:
        raise Exception("perceptualdiff exectuable not found on path")

    pm_chunks = []

    if pm_filebuf is not None:
        data = pm_filebuf.read(PM_CHUNK_SIZE)
        refinements_read = 0
        num_refinements = None
        while len(data) > 0:
            (refinements_read, num_refinements, pm_refinements,
             data_left) = pdae_utils.readPDAEPartial(data, refinements_read,
                                                     num_refinements)
            pm_chunks.append(pm_refinements)
            data = data_left + pm_filebuf.read(PM_CHUNK_SIZE)

    tar = tarfile.TarFile(fileobj=mipmap_tarfilebuf)
    texsizes = []
    largest_tarinfo = (0, None)
    for tarinfo in tar:
        tarinfo.xsize = int(tarinfo.name.split('x')[0])
        if tarinfo.xsize > largest_tarinfo[0]:
            largest_tarinfo = (tarinfo.xsize, tarinfo)
        if tarinfo.xsize >= 128:
            texsizes.append(tarinfo)
    if len(texsizes) == 0:
        texsizes.append(largest_tarinfo[1])

    texsizes = sorted(texsizes, key=lambda t: t.xsize)
    texims = []
    first_image_data = None
    for tarinfo in texsizes:
        f = tar.extractfile(tarinfo)
        texdata = f.read()
        if first_image_data is None:
            first_image_data = texdata

        texpnm = PNMImage()
        texpnm.read(StringStream(texdata), 'something.jpg')
        newtex = Texture()
        newtex.load(texpnm)
        texims.append(newtex)

    mesh.images[0].setData(first_image_data)

    scene_members = getSceneMembers(mesh)

    # turn off panda3d printing to stdout
    nout = MultiplexStream()
    Notify.ptr().setOstreamPtr(nout, 0)
    nout.addFile(Filename(os.devnull))

    base = ShowBase()

    rotateNode = GeomNode("rotater")
    rotatePath = base.render.attachNewNode(rotateNode)
    matrix = numpy.identity(4)
    if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
        r = collada.scene.RotateTransform(0, 1, 0, 90)
        matrix = r.matrix
    elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
        r = collada.scene.RotateTransform(1, 0, 0, 90)
        matrix = r.matrix
    rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))
    geom, renderstate, mat4 = scene_members[0]
    node = GeomNode("primitive")
    node.addGeom(geom)
    if renderstate is not None:
        node.setGeomState(0, renderstate)
    geomPath = rotatePath.attachNewNode(node)
    geomPath.setMat(mat4)

    wrappedNode = ensureCameraAt(geomPath, base.camera)
    base.disableMouse()
    attachLights(base.render)
    base.render.setShaderAuto()
    base.render.setTransparency(TransparencyAttrib.MNone)
    base.render.setColorScaleOff(9999)

    controls.KeyboardMovement()
    controls.MouseDrag(wrappedNode)
    controls.MouseScaleZoom(wrappedNode)
    controls.ButtonUtils(wrappedNode)
    controls.MouseCamera()

    error_data = []

    try:
        tempdir = tempfile.mkdtemp(prefix='meshtool-print-pm-perceptual-error')

        triangleCounts = []

        hprs = [(0, 0, 0), (0, 90, 0), (0, 180, 0), (0, 270, 0), (90, 0, 0),
                (-90, 0, 0)]

        for texim in texims:
            np = base.render.find("**/rotater/collada")
            np.setTextureOff(1)
            np.setTexture(texim, 1)
            for angle, hpr in enumerate(hprs):
                wrappedNode.setHpr(*hpr)
                takeScreenshot(tempdir, base, geomPath, texim, angle)
        triangleCounts.append(getNumTriangles(geomPath))

        for pm_chunk in pm_chunks:
            pdae_panda.add_refinements(geomPath, pm_chunk)

            for texim in texims:
                np = base.render.find("**/rotater/collada")
                np.setTextureOff(1)
                np.setTexture(texim, 1)
                for angle, hpr in enumerate(hprs):
                    wrappedNode.setHpr(*hpr)
                    takeScreenshot(tempdir, base, geomPath, texim, angle)
            triangleCounts.append(getNumTriangles(geomPath))

        full_tris = triangleCounts[-1]
        full_tex = texims[-1]

        for numtris in triangleCounts:
            for texim in texims:
                pixel_diff = 0
                for angle, hpr in enumerate(hprs):
                    curFile = '%d_%d_%d_%d.png' % (numtris, texim.getXSize(),
                                                   texim.getYSize(), angle)
                    curFile = os.path.join(tempdir, curFile)

                    fullFile = '%d_%d_%d_%d.png' % (full_tris,
                                                    full_tex.getXSize(),
                                                    full_tex.getYSize(), angle)
                    fullFile = os.path.join(tempdir, fullFile)

                    try:
                        output = subprocess.check_output([
                            perceptualdiff, '-threshold', '1', fullFile,
                            curFile
                        ])
                    except subprocess.CalledProcessError as ex:
                        output = ex.output

                    output = output.strip()
                    if len(output) > 0:
                        pixel_diff = max(pixel_diff,
                                         int(output.split('\n')[1].split()[0]))

                error_data.append({
                    'triangles': numtris,
                    'width': texim.getXSize(),
                    'height': texim.getYSize(),
                    'pixel_error': pixel_diff
                })

    finally:
        shutil.rmtree(tempdir, ignore_errors=True)

    return error_data
Exemple #34
0
    def load(self, path):
        # vignette mask
        self.vignette_mask = None
        self.vignette_mask_small = None
        vfile = os.path.join(path, "vignette-mask.jpg")
        if os.path.exists(vfile):
            print("loading vignette correction mask:", vfile)
            self.vignette_mask = cv2.imread(vfile,
                                            flags=cv2.IMREAD_ANYCOLOR
                                            | cv2.IMREAD_ANYDEPTH
                                            | cv2.IMREAD_IGNORE_ORIENTATION)
            self.vignette_mask_small = cv2.resize(self.vignette_mask,
                                                  (512, 512))
        files = []
        for file in sorted(os.listdir(path)):
            if fnmatch.fnmatch(file, '*.egg'):
                # print('load:', file)
                files.append(file)
        print('Loading models:')
        for file in tqdm(files, ascii=True):
            # load and reparent each egg file
            pandafile = Filename.fromOsSpecific(os.path.join(path, file))
            model = self.loader.loadModel(pandafile)
            # model.set_shader(self.shader)

            # print(file)
            # self.pretty_print(model, '  ')

            model.reparentTo(self.render)
            self.models.append(model)
            tex = model.findTexture('*')
            if tex != None:
                tex.setWrapU(Texture.WM_clamp)
                tex.setWrapV(Texture.WM_clamp)
            self.base_textures.append(tex)

        # The egg model lists "dummy.jpg" as the texture model which
        # doesn't exists.  Here we load the actual textures and
        # possibly apply vignette correction and adaptive histogram
        # equalization.
        print('Loading base textures:')
        for i, model in enumerate(tqdm(self.models, ascii=True)):
            base, ext = os.path.splitext(model.getName())
            image_file = None
            dir = os.path.join(proj.analysis_dir, 'models')
            tmp1 = os.path.join(dir, base + '.JPG')
            tmp2 = os.path.join(dir, base + '.jpg')
            if os.path.isfile(tmp1):
                image_file = tmp1
            elif os.path.isfile(tmp2):
                image_file = tmp2
            #print("texture file:", image_file)
            if False:
                tex = self.loader.loadTexture(image_file)
            else:
                rgb = cv2.imread(image_file,
                                 flags=cv2.IMREAD_ANYCOLOR
                                 | cv2.IMREAD_ANYDEPTH
                                 | cv2.IMREAD_IGNORE_ORIENTATION)
                rgb = np.flipud(rgb)
                # vignette correction
                if not self.vignette_mask_small is None:
                    rgb = rgb.astype('uint16') + self.vignette_mask_small
                    rgb = np.clip(rgb, 0, 255).astype('uint8')
                # adaptive equalization
                hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV)
                hue, sat, val = cv2.split(hsv)
                aeq = clahe.apply(val)
                # recombine
                hsv = cv2.merge((hue, sat, aeq))
                # convert back to rgb
                rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
                tex = Texture(base)
                tex.setCompression(Texture.CMOff)
                tex.setup2dTexture(512, 512, Texture.TUnsignedByte,
                                   Texture.FRgb)
                tex.setRamImage(rgb)
            tex.setWrapU(Texture.WM_clamp)
            tex.setWrapV(Texture.WM_clamp)
            model.setTexture(tex, 1)
            self.base_textures[i] = tex
        self.sortImages()
        self.annotations.rebuild(self.view_size)
Exemple #35
0
class MazeMapGui(DirectFrame):
    notify = directNotify.newCategory('MazeMapGui')

    def __init__(self,
                 mazeCollTable,
                 maskResolution=None,
                 radiusRatio=None,
                 bgColor=(0.8, 0.8, 0.8),
                 fgColor=(0.5, 0.5, 0.5, 1.0)):
        DirectFrame.__init__(self,
                             relief=None,
                             state=DGG.NORMAL,
                             sortOrder=DGG.BACKGROUND_SORT_INDEX)
        self.hide()
        self._bgColor = bgColor
        self._fgColor = fgColor
        self._mazeCollTable = mazeCollTable
        self._mazeWidth = len(self._mazeCollTable[0])
        self._mazeHeight = len(self._mazeCollTable)
        self._maskResolution = maskResolution or DEFAULT_MASK_RESOLUTION
        if radiusRatio is None:
            self._radius = self._maskResolution * DEFAULT_RADIUS_RATIO
        else:
            self._radius = self._maskResolution * radiusRatio
        self._revealedCells = []
        for y in xrange(self._mazeHeight):
            self._revealedCells.append([])
            for u in xrange(self._mazeWidth):
                self._revealedCells[y].append(False)

        self._revealFunctions = {
            MazeRevealType.SmoothCircle: self._revealSmoothCircle,
            MazeRevealType.HardCircle: self._revealHardCircle,
            MazeRevealType.Square: self._revealSquare
        }
        self._revealFunction = MAZE_REVEAL_TYPE
        self.map = self._createMapTextureCard()
        self.map.reparentTo(self)
        self.maskedLayer = self.attachNewNode('maskedLayer')
        self.mask = self._createMaskTextureCard()
        self.mask.reparentTo(self)
        self.visibleLayer = self.attachNewNode('visibleLayer')
        self._laffMeterModel = loader.loadModel(
            'phase_3/models/gui/laff_o_meter')
        self._toon2marker = {}
        return

    def _createMapTextureCard(self):
        mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION)
        mapImage.fill(*self._bgColor)
        fgColor = VBase4D(*self._fgColor)
        for x in xrange(self._mazeHeight):
            for y in xrange(self._mazeWidth):
                if self._mazeCollTable[y][x] == 1:
                    ax = float(x) / self._mazeWidth * MAP_RESOLUTION
                    invertedY = self._mazeHeight - 1 - y
                    ay = float(invertedY) / self._mazeHeight * MAP_RESOLUTION
                    self._drawSquare(mapImage, int(ax), int(ay), 10, fgColor)

        mapTexture = Texture('mapTexture')
        mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution,
                                self._maskResolution, 1, Texture.TUnsignedByte,
                                Texture.FRgba)
        mapTexture.setMinfilter(Texture.FTLinear)
        mapTexture.load(mapImage)
        mapTexture.setWrapU(Texture.WMClamp)
        mapTexture.setWrapV(Texture.WMClamp)
        mapImage.clear()
        del mapImage
        cm = CardMaker('map_cardMaker')
        cm.setFrame(-1.0, 1.0, -1.0, 1.0)
        map = self.attachNewNode(cm.generate())
        map.setTexture(mapTexture, 1)
        return map

    def _createMaskTextureCard(self):
        self._maskImage = PNMImage(self._maskResolution, self._maskResolution,
                                   4)
        for x in xrange(self._maskResolution):
            for y in xrange(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)

        self.maskTexture = Texture('maskTexture')
        self.maskTexture.setupTexture(Texture.TT2dTexture,
                                      self._maskResolution,
                                      self._maskResolution, 1,
                                      Texture.TUnsignedByte, Texture.FRgba)
        self.maskTexture.setMinfilter(Texture.FTLinear)
        self.maskTexture.setWrapU(Texture.WMClamp)
        self.maskTexture.setWrapV(Texture.WMClamp)
        self.maskTexture.load(self._maskImage)
        base.graphicsEngine.renderFrame()
        cm = CardMaker('mask_cardMaker')
        cm.setFrame(-1.1, 1.1, -1.1, 1.1)
        mask = self.attachNewNode(cm.generate())
        mask.setTexture(self.maskTexture, 1)
        mask.setTransparency(1)
        return mask

    def _drawSquare(self, image, ulx, uly, size, color):
        x = int(ulx)
        while x <= ulx + size:
            y = int(uly)
            while y <= uly + size:
                if x > 0 and y > 0 and x < image.getXSize(
                ) and y < image.getYSize():
                    image.setXelA(x, y, color)
                y += 1

            x += 1

    def destroy(self):
        del self._mazeCollTable
        del self._maskResolution
        del self._radius
        del self._revealedCells
        del self._revealFunctions
        del self._revealFunction
        self.map.removeNode()
        del self.map
        self.mask.removeNode()
        del self.mask
        self.maskedLayer.removeNode()
        del self.maskedLayer
        self.visibleLayer.removeNode()
        del self.visibleLayer
        self._maskImage.clear()
        del self._maskImage
        self.maskTexture.clear()
        del self.maskTexture
        self._laffMeterModel.removeNode()
        del self._laffMeterModel
        DirectFrame.destroy(self)

    def _revealSmoothCircle(self, x, y, center):
        length = (Vec2(x, y) - center).length()
        goalAlpha = max(0.0, length / float(self._radius) - 0.5)
        self._maskImage.setXelA(
            x, y,
            VBase4D(0.0, 0.0, 0.0,
                    min(self._maskImage.getAlpha(x, y), goalAlpha * 2.0)))

    def _revealHardCircle(self, x, y, center):
        length = (Vec2(x, y) - center).length()
        if length <= self._radius:
            self._maskImage.setXelA(x, y, VBase4D(0, 0, 0, 0))

    def _revealSquare(self, x, y, center):
        self._maskImage.setXelA(x, y, VBase4D(0, 0, 0, 0))

    def _drawHole(self, x, y):
        center = Vec2(x, y)
        ul = center - Vec2(self._radius, self._radius)
        lr = center + Vec2(self._radius, self._radius)
        x = int(ul[0])
        while x <= lr[0]:
            y = int(ul[1])
            while y <= lr[1]:
                if x > 0 and y > 0 and x < self._maskResolution and y < self._maskResolution:
                    self._revealFunctions[self._revealFunction](x, y, center)
                y += 1

            x += 1

        self.maskTexture.load(self._maskImage)
        self.mask.setTexture(self.maskTexture, 1)

    def _createSimpleMarker(self, size, color=(1, 1, 1)):
        halfSize = size * 0.5
        cm = CardMaker('mazemap_simple_marker')
        cm.setFrame(-halfSize, halfSize, -halfSize, halfSize)
        markerNP = self.maskedLayer.attachNewNode(cm.generate())
        markerNP.setColor(*color)
        return markerNP

    def tile2gui(self, x, y):
        y = self._mazeHeight - y
        cellWidth = self._maskResolution / self._mazeWidth
        cellHeight = self._maskResolution / self._mazeHeight
        ax = float(x) / self._mazeWidth * self._maskResolution
        ax += cellWidth
        ay = float(y) / self._mazeHeight * self._maskResolution
        ay += cellHeight
        return (ax, ay)

    def gui2pos(self, x, y):
        return (x / self._maskResolution * 2.0 - 0.97, 0,
                y / self._maskResolution * -2.0 + 1.02)

    def _getToonMarker(self, toon):
        hType = toon.style.getType()
        if hType == 'rabbit':
            hType = 'bunny'
        return self._laffMeterModel.find('**/' + hType + 'head')

    def addToon(self, toon, tX, tY):
        marker = NodePath('toon_marker-%i' % toon.doId)
        marker.reparentTo(self)
        self._getToonMarker(toon).copyTo(marker)
        marker.setColor(toon.style.getHeadColor())
        if toon.isLocal():
            marker.setScale(0.07)
        else:
            marker.setScale(0.05)
        marker.flattenStrong()
        marker.setPos(*self.gui2pos(*self.tile2gui(tX, tY)))
        self._toon2marker[toon] = marker

    def removeToon(self, toon):
        if toon not in self._toon2marker:
            return
        self._toon2marker[toon].removeNode()
        del self._toon2marker[toon]

    def updateToon(self, toon, tX, tY):
        if toon not in self._toon2marker:
            return
        x, y = self.tile2gui(tX, tY)
        self._toon2marker[toon].setPos(*self.gui2pos(x, y))
        if tY < 0 or tY >= len(self._revealedCells):
            self.notify.warning('updateToon earlying out:')
            self.notify.warning('(tX, tY): (%s, %s)' % (tX, tY))
            self.notify.warning('len(_revealedCells): %s' %
                                (len(self._revealedCells), ))
            if len(self._revealedCells) > 0:
                self.notify.warning('len(_revealedCells[0]): %s' %
                                    (len(self._revealedCells[0]), ))
            return
        if tX < 0 or tX >= len(self._revealedCells[tY]):
            self.notify.warning('updateToon earlying out:')
            self.notify.warning('(tX, tY): (%s, %s)' % (tX, tY))
            self.notify.warning('len(_revealedCells): %s' %
                                (len(self._revealedCells), ))
            if tY < len(self._revealedCells):
                self.notify.warning('len(_revealedCells[tY]): %s' %
                                    (len(self._revealedCells[tY]), ))
            elif len(self._revealedCells) > 0:
                self.notify.warning('len(_revealedCells[0]): %s' %
                                    (len(self._revealedCells[0]), ))
            return
        if not self._revealedCells[tY][tX]:
            self._drawHole(x, y)
            self._revealedCells[tY][tX] = True

    def revealCell(self, x, y):
        ax, ay = self.tile2gui(x, y)
        if not self._revealedCells[y][x]:
            self._drawHole(ax, ay)
            self._revealedCells[y][x] = True

    def revealAll(self):
        for x in xrange(self._maskResolution):
            for y in xrange(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 0)

        self.revealCell(0, 0)

    def reset(self):
        for x in xrange(self._maskResolution):
            for y in xrange(self._maskResolution):
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)
    def reconfigure(self, fullrebuild, changed):
        configuration = self.configuration
        if fullrebuild:
            self.cleanup()
            if len(configuration) == 0:
                return
            auxbits = 0
            needtex = set(['color'])
            needtexcoord = set(['color'])
            if 'CartoonInk' in configuration:
                needtex.add('aux')
                auxbits |= AuxBitplaneAttrib.ABOAuxNormal
                needtexcoord.add('aux')
            if 'AmbientOcclusion' in configuration:
                needtex.add('depth')
                needtex.add('ssao0')
                needtex.add('ssao1')
                needtex.add('ssao2')
                needtex.add('aux')
                auxbits |= AuxBitplaneAttrib.ABOAuxNormal
                needtexcoord.add('ssao2')
            if 'BlurSharpen' in configuration:
                needtex.add('blur0')
                needtex.add('blur1')
                needtexcoord.add('blur1')
            if 'Bloom' in configuration:
                needtex.add('bloom0')
                needtex.add('bloom1')
                needtex.add('bloom2')
                needtex.add('bloom3')
                auxbits |= AuxBitplaneAttrib.ABOGlow
                needtexcoord.add('bloom3')
            if 'ViewGlow' in configuration:
                auxbits |= AuxBitplaneAttrib.ABOGlow
            if 'VolumetricLighting' in configuration:
                needtex.add(configuration['VolumetricLighting'].source)
            for tex in needtex:
                self.textures[tex] = Texture('scene-' + tex)
                self.textures[tex].setWrapU(Texture.WMClamp)
                self.textures[tex].setWrapV(Texture.WMClamp)

            self.finalQuad = self.manager.renderSceneInto(
                textures=self.textures, auxbits=auxbits)
            if self.finalQuad == None:
                self.cleanup()
                return False
            if 'BlurSharpen' in configuration:
                blur0 = self.textures['blur0']
                blur1 = self.textures['blur1']
                self.blur.append(
                    self.manager.renderQuadInto(colortex=blur0, div=2))
                self.blur.append(self.manager.renderQuadInto(colortex=blur1))
                self.blur[0].setShaderInput('src', self.textures['color'])
                self.blur[0].setShader(self.loadShader('filter-blurx.sha'))
                self.blur[1].setShaderInput('src', blur0)
                self.blur[1].setShader(self.loadShader('filter-blury.sha'))
            if 'AmbientOcclusion' in configuration:
                ssao0 = self.textures['ssao0']
                ssao1 = self.textures['ssao1']
                ssao2 = self.textures['ssao2']
                self.ssao.append(self.manager.renderQuadInto(colortex=ssao0))
                self.ssao.append(
                    self.manager.renderQuadInto(colortex=ssao1, div=2))
                self.ssao.append(self.manager.renderQuadInto(colortex=ssao2))
                self.ssao[0].setShaderInput('depth', self.textures['depth'])
                self.ssao[0].setShaderInput('normal', self.textures['aux'])
                self.ssao[0].setShaderInput(
                    'random', loader.loadTexture('maps/random.rgb'))
                self.ssao[0].setShader(
                    Shader.make(
                        SSAO_BODY %
                        configuration['AmbientOcclusion'].numsamples,
                        Shader.SL_Cg))
                self.ssao[1].setShaderInput('src', ssao0)
                self.ssao[1].setShader(self.loadShader('filter-blurx.sha'))
                self.ssao[2].setShaderInput('src', ssao1)
                self.ssao[2].setShader(self.loadShader('filter-blury.sha'))
            if 'Bloom' in configuration:
                bloomconf = configuration['Bloom']
                bloom0 = self.textures['bloom0']
                bloom1 = self.textures['bloom1']
                bloom2 = self.textures['bloom2']
                bloom3 = self.textures['bloom3']
                if bloomconf.size == 'large':
                    scale = 8
                    downsampler = 'filter-down4.sha'
                else:
                    if bloomconf.size == 'medium':
                        scale = 4
                        downsampler = 'filter-copy.sha'
                    else:
                        scale = 2
                        downsampler = 'filter-copy.sha'
                self.bloom.append(
                    self.manager.renderQuadInto(colortex=bloom0,
                                                div=2,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto(colortex=bloom1,
                                                div=scale,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto(colortex=bloom2,
                                                div=scale,
                                                align=scale))
                self.bloom.append(
                    self.manager.renderQuadInto(colortex=bloom3,
                                                div=scale,
                                                align=scale))
                self.bloom[0].setShaderInput('src', self.textures['color'])
                self.bloom[0].setShader(self.loadShader('filter-bloomi.sha'))
                self.bloom[1].setShaderInput('src', bloom0)
                self.bloom[1].setShader(self.loadShader(downsampler))
                self.bloom[2].setShaderInput('src', bloom1)
                self.bloom[2].setShader(self.loadShader('filter-bloomx.sha'))
                self.bloom[3].setShaderInput('src', bloom2)
                self.bloom[3].setShader(self.loadShader('filter-bloomy.sha'))
            texcoords = {}
            texcoordPadding = {}
            for tex in needtexcoord:
                if self.textures[tex].getAutoTextureScale(
                ) != ATSNone or 'HalfPixelShift' in configuration:
                    texcoords[tex] = 'l_texcoord_' + tex
                    texcoordPadding['l_texcoord_' + tex] = tex
                else:
                    texcoords[tex] = 'l_texcoord'
                    texcoordPadding['l_texcoord'] = None

            texcoordSets = list(enumerate(texcoordPadding.keys()))
            text = '//Cg\n'
            text += 'void vshader(float4 vtx_position : POSITION,\n'
            text += '  out float4 l_position : POSITION,\n'
            for texcoord, padTex in texcoordPadding.items():
                if padTex is not None:
                    text += '  uniform float4 texpad_tx%s,\n' % padTex
                    if 'HalfPixelShift' in configuration:
                        text += '  uniform float4 texpix_tx%s,\n' % padTex

            for i, name in texcoordSets:
                text += '  out float2 %s : TEXCOORD%d,\n' % (name, i)

            text += '  uniform float4x4 mat_modelproj)\n'
            text += '{\n'
            text += '  l_position = mul(mat_modelproj, vtx_position);\n'
            for texcoord, padTex in texcoordPadding.items():
                if padTex is None:
                    text += '  %s = vtx_position.xz * float2(0.5, 0.5) + float2(0.5, 0.5);\n' % texcoord
                else:
                    text += '  %s = (vtx_position.xz * texpad_tx%s.xy) + texpad_tx%s.xy;\n' % (
                        texcoord, padTex, padTex)
                    if 'HalfPixelShift' in configuration:
                        text += '  %s += texpix_tx%s.xy * 0.5;\n' % (texcoord,
                                                                     padTex)

            text += '}\n'
            text += 'void fshader(\n'
            for i, name in texcoordSets:
                text += '  float2 %s : TEXCOORD%d,\n' % (name, i)

            for key in self.textures:
                text += '  uniform sampler2D k_tx' + key + ',\n'

            if 'CartoonInk' in configuration:
                text += '  uniform float4 k_cartoonseparation,\n'
                text += '  uniform float4 k_cartooncolor,\n'
                text += '  uniform float4 texpix_txaux,\n'
            if 'BlurSharpen' in configuration:
                text += '  uniform float4 k_blurval,\n'
            if 'VolumetricLighting' in configuration:
                text += '  uniform float4 k_casterpos,\n'
                text += '  uniform float4 k_vlparams,\n'
            text += '  out float4 o_color : COLOR)\n'
            text += '{\n'
            text += '  o_color = tex2D(k_txcolor, %s);\n' % texcoords['color']
            if 'CartoonInk' in configuration:
                text += CARTOON_BODY % {'texcoord': texcoords['aux']}
            if 'AmbientOcclusion' in configuration:
                text += '  o_color *= tex2D(k_txssao2, %s).r;\n' % texcoords[
                    'ssao2']
            if 'BlurSharpen' in configuration:
                text += '  o_color = lerp(tex2D(k_txblur1, %s), o_color, k_blurval.x);\n' % texcoords[
                    'blur1']
            if 'Bloom' in configuration:
                text += '  o_color = saturate(o_color);\n'
                text += '  float4 bloom = 0.5 * tex2D(k_txbloom3, %s);\n' % texcoords[
                    'bloom3']
                text += '  o_color = 1-((1-bloom)*(1-o_color));\n'
            if 'ViewGlow' in configuration:
                text += '  o_color.r = o_color.a;\n'
            if 'VolumetricLighting' in configuration:
                text += '  float decay = 1.0f;\n'
                text += '  float2 curcoord = %s;\n' % texcoords['color']
                text += '  float2 lightdir = curcoord - k_casterpos.xy;\n'
                text += '  lightdir *= k_vlparams.x;\n'
                text += '  half4 sample = tex2D(k_txcolor, curcoord);\n'
                text += '  float3 vlcolor = sample.rgb * sample.a;\n'
                text += '  for (int i = 0; i < %s; i++) {\n' % int(
                    configuration['VolumetricLighting'].numsamples)
                text += '    curcoord -= lightdir;\n'
                text += '    sample = tex2D(k_tx%s, curcoord);\n' % configuration[
                    'VolumetricLighting'].source
                text += '    sample *= sample.a * decay;//*weight\n'
                text += '    vlcolor += sample.rgb;\n'
                text += '    decay *= k_vlparams.y;\n'
                text += '  }\n'
                text += '  o_color += float4(vlcolor * k_vlparams.z, 1);\n'
            if 'GammaAdjust' in configuration:
                gamma = configuration['GammaAdjust']
                if gamma == 0.5:
                    text += '  o_color.rgb = sqrt(o_color.rgb);\n'
                elif gamma == 2.0:
                    text += '  o_color.rgb *= o_color.rgb;\n'
                elif gamma != 1.0:
                    text += '  o_color.rgb = pow(o_color.rgb, %ff);\n' % gamma
            if 'Inverted' in configuration:
                text += '  o_color = float4(1, 1, 1, 1) - o_color;\n'
            text += '}\n'
            self.finalQuad.setShader(Shader.make(text, Shader.SL_Cg))
            for tex in self.textures:
                self.finalQuad.setShaderInput('tx' + tex, self.textures[tex])

            self.task = taskMgr.add(self.update, 'common-filters-update')
        if changed == 'CartoonInk' or fullrebuild:
            if 'CartoonInk' in configuration:
                c = configuration['CartoonInk']
                self.finalQuad.setShaderInput(
                    'cartoonseparation',
                    LVecBase4(c.separation, 0, c.separation, 0))
                self.finalQuad.setShaderInput('cartooncolor', c.color)
        if changed == 'BlurSharpen' or fullrebuild:
            if 'BlurSharpen' in configuration:
                blurval = configuration['BlurSharpen']
                self.finalQuad.setShaderInput(
                    'blurval', LVecBase4(blurval, blurval, blurval, blurval))
        if changed == 'Bloom' or fullrebuild:
            if 'Bloom' in configuration:
                bloomconf = configuration['Bloom']
                intensity = bloomconf.intensity * 3.0
                self.bloom[0].setShaderInput('blend', bloomconf.blendx,
                                             bloomconf.blendy,
                                             bloomconf.blendz,
                                             bloomconf.blendw * 2.0)
                self.bloom[0].setShaderInput(
                    'trigger', bloomconf.mintrigger,
                    1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0,
                    0.0)
                self.bloom[0].setShaderInput('desat', bloomconf.desat)
                self.bloom[3].setShaderInput('intensity', intensity, intensity,
                                             intensity, intensity)
        if changed == 'VolumetricLighting' or fullrebuild:
            if 'VolumetricLighting' in configuration:
                config = configuration['VolumetricLighting']
                tcparam = config.density / float(config.numsamples)
                self.finalQuad.setShaderInput('vlparams', tcparam,
                                              config.decay, config.exposure,
                                              0.0)
        if changed == 'AmbientOcclusion' or fullrebuild:
            if 'AmbientOcclusion' in configuration:
                config = configuration['AmbientOcclusion']
                self.ssao[0].setShaderInput(
                    'params1', config.numsamples,
                    -float(config.amount) / config.numsamples, config.radius,
                    0)
                self.ssao[0].setShaderInput('params2', config.strength,
                                            config.falloff, 0, 0)
        self.update()
        return True
Exemple #37
0
 def create_default_texture(self):
     image = self.create_default_image()
     texture = Texture()
     texture.load(image)
     return (texture, 0, 0)
Exemple #38
0
    def __init__(self):
        load_prc_file_data(
            "", """
            textures-power-2 none
            window-type offscreen
            win-size 100 100
            gl-coordinate-system default
            notify-level-display error
            print-pipe-types #f
            gl-version 4 3
        """)

        ShowBase.__init__(self)

        dest_tex = Texture()
        dest_tex.setup_2d_texture(2048, 2048, Texture.T_unsigned_byte,
                                  Texture.F_rgba8)
        cshader = Shader.load_compute(Shader.SL_GLSL, "grain.compute.glsl")
        node = NodePath("")
        node.set_shader(cshader)
        node.set_shader_input("DestTex", dest_tex)
        attr = node.get_attrib(ShaderAttrib)
        self.graphicsEngine.dispatch_compute((2048 // 16, 2048 // 16, 1), attr,
                                             self.win.gsg)

        base.graphicsEngine.extract_texture_data(dest_tex, base.win.gsg)

        # Convert to single channel
        img = PNMImage(2048, 2048, 1, 255)
        dest_tex.store(img)
        img.set_num_channels(1)

        tex = Texture()
        tex.load(img)
        tex.write("grain.txo.pz")
Exemple #39
0
    def updateTexture(self, main):
        dir_node = getNode('/config/directories', True)

        # reset base textures
        for i, m in enumerate(self.models):
            if m != main:
                if m.getName() in tcache:
                    fulltex = tcache[m.getName()][1]
                    self.models[i].setTexture(fulltex, 1)
                else:
                    if self.base_textures[i] != None:
                        self.models[i].setTexture(self.base_textures[i], 1)
            else:
                print(m.getName())
                if m.getName() in tcache:
                    fulltex = tcache[m.getName()][1]
                    self.models[i].setTexture(fulltex, 1)
                    continue
                base, ext = os.path.splitext(m.getName())
                image_file = None
                search = [args.project, os.path.join(args.project, 'images')]
                for dir in search:
                    tmp1 = os.path.join(dir, base + '.JPG')
                    tmp2 = os.path.join(dir, base + '.jpg')
                    if os.path.isfile(tmp1):
                        image_file = tmp1
                    elif os.path.isfile(tmp2):
                        image_file = tmp2
                if not image_file:
                    print(
                        'Warning: no full resolution image source file found:',
                        base)
                else:
                    if True:
                        # example of passing an opencv image as a
                        # panda texture
                        print(base, image_file)
                        #image = proj.findImageByName(base)
                        #print(image)
                        rgb = cv2.imread(image_file,
                                         flags=cv2.IMREAD_ANYCOLOR
                                         | cv2.IMREAD_ANYDEPTH
                                         | cv2.IMREAD_IGNORE_ORIENTATION)
                        rgb = np.flipud(rgb)
                        # vignette correction
                        if not self.vignette_mask is None:
                            rgb = rgb.astype('uint16') + self.vignette_mask
                            rgb = np.clip(rgb, 0, 255).astype('uint8')

                        h, w = rgb.shape[:2]
                        print('shape: (%d,%d)' % (w, h))
                        rescale = False
                        if h > self.max_texture_dimension:
                            h = self.max_texture_dimension
                            rescale = True
                        if w > self.max_texture_dimension:
                            w = self.max_texture_dimension
                            rescale = True
                        if self.needs_pow2:
                            h2 = 2**math.floor(math.log(h, 2))
                            w2 = 2**math.floor(math.log(w, 2))
                            if h2 != h:
                                h = h2
                                rescale = True
                            if w2 != w:
                                w = w2
                                rescale = True
                        if rescale:
                            print(
                                "Notice: rescaling texture to (%d,%d) to honor video card capability."
                                % (w, h))
                            rgb = cv2.resize(rgb, (w, h))

                        # filter_by = 'none'
                        filter_by = 'equalize_value'
                        # filter_by = 'equalize_rgb'
                        # filter_by = 'equalize_blue'
                        # filter_by = 'equalize_green'
                        # filter_by = 'equalize_blue'
                        # filter_by = 'equalize_red'
                        # filter_by = 'red/green'
                        if filter_by == 'none':
                            b, g, r = cv2.split(rgb)
                            result = cv2.merge((b, g, r))
                        if filter_by == 'equalize_value':
                            # equalize val (essentially gray scale level)
                            hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV)
                            hue, sat, val = cv2.split(hsv)
                            aeq = clahe.apply(val)
                            # recombine
                            hsv = cv2.merge((hue, sat, aeq))
                            # convert back to rgb
                            result = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
                        elif filter_by == 'equalize_rgb':
                            # equalize individual b, g, r channels
                            b, g, r = cv2.split(rgb)
                            b = clahe.apply(b)
                            g = clahe.apply(g)
                            r = clahe.apply(r)
                            result = cv2.merge((b, g, r))
                        elif filter_by == 'equalize_blue':
                            # equalize val (essentially gray scale level)
                            hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV)
                            hue, sat, val = cv2.split(hsv)
                            # blue hue = 120

                            # slide 120 -> 90 (center of 0-180 range
                            # with mod() roll over)
                            diff = np.mod(hue.astype('float64') - 30, 180)
                            # move this center point to 0 (-90 to +90
                            # range) and take absolute value
                            # (distance)
                            diff = np.abs(diff - 90)
                            # scale to 0 to 1 (1 being the closest to
                            # our target hue)
                            diff = 1.0 - diff / 90
                            print('hue:', np.amin(hue), np.amax(hue))
                            print('sat:', np.amin(sat), np.amax(sat))
                            print('diff:', np.amin(diff), np.amax(diff))
                            #print(diff)
                            #g = (256 - (256.0/90.0)*diff).astype('uint8')
                            b = (diff * sat).astype('uint8')
                            g = np.zeros(hue.shape, dtype='uint8')
                            r = np.zeros(hue.shape, dtype='uint8')
                            #g = clahe.apply(g)
                            result = cv2.merge((b, g, r))
                            print(result.shape, result.dtype)
                        elif filter_by == 'equalize_green':
                            # equalize val (essentially gray scale level)
                            hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV)
                            hue, sat, val = cv2.split(hsv)
                            # green hue = 60

                            # slide 60 -> 90 (center of 0-180 range
                            # with mod() roll over)
                            diff = np.mod(hue.astype('float64') + 30, 180)
                            # move this center point to 0 (-90 to +90
                            # range) and take absolute value
                            # (distance)
                            diff = np.abs(diff - 90)
                            # scale to 0 to 1 (1 being the closest to
                            # our target hue)
                            diff = 1.0 - diff / 90
                            print('hue:', np.amin(hue), np.amax(hue))
                            print('sat:', np.amin(sat), np.amax(sat))
                            print('diff:', np.amin(diff), np.amax(diff))
                            #print(diff)
                            b = np.zeros(hue.shape, dtype='uint8')
                            g = (diff * sat).astype('uint8')
                            r = np.zeros(hue.shape, dtype='uint8')
                            #g = clahe.apply(g)
                            result = cv2.merge((b, g, r))
                            print(result.shape, result.dtype)
                        elif filter_by == 'equalize_red':
                            # equalize val (essentially gray scale level)
                            hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV)
                            hue, sat, val = cv2.split(hsv)
                            # red hue = 0

                            # slide 0 -> 90 (center of 0-180 range
                            # with mod() roll over)
                            diff = np.mod(hue.astype('float64') + 90, 180)
                            # move this center point to 0 (-90 to +90
                            # range) and take absolute value
                            # (distance)
                            diff = np.abs(diff - 90)
                            # scale to 0 to 1 (1 being the closest to
                            # our target hue)
                            diff = 1.0 - diff / 90
                            print('hue:', np.amin(hue), np.amax(hue))
                            print('sat:', np.amin(sat), np.amax(sat))
                            print('diff:', np.amin(diff), np.amax(diff))
                            b = np.zeros(hue.shape, dtype='uint8')
                            g = np.zeros(hue.shape, dtype='uint8')
                            r = (diff * sat).astype('uint8')
                            result = cv2.merge((b, g, r))
                            print(result.shape, result.dtype)
                        elif filter_by == 'red/green':
                            # equalize val (essentially gray scale level)
                            max = 4.0
                            b, g, r = cv2.split(rgb)
                            ratio = r / (g.astype('float64') + 1.0)
                            ratio = np.clip(ratio, 0, max)
                            inv = g / (r.astype('float64') + 1.0)
                            inv = np.clip(inv, 0, max)
                            max_ratio = np.amax(ratio)
                            max_inv = np.amax(inv)
                            print(max_ratio, max_inv)
                            b[:] = 0
                            g = (inv * (255 / max)).astype('uint8')
                            r = (ratio * (255 / max)).astype('uint8')
                            result = cv2.merge((b, g, r))
                            print(result.shape, result.dtype)

                        fulltex = Texture(base)
                        fulltex.setCompression(Texture.CMOff)
                        fulltex.setup2dTexture(w, h, Texture.TUnsignedByte,
                                               Texture.FRgb)
                        fulltex.setRamImage(result)
                        # fulltex.load(rgb) # for loading a pnm image
                        fulltex.setWrapU(Texture.WM_clamp)
                        fulltex.setWrapV(Texture.WM_clamp)
                        m.setTexture(fulltex, 1)
                        tcache[m.getName()] = [m, fulltex, time.time()]
                    else:
                        print(image_file)
                        fulltex = self.loader.loadTexture(image_file)
                        fulltex.setWrapU(Texture.WM_clamp)
                        fulltex.setWrapV(Texture.WM_clamp)
                        #print('fulltex:', fulltex)
                        m.setTexture(fulltex, 1)
                        tcache[m.getName()] = [m, fulltex, time.time()]
        cachesize = 10
        while len(tcache) > cachesize:
            oldest_time = time.time()
            oldest_name = ""
            for name in tcache:
                if tcache[name][2] < oldest_time:
                    oldest_time = tcache[name][2]
                    oldest_name = name
            del tcache[oldest_name]
Exemple #40
0
class TextureHeightmapBase(Heightmap):
    def __init__(self, name, width, height, height_scale, u_scale, v_scale,
                 median, interpolator):
        Heightmap.__init__(self, name, width, height, height_scale, u_scale,
                           v_scale, median, interpolator)
        self.texture = None
        self.texture_offset = LVector2()
        self.texture_scale = LVector2(1, 1)
        self.tex_id = str(width) + ':' + str(height)

    def reset(self):
        self.texture = None

    def get_texture_offset(self, patch):
        return self.texture_offset

    def get_texture_scale(self, patch):
        return self.texture_scale

        return self.heightmap_ready

    def set_height(self, x, y, height):
        pass

    def get_height(self, x, y):
        if self.texture_peeker is None:
            print("No peeker")
            traceback.print_stack()
            return 0.0
        new_x = x * self.texture_scale[0] + self.texture_offset[0] * self.width
        new_y = y * self.texture_scale[1] + self.texture_offset[1] * self.height
        new_x = min(new_x, self.width - 1)
        new_y = min(new_y, self.height - 1)
        height = self.interpolator.get_value(self.texture_peeker, new_x, new_y)
        return height * self.height_scale  # + self.offset

    def create_heightmap(self, shape, callback=None, cb_args=()):
        return self.load(shape, callback, cb_args)

    def load(self, shape, callback, cb_args=()):
        if self.texture is None:
            self.texture = Texture()
            self.texture.set_wrap_u(Texture.WMClamp)
            self.texture.set_wrap_v(Texture.WMClamp)
            self.interpolator.configure_texture(self.texture)
            self.do_load(shape, self.heightmap_ready_cb, (callback, cb_args))
        else:
            if callback is not None:
                callback(self, *cb_args)

    def heightmap_ready_cb(self, texture, callback, cb_args):
        #print("READY", self.patch.str_id())
        self.texture_peeker = self.texture.peek()
        #         if self.texture_peeker is None:
        #             print("NOT READY !!!")
        self.heightmap_ready = True
        data = self.texture.getRamImage()
        if sys.version_info[0] < 3:
            buf = data.getData()
            np_buffer = numpy.fromstring(buf, dtype=numpy.float32)
        else:
            np_buffer = numpy.frombuffer(data, numpy.float32)
        np_buffer.shape = (self.texture.getYSize(), self.texture.getXSize(),
                           self.texture.getNumComponents())
        self.min_height = np_buffer.min()
        self.max_height = np_buffer.max()
        self.mean_height = np_buffer.mean()
        if callback is not None:
            callback(self, *cb_args)

    def do_load(self, shape, callback, cb_args):
        pass
Exemple #41
0
    def __init__(self):
        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)

        self.disableMouse()
        self.camera.setPos(0, -26, 4)
        self.setBackgroundColor(0, 0, 0)

        # Create a texture into which we can copy the main window.
        # We set it to RTMTriggeredCopyTexture mode, which tells it that we
        # want it to copy the window contents into a texture every time we
        # call self.win.triggerCopy().
        self.tex = Texture()
        self.tex.setMinfilter(Texture.FTLinear)
        self.win.addRenderTexture(self.tex,
                                  GraphicsOutput.RTMTriggeredCopyTexture)

        # Set the initial color to clear the texture to, before rendering it.
        # This is necessary because we don't clear the texture while rendering,
        # and otherwise the user might see garbled random data from GPU memory.
        self.tex.setClearColor((0, 0, 0, 1))
        self.tex.clearImage()

        # Create another 2D camera. Tell it to render before the main camera.
        self.backcam = self.makeCamera2d(self.win, sort=-10)
        self.background = NodePath("background")
        self.backcam.reparentTo(self.background)
        self.background.setDepthTest(0)
        self.background.setDepthWrite(0)
        self.backcam.node().getDisplayRegion(0).setClearDepthActive(0)

        # Obtain two texture cards. One renders before the dragon, the other
        # after.
        self.bcard = self.win.getTextureCard()
        self.bcard.reparentTo(self.background)
        self.bcard.setTransparency(1)
        self.fcard = self.win.getTextureCard()
        self.fcard.reparentTo(self.render2d)
        self.fcard.setTransparency(1)

        # Initialize one of the nice effects.
        self.chooseEffectGhost()

        # Add the task that initiates the screenshots.
        taskMgr.add(self.takeSnapShot, "takeSnapShot")

        # Create some black squares on top of which we will
        # place the instructions.
        blackmaker = CardMaker("blackmaker")
        blackmaker.setColor(0, 0, 0, 1)
        blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00)
        instcard = NodePath(blackmaker.generate())
        instcard.reparentTo(self.render2d)
        blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85)
        titlecard = NodePath(blackmaker.generate())
        titlecard.reparentTo(self.render2d)

        # Panda does its best to hide the differences between DirectX and
        # OpenGL.  But there are a few differences that it cannot hide.
        # One such difference is that when OpenGL copies from a
        # visible window to a texture, it gets it right-side-up.  When
        # DirectX does it, it gets it upside-down.  There is nothing panda
        # can do to compensate except to expose a flag and let the
        # application programmer deal with it.  You should only do this
        # in the rare event that you're copying from a visible window
        # to a texture.
        if self.win.getGsg().getCopyTextureInverted():
            print("Copy texture is inverted.")
            self.bcard.setScale(1, 1, -1)
            self.fcard.setScale(1, 1, -1)

        # Put up the instructions
        title = OnscreenText(text="Panda3D: Tutorial - Motion Trails",
                             fg=(1, 1, 1, 1),
                             parent=base.a2dBottomCenter,
                             pos=(0, 0.1),
                             scale=.08)

        instr0 = addInstructions(0.06, "Press ESC to exit")
        instr1 = addInstructions(0.12, "Press 1: Ghost effect")
        instr2 = addInstructions(0.18, "Press 2: PaintBrush effect")
        instr3 = addInstructions(0.24, "Press 3: Double Vision effect")
        instr4 = addInstructions(0.30, "Press 4: Wings of Blue effect")
        instr5 = addInstructions(0.36, "Press 5: Whirlpool effect")

        # Enable the key events
        self.accept("escape", sys.exit, [0])
        self.accept("1", self.chooseEffectGhost)
        self.accept("2", self.chooseEffectPaintBrush)
        self.accept("3", self.chooseEffectDoubleVision)
        self.accept("4", self.chooseEffectWingsOfBlue)
        self.accept("5", self.chooseEffectWhirlpool)
Exemple #42
0
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        # Load the environment model.
        self.setup_environment()
        #self.scene = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        #self.scene.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        #self.scene.setScale(0.25, 0.25, 0.25)
        #self.scene.setPos(-8, 42, 0)

        # Needed for camera image
        self.dr = self.camNode.getDisplayRegion(0)

        # Needed for camera depth image
        winprops = WindowProperties.size(self.win.getXSize(),
                                         self.win.getYSize())
        fbprops = FrameBufferProperties()
        fbprops.setDepthBits(1)
        self.depthBuffer = self.graphicsEngine.makeOutput(
            self.pipe, "depth buffer", -2, fbprops, winprops,
            GraphicsPipe.BFRefuseWindow, self.win.getGsg(), self.win)
        self.depthTex = Texture()
        self.depthTex.setFormat(Texture.FDepthComponent)
        self.depthBuffer.addRenderTexture(self.depthTex,
                                          GraphicsOutput.RTMCopyRam,
                                          GraphicsOutput.RTPDepth)
        lens = self.cam.node().getLens()
        lens.setFov(90.0, 90.0)
        # the near and far clipping distances can be changed if desired
        # lens.setNear(5.0)
        # lens.setFar(500.0)
        self.depthCam = self.makeCamera(self.depthBuffer,
                                        lens=lens,
                                        scene=self.render)
        self.depthCam.reparentTo(self.cam)

        # TODO: Scene is rendered twice: once for rgb and once for depth image.
        # How can both images be obtained in one rendering pass?
        self.render.setAntialias(AntialiasAttrib.MAuto)

    def setup_environment(self):
        # encapsulate some stuff

        # set up ambient lighting
        self.alight = AmbientLight('alight')
        self.alight.setColor(VBase4(0.1, 0.1, 0.1, 1))
        self.alnp = self.render.attachNewNode(self.alight)
        self.render.setLight(self.alnp)

        # set up a point light
        self.plight = PointLight('plight')
        self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1))
        self.plnp = self.render.attachNewNode(self.plight)
        self.plnp.setPos(0, 0, 100)
        self.render.setLight(self.plnp)

        # set up terrain model
        self.terr_material = Material()
        self.terr_material.setShininess(1.0)
        self.terr_material.setAmbient(VBase4(0, 0, 0, 0))
        self.terr_material.setDiffuse(VBase4(1, 1, 1, 1))
        self.terr_material.setEmission(VBase4(0, 0, 0, 0))
        self.terr_material.setSpecular(VBase4(0, 0, 0, 0))

        # general scaling
        self.trrHorzSc = 4.0
        self.trrVertSc = 4.0  # was 4.0

        # Create sky
        #terrctr = self.trrHorzSc*65.0
        #self.setup_skybox(terrctr,800.0,2.0,0.3)

        self.skysphere = self.loader.loadModel("sky-forest/SkySphere.bam")
        self.skysphere.setBin('background', 1)
        self.skysphere.setDepthWrite(0)
        self.skysphere.reparentTo(self.render)

        # Load some textures
        self.grsTxtSc = 5
        self.numTreeTexts = 7

        # ground texture
        self.txtGrass = self.loader.loadTexture('tex/ground005.png')
        self.txtGrass.setWrapU(Texture.WM_mirror)
        self.txtGrass.setWrapV(Texture.WM_mirror)
        self.txtGrass.setMagfilter(Texture.FTLinear)
        self.txtGrass.setMinfilter(Texture.FTLinearMipmapLinear)

        # set up terrain texture stages
        self.TS1 = TextureStage('terrtext')
        self.TS1.setSort(0)
        self.TS1.setMode(TextureStage.MReplace)

        # Set up the GeoMipTerrain
        self.terrain = GeoMipTerrain("myDynamicTerrain")
        img = PNMImage(Filename('tex/bowl_height_map.png'))
        self.terrain.setHeightfield(img)
        self.terrain.setBruteforce(0)
        self.terrain.setAutoFlatten(GeoMipTerrain.AFMMedium)

        # Set terrain properties
        self.terrain.setBlockSize(32)
        self.terrain.setNear(50)
        self.terrain.setFar(500)
        self.terrain.setFocalPoint(self.camera)

        # Store the root NodePath for convenience
        self.root = self.terrain.getRoot()
        self.root.clearTexture()
        self.root.setTwoSided(0)
        self.root.setCollideMask(BitMask32.bit(0))
        self.root.setSz(self.trrVertSc)
        self.root.setSx(self.trrHorzSc)
        self.root.setSy(self.trrHorzSc)
        self.root.setMaterial(self.terr_material)
        self.root.setTexture(self.TS1, self.txtGrass)
        self.root.setTexScale(self.TS1, self.grsTxtSc, self.grsTxtSc)
        offset = 0.5 * img.getXSize() * self.trrHorzSc - 0.5
        self.root.setPos(-offset, -offset, 0)

        self.terrain.generate()
        self.root.reparentTo(self.render)

        # load tree billboards
        self.txtTreeBillBoards = []
        for a in range(self.numTreeTexts):
            fstr = 'trees/tree' + '%03d' % (a + 991)
            self.txtTreeBillBoards.append( \
                self.loader.loadTexture(fstr + '-color.png', fstr + '-opacity.png'))
            self.txtTreeBillBoards[a].setMinfilter(
                Texture.FTLinearMipmapLinear)

        #self.placePlantOnTerrain('trees',300,0,20,20,self.trrHorzSc,self.trrVertSc, \
        #    self.numTreeTexts,self.txtTreeBillBoards,'scene-def/trees.txt')
        self.setup_house()
        self.setup_vehicle()

        self.taskMgr.add(self.skysphereTask, "SkySphere Task")

    def setup_house(self):
        # place farmhouse on terrain
        self.house = ModelNode('house1')
        self.loadModelOntoTerrain(self.render, self.terrain, self.house, 43.0,
                                  0.275, 0.0, 0.0, self.trrHorzSc,
                                  self.trrVertSc, 'models/FarmHouse',
                                  Vec3(0, 0, 0),
                                  Point3(-12.0567, -29.1724, 0.0837742),
                                  Point3(12.2229, 21.1915, 21.3668))

    def setup_vehicle(self):
        # place HMMWV on terrain
        self.hmmwv = ModelNode('hmmwv1')
        self.loadModelOntoTerrain(self.render, self.terrain, self.hmmwv, 33.0,
                                  1.0, 20.0, 24.0, self.trrHorzSc,
                                  self.trrVertSc, 'models/hmmwv',
                                  Vec3(0, -90, 0),
                                  Point3(-1.21273, -2.49153, -1.10753),
                                  Point3(1.21273, 2.49153, 1.10753))

    def setup_skybox(self,
                     terrctr=645.0,
                     boxsz=1000.0,
                     aspect=1.0,
                     uplift=0.0):
        vsz = boxsz / aspect
        self.bckgtx = []
        self.bckgtx.append(self.loader.loadTexture('sky/Back2.png'))
        self.bckgtx.append(self.loader.loadTexture('sky/Right2.png'))
        self.bckgtx.append(self.loader.loadTexture('sky/Front2.png'))
        self.bckgtx.append(self.loader.loadTexture('sky/Left2.png'))
        self.bckgtx.append(self.loader.loadTexture('sky/Up.png'))
        for a in range(4):
            self.bckg = CardMaker('bkcard')
            lr = Point3(0.5 * boxsz, 0.5 * boxsz, -0.5 * vsz)
            ur = Point3(0.5 * boxsz, 0.5 * boxsz, 0.5 * vsz)
            ul = Point3(-0.5 * boxsz, 0.5 * boxsz, 0.5 * vsz)
            ll = Point3(-0.5 * boxsz, 0.5 * boxsz, -0.5 * vsz)
            self.bckg.setFrame(ll, lr, ur, ul)
            self.bckg.setHasNormals(0)
            self.bckg.setHasUvs(1)
            #self.bckg.setUvRange(self.bckgtx[a])
            bkcrd = self.render.attachNewNode(self.bckg.generate())
            bkcrd.setTexture(self.bckgtx[a])
            self.bckgtx[a].setWrapU(Texture.WMClamp)
            self.bckgtx[a].setWrapV(Texture.WMClamp)
            bkcrd.setLightOff()
            bkcrd.setFogOff()
            bkcrd.setHpr(90.0 * a, 0, 0)
            cz = 0.5 * boxsz * uplift
            #print 'set card at:', terrctr,terrctr,cz, ' with points: ', lr,ur,ul,ll
            bkcrd.setPos(terrctr, terrctr, cz)
            self.top = CardMaker('bkcard')
            lr = Point3(0.5 * boxsz, -0.5 * boxsz, 0)
            ur = Point3(0.5 * boxsz, 0.5 * boxsz, 0)
            ul = Point3(-0.5 * boxsz, 0.5 * boxsz, 0)
            ll = Point3(-0.5 * boxsz, -0.5 * boxsz, 0)
            self.top.setFrame(ll, lr, ur, ul)
            self.top.setHasNormals(0)
            self.top.setHasUvs(1)
            #self.top.setUvRange(self.bckgtx[4])
            bkcrd = self.render.attachNewNode(self.bckg.generate())
            bkcrd.setTexture(self.bckgtx[4])
            self.bckgtx[4].setWrapU(Texture.WMClamp)
            self.bckgtx[4].setWrapV(Texture.WMClamp)
            bkcrd.setLightOff()
            bkcrd.setFogOff()
            bkcrd.setHpr(0, 90, 90)
            bkcrd.setPos(terrctr, terrctr, 0.5 * vsz + 0.5 * boxsz * uplift)

    def placePlantOnTerrain(self, itemStr, itemCnt, Mode, typItemWidth,
                            typItemHeight, trrHorzSc, trrVertSc, numTxtTypes,
                            txtList, planFileName):
        # Billboarding plants
        crd = CardMaker('mycard')
        crd.setColor(0.5, 0.5, 0.5, 1)
        ll = Point3(-0.5 * typItemWidth, 0, 0)
        lr = Point3(0.5 * typItemWidth, 0, 0)
        ur = Point3(0.5 * typItemWidth, 0, typItemHeight)
        ul = Point3(-0.5 * typItemWidth, 0, typItemHeight)
        crd.setFrame(ll, lr, ur, ul)
        crd.setHasNormals(False)
        crd.setHasUvs(True)
        # generate/save/load locations
        try:
            plan_data_fp = open(planFileName, 'r')
            item_list = []
            for line in plan_data_fp:
                toks = line.split(',')
                px = float(toks[0].strip(' '))
                py = float(toks[1].strip(' '))
                ang = float(toks[2].strip(' '))
                dht = float(toks[3].strip(' '))
                scl = float(toks[4].strip(' '))
                idx = int(toks[5].strip(' '))
                item_list.append((px, py, ang, dht, scl, idx))
            plan_data_fp.close()
            print 'loaded ', itemStr, ' data file of size:', len(item_list)
        except IOError:
            # generate list and try to save
            item_list = []
            for a in range(itemCnt):
                px = random.randrange(-self.trrHorzSc * 64,
                                      self.trrHorzSc * 64)
                py = random.randrange(-self.trrHorzSc * 64,
                                      self.trrHorzSc * 64)
                ang = 180 * random.random()
                dht = 0.0
                scl = 0.75 + 0.25 * (random.random() + random.random())
                idx = random.randrange(0, numTxtTypes)
                item_list.append([px, py, ang, dht, scl, idx])
            try:
                plan_data_fp = open(planFileName, 'w')
                for c in item_list:
                    print >> plan_data_fp, c[0], ',', c[1], ',', c[2], ',', c[
                        3], ',', c[4], ',', c[5]
                plan_data_fp.close()
                print 'saved ', itemStr, ' data of size: ', len(item_list)
            except IOError:
                print 'unable to store ', itemStr, ' data of size: ', len(
                    item_list)
        # define each plant
        for c in item_list:
            px = c[0]
            py = c[1]
            ang = c[2]
            dht = c[3]
            scl = c[4]
            idx = c[5]
            if idx >= numTxtTypes:
                idx = 0
            if Mode > 0:
                for b in range(Mode):
                    crdNP = self.render.attachNewNode(crd.generate())
                    crdNP.setTexture(txtList[idx])
                    crdNP.setScale(scl)
                    crdNP.setTwoSided(True)
                    ht = self.terrain.getElevation(px / trrHorzSc,
                                                   py / trrHorzSc)
                    crdNP.setPos(px, py, ht * trrVertSc + dht)
                    crdNP.setHpr(ang + (180 / Mode) * b, 0, 0)
                    crdNP.setTransparency(TransparencyAttrib.MAlpha)
                    crdNP.setLightOff()
            else:
                # set up item as defined
                crd.setUvRange(txtList[idx])
                crdNP = self.render.attachNewNode(crd.generate())
                crdNP.setBillboardAxis()
                crdNP.setTexture(txtList[idx])
                crdNP.setScale(scl)
                ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc)
                crdNP.setPos(px, py, ht * trrVertSc)
                crdNP.setTransparency(TransparencyAttrib.MAlpha)
                crdNP.setLightOff()

    def loadModelOntoTerrain(self, render_node, terr_obj, model_obj, hdg, scl,
                             xctr, yctr, terr_horz_sc, terr_vert_sc,
                             model_path, rotA, minP, maxP):
        # load model onto terrain
        hdg_rads = hdg * math.pi / 180.0
        model_obj = self.loader.loadModel(model_path)
        rotAll = rotA
        rotAll.setX(rotAll.getX() + hdg)
        model_obj.setHpr(rotA)
        model_obj.setLightOff()
        # if model changes, these will have to be recomputed
        # minP = Point3(0,0,0)
        # maxP = Point3(0,0,0)
        # model_obj.calcTightBounds(minP,maxP)
        print minP
        print maxP
        htl = []
        maxzofs = -1000.0
        for xi in [minP[0], maxP[0]]:
            for yi in [minP[1], maxP[1]]:
                tx = xctr + scl * xi * math.cos(hdg_rads)
                ty = yctr + scl * yi * math.sin(hdg_rads)
                tht = self.terrain.getElevation(tx / terr_horz_sc,
                                                ty / terr_horz_sc)
                print 'tx=', tx, ', ty=', ty, ', tht=', tht
                htl.append(tht * terr_vert_sc - minP.getZ())
        for hi in htl:
            if hi > maxzofs:
                maxzofs = hi
        print maxzofs
        model_obj.setPos(xctr, yctr, maxzofs)
        model_obj.setHpr(rotAll)
        model_obj.setScale(scl)
        model_obj.reparentTo(render_node)
        return maxzofs, minP, maxP

    def get_camera_image(self, requested_format=None):
        """
        Returns the camera's image, which is of type uint8 and has values
        between 0 and 255.
        The 'requested_format' argument should specify in which order the
        components of the image must be. For example, valid format strings are
        "RGBA" and "BGRA". By default, Panda's internal format "BGRA" is used,
        in which case no data is copied over.
        """
        tex = self.dr.getScreenshot()
        if requested_format is None:
            data = tex.getRamImage()
        else:
            data = tex.getRamImageAs(requested_format)
        image = np.frombuffer(
            data.get_data(),
            np.uint8)  # use data.get_data() instead of data in python 2
        image.shape = (tex.getYSize(), tex.getXSize(), tex.getNumComponents())
        image = np.flipud(image)
        return image

    def get_camera_depth_image(self):
        """
        Returns the camera's depth image, which is of type float32 and has
        values between 0.0 and 1.0.
        """
        data = self.depthTex.getRamImage()
        depth_image = np.frombuffer(data.get_data(), np.float32)
        depth_image.shape = (self.depthTex.getYSize(),
                             self.depthTex.getXSize(),
                             self.depthTex.getNumComponents())
        depth_image = np.flipud(depth_image)
        '''
        
        Surface position can be inferred by calculating backward from the
        depth buffer. Each pixel on the screen represents a ray from the
        camera into the scene, and the depth value in the pixel indicates a
        distance along the ray. Because of this, it is not actually necessary
        to store surface position explicitly - it is only necessary to store
        depth values. Of course, OpenGL does that for free.

        So the framebuffer now needs to store surface normal, diffuse color,
        and depth value (to infer surface position). In practice, most
        ordinary framebuffers can only store color and depth - they don't have
        any place to store a third value. So we need to use a special
        offscreen buffer with an "auxiliary" bitplane. The auxiliary bitplane
        stores the surface normal.

        So then, there's the final postprocessing pass. This involves
        combining the diffuse color texture, the surface normal texture, the
        depth texture, and the light parameters into a final rendered output.
        The light parameters are passed into the postprocessing shader as
        constants, not as textures.

        If there are a lot of lights, things get interesting. You use one
        postprocessing pass per light. Each pass only needs to scan those
        framebuffer pixels that are actually in range of the light in
        question. To traverse only the pixels that are affected by the light,
        just render the illuminated area's convex bounding volume.

        The shader to store the diffuse color and surface normal is trivial.
        But the final postprocessing shader is a little complicated. What
        makes it tricky is that it needs to regenerate the original surface
        position from the screen position and depth value. The math for that
        deserves some explanation.

        We need to take a clip-space coordinate and depth-buffer value
        (ClipX,ClipY,ClipZ,ClipW) and unproject it back to a view-space
        (ViewX,ViewY,ViewZ) coordinate. Lighting is then done in view-space.

        Okay, so here's the math. Panda uses the projection matrix to
        transform view-space into clip-space. But in practice, the projection
        matrix for a perspective camera always contains four nonzero
        constants, and they're always in the same place:
            
        -- here are the non-zero elements of the projection matrix --
        
        A	0	0	0
        0	0	B	1
        0	C	0	0
        0	0	D	0
        
        -- precompute these from above projection matrix --
        '''
        proj = self.cam.node().getLens().getProjectionMat()
        proj_x = 0.5 * proj.getCell(3, 2) / proj.getCell(0, 0)
        proj_y = 0.5 * proj.getCell(3, 2)
        proj_z = 0.5 * proj.getCell(3, 2) / proj.getCell(2, 1)
        proj_w = -0.5 - 0.5 * proj.getCell(1, 2)
        '''
        -- now for each pixel compute viewpoint coordinates --
        
        viewx = (screenx * projx) / (depth + projw)
        viewy = (1 * projy) / (depth + projw)
        viewz = (screeny * projz) / (depth + projw)
        '''
        grid = np.mgrid[0:depth_image.shape[0], 0:depth_image.shape[1]]
        ygrid = np.float32(np.squeeze(
            grid[0, :, :])) / float(depth_image.shape[0] - 1)
        ygrid -= 0.5
        xgrid = np.float32(np.squeeze(
            grid[1, :, :])) / float(depth_image.shape[1] - 1)
        xgrid -= 0.5
        xview = 2.0 * xgrid * proj_x
        zview = 2.0 * ygrid * proj_z
        denom = np.squeeze(depth_image) + proj_w
        xview = xview / denom
        yview = proj_y / denom
        zview = zview / denom
        sqrng = xview**2 + yview**2 + zview**2
        range_image = np.sqrt(sqrng)
        range_image_1 = np.expand_dims(range_image, axis=2)

        return depth_image, range_image_1

    def compute_sample_pattern(self, limg_shape, res_factor):
        # assume velocity is XYZ and we are looking +X up and towards -Z
        pattern = []
        lens = self.cam.node().getLens()
        sx = self.win.getXSize()
        sy = self.win.getYSize()
        ifov_vert = 2.0 * math.tan(
            0.5 * math.radians(lens.getVfov())) / float(sy - 1)
        ifov_horz = 2.0 * math.tan(
            0.5 * math.radians(lens.getHfov())) / float(sx - 1)
        #ifov_vert = lens.getVfov() / float(sy-1)
        #ifov_horz = lens.getHfov() / float(sy-1)
        for ldr_row in range(limg_shape[0]):
            theta = -10.0 - 41.33 * (
                float(ldr_row) / float(limg_shape[0] - 1) - 0.5)
            for ldr_col in range(limg_shape[1]):
                psi = 60.0 * (float(ldr_col) / float(limg_shape[1] - 1) - 0.5)
                cpsi = math.cos(math.radians(psi))
                vert_ang = theta / cpsi
                img_row_flt = (0.5 * float(sy - 1) -
                               (math.tan(math.radians(vert_ang)) / ifov_vert))
                #img_row_flt = 0.5*(sy-1) - (vert_ang / ifov_vert)
                if img_row_flt < 0:
                    print('img_row_flt=%f' % img_row_flt)
                    img_row_flt = 0.0
                if img_row_flt >= sy:
                    print('img_row_flt=%f' % img_row_flt)
                    img_row_flt = float(sy - 1)
                img_col_flt = (0.5 * float(sx - 1) +
                               (math.tan(math.radians(psi)) / ifov_horz))
                #img_col_flt = 0.5*(sx-1) + (psi / ifov_horz)
                if img_col_flt < 0:
                    print('img_col_flt=%f' % img_col_flt)
                    img_col_flt = 0.0
                if img_col_flt >= sx:
                    print('img_col_flt=%f' % img_col_flt)
                    img_col_flt = float(sx - 1)
                pattern.append((ldr_row, ldr_col, img_row_flt, img_col_flt))
        return pattern

    def find_sorted_ladar_returns(self, rangearr, intensarr, ks_m):
        my_range = rangearr.copy()
        my_inten = intensarr.copy()
        '''
        pixels data is organized by:
           [0] starting range of this return
           [1] ending range of this return
           [2] peak range of this return
           [3] total intensity of this return
        '''
        int_mult = len(my_inten)
        pixels = map(
            list,
            zip(my_range.tolist(), my_range.tolist(), my_range.tolist(),
                my_inten.tolist()))
        spix = sorted(pixels, key=lambda x: x[0])
        done = False
        while not done:
            mxpi = len(spix)
            if mxpi > 2:
                mindel = 1e20
                mnidx = None
                for pidx in range(mxpi - 1):
                    rdel = spix[pidx + 1][0] - spix[pidx][1]
                    # must be within ks_m meters in range to merge
                    if (rdel < ks_m) and (rdel < mindel):
                        mindel = rdel
                        mnidx = pidx
                # merge best two returns
                if mnidx is not None:
                    # new range span for testing against neighbors
                    spix[mnidx][1] = spix[mnidx + 1][1]
                    # new peak range is range of max contributor
                    if spix[mnidx + 1][3] > spix[mnidx][3]:
                        spix[mnidx][2] = spix[mnidx + 1][2]
                    # intensity of return is sum of contributors
                    spix[mnidx][3] += spix[mnidx + 1][3]
                    # remove one of the two merged
                    del spix[mnidx + 1]
                else:
                    done = True
            else:
                done = True
        # now eliminate all but max and last returns
        max_idx = None
        max_val = 0.0
        for ci, pix in enumerate(spix):
            if pix[3] > max_val:
                max_val = pix[3] / int_mult
                max_idx = ci
        # if they are the same, return only one
        if spix[-1][3] >= spix[max_idx][3]:
            return [spix[-1]]
        else:
            return [spix[max_idx], spix[-1]]

    def sample_range_image(self, rng_img, int_img, limg_shape, vel_cam, pps,
                           ldr_err, pattern):
        # depth image is set up as 512 x 512 and is 62.5 degrees vertical FOV
        # the center row is vertical, but we want to sample from the
        # region corresponding to HDL-32 FOV: from +10 to -30 degrees
        detailed_sensor_model = False
        fwd_vel = vel_cam[1]
        beam_div = 0.002
        lens = self.cam.node().getLens()
        #sx = self.win.getXSize()
        sy = self.win.getYSize()
        ifov_vert = 2.0 * math.tan(
            0.5 * math.radians(lens.getVfov())) / float(sy - 1)
        #ifov_horz = 2.0*math.tan(0.5*math.radians(lens.getHfov()))/float(sx-1)
        #ifov = math.radians(self.cam.node().getLens().getVfov() / self.win.getYSize())
        sigma = beam_div / ifov_vert
        hs = int(2.0 * sigma + 1.0)
        gprof = gauss_kern(sigma, hs, normalize=False)
        rimg = np.zeros(limg_shape, dtype=np.float32)
        iimg = np.zeros(limg_shape, dtype=np.float32)
        margin = 10.0

        for pidx, relation in enumerate(pattern):

            # get the usual scan pattern sample
            ldr_row, ldr_col, img_row_flt, img_col_flt = relation

            if ((img_row_flt > -margin) and (img_col_flt > -margin)
                    and (img_row_flt < rng_img.shape[0] + margin)
                    and (img_col_flt < rng_img.shape[1] + margin)):

                # within reasonable distance from image limits
                img_row = int(round(img_row_flt))
                img_col = int(round(img_col_flt))

                # motion compensation
                trng = np.float32(rng_img[img_row, img_col])
                if trng > 0.0:
                    # TODO: change this back to False
                    done = True
                    ic = 0
                    while not done:
                        old_trng = trng
                        del_row = pidx * fwd_vel / (ifov_vert * trng * pps)
                        if (abs(del_row) > 1e-1) and (ic < 10):
                            img_row_f = img_row_flt + del_row
                            img_row = int(round(img_row_f))
                            trng = np.float32(rng_img[img_row, img_col])
                            ic += 1
                            if abs(trng - old_trng) < 0.5:
                                done = True
                        else:
                            done = True

                    # simple sensor processing: just sample from large images
                    rimg[ldr_row, ldr_col] = np.float32(rng_img[img_row,
                                                                img_col])
                    iimg[ldr_row, ldr_col] = np.float32(int_img[img_row,
                                                                img_col])

                    if detailed_sensor_model:
                        # detailed model subsamples whole beam width
                        gpatch = copy_patch_centered((img_row, img_col), hs,
                                                     int_img, 0.0)
                        gpatch = np.float32(gpatch)
                        gpatch *= gprof
                        rpatch = copy_patch_centered((img_row, img_col), hs,
                                                     rng_img, 0.0)
                        rpatch = np.squeeze(rpatch)
                        valid = rpatch > 1e-3
                        if np.count_nonzero(valid) > 0:
                            rpatch_ts = rpatch[valid]
                            gpatch_ts = gpatch[valid]
                            returns = self.find_sorted_ladar_returns(
                                rpatch_ts, gpatch_ts, 2.5)
                            # for now we just take first return
                            rimg[ldr_row, ldr_col] = returns[0][2]
                            iimg[ldr_row, ldr_col] = returns[0][3]
                else:
                    rimg[ldr_row, ldr_col] = 0.0
                    iimg[ldr_row, ldr_col] = np.float32(int_img[img_row,
                                                                img_col])

        rimg += ldr_err * np.random.standard_normal(rimg.shape)
        return rimg, iimg

    def skysphereTask(self, task):
        if self.base is not None:
            self.skysphere.setPos(self.base.camera, 0, 0, 0)
            self.terrain.generate()
        return task.cont
Exemple #43
0
    def renderSceneInto(self,
                        depthtex=None,
                        colortex=None,
                        auxtex=None,
                        auxbits=0,
                        textures=None,
                        rgbabits=(1, 1, 1, 1),
                        floatcolor=False,
                        srgb=False,
                        depthbits=1,
                        floatdepth=False,
                        multisamples=0):
        """ 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,
                                   rgbabits=rgbabits,
                                   floatcolor=floatcolor,
                                   srgb=srgb,
                                   depthbits=depthbits,
                                   floatdepth=floatdepth,
                                   multisamples=multisamples)

        if (buffer == None):
            return None

        cm = CardMaker("filter-base-quad")
        cm.setFrameFullscreenQuad()
        quad = NodePath(cm.generate())
        quad.setDepthTest(0)
        quad.setDepthWrite(0)
        quad.setTexture(colortex)
        quad.setColor(1, 0.5, 0.5, 1)

        cs = NodePath("dummy")
        cs.setState(self.camstate)
        # Do we really need to turn on the Shader Generator?
        #cs.setShaderAuto()
        if (auxbits):
            cs.setAttrib(AuxBitplaneAttrib.make(auxbits))
        self.camera.node().setInitialState(cs.getState())

        quadcamnode = Camera("filter-quad-cam")
        lens = OrthographicLens()
        lens.setFilmSize(2, 2)
        lens.setFilmOffset(0, 0)
        lens.setNearFar(-1000, 1000)
        quadcamnode.setLens(lens)
        quadcam = quad.attachNewNode(quadcamnode)

        self.region.setCamera(quadcam)

        self.setStackedClears(buffer, self.rclears, self.wclears)
        if (auxtex0):
            buffer.setClearActive(GraphicsOutput.RTPAuxRgba0, 1)
            buffer.setClearValue(GraphicsOutput.RTPAuxRgba0,
                                 (0.5, 0.5, 1.0, 0.0))
        if (auxtex1):
            buffer.setClearActive(GraphicsOutput.RTPAuxRgba1, 1)
        self.region.disableClears()
        if (self.isFullscreen()):
            self.win.disableClears()

        dr = buffer.makeDisplayRegion()
        dr.disableClears()
        dr.setCamera(self.camera)
        dr.setActive(1)

        self.buffers.append(buffer)
        self.sizes.append((1, 1, 1))

        return quad
Exemple #44
0
 def initPostProcessing(self):
     manager = FilterManager(base.win, base.cam)
     tex = Texture()
     quad = manager.renderSceneInto(colortex=tex)
     quad.setShader(Shader.load("shaders/post_processing.sha"))
     quad.setShaderInput("tex", tex)
Exemple #45
0
    def __init__(self,
                 texture_array,
                 stim_angles=(0, 0),
                 mask_angle=0,
                 position=(0, 0),
                 velocity=0,
                 band_radius=3,
                 window_size=512,
                 texture_size=512,
                 bgcolor=(0, 0, 0, 1)):
        super().__init__()

        self.mask_position_ndc = position
        self.mask_position_uv = (ndc2uv(self.mask_position_ndc[0]),
                                 ndc2uv(self.mask_position_ndc[1]))
        self.mask_scale = np.sqrt(8)
        self.texture_array = texture_array
        self.texture_dtype = type(self.texture_array.flat[0])
        self.ndims = self.texture_array.ndim
        self.left_texture_angle = stim_angles[0]
        self.right_texture_angle = stim_angles[1]
        self.velocity = velocity
        self.mask_angle = mask_angle  #this will change fairly frequently

        #Set window title and size
        self.window_properties = WindowProperties()
        self.window_properties.setSize(window_size, window_size)
        self.window_properties.setTitle("BinocularStatic")
        ShowBaseGlobal.base.win.requestProperties(
            self.window_properties)  #base is a panda3d global

        #CREATE MASKS (right mask for left stim, and vice-versa)
        self.right_mask = 255 * np.ones(
            (texture_size, texture_size), dtype=np.uint8)
        self.right_mask[:, texture_size // 2 - band_radius:] = 0

        #CREATE TEXTURE STAGES
        #Grating texture
        self.grating_texture = Texture("Grating")  #T_unsigned_byte
        self.grating_texture.setup2dTexture(texture_size, texture_size,
                                            Texture.T_unsigned_byte,
                                            Texture.F_luminance)
        self.grating_texture.setRamImage(self.texture_array)
        self.left_texture_stage = TextureStage('grating')
        #Mask
        self.right_mask_texture = Texture("right_mask")
        self.right_mask_texture.setup2dTexture(texture_size, texture_size,
                                               Texture.T_unsigned_byte,
                                               Texture.F_luminance)
        self.right_mask_texture.setRamImage(self.right_mask)
        self.right_mask_stage = TextureStage('right_mask')
        #Multiply the texture stages together
        self.right_mask_stage.setCombineRgb(TextureStage.CMModulate,
                                            TextureStage.CSTexture,
                                            TextureStage.COSrcColor,
                                            TextureStage.CSPrevious,
                                            TextureStage.COSrcColor)

        #CREATE CARDS/SCENEGRAPH
        cm = CardMaker('stimcard')
        cm.setFrameFullscreenQuad()
        self.left_card = self.aspect2d.attachNewNode(cm.generate())

        #SET TEXTURE STAGES
        self.left_card.setTexture(self.left_texture_stage,
                                  self.grating_texture)
        self.left_card.setTexture(self.right_mask_stage,
                                  self.right_mask_texture)

        #Add texture move procedure to the task manager, if needed
        if self.velocity != 0:
            self.taskMgr.add(self.update_trs, "moveTextureTask")

        self.title = OnscreenText("x",
                                  style=1,
                                  fg=(1, 1, 1, 1),
                                  bg=(0, 0, 0, .8),
                                  pos=self.mask_position_ndc,
                                  scale=0.05)
Exemple #46
0
class ShaderHeightmap(Heightmap):
    tex_generators = {}

    def __init__(self, name, width, height, height_scale, median, noise, offset, scale, coord = TexCoord.Cylindrical):
        Heightmap.__init__(self, name, width, height, height_scale, 1.0, 1.0, median)
        self.noise = noise
        self.offset = offset
        self.scale = scale
        self.coord = coord
        self.shader = None
        self.texture = None
        self.texture_offset = LVector2()
        self.texture_scale = LVector2(1, 1)
        self.tex_id = str(width) + ':' + str(height)

    def reset(self):
        self.texture = None

    def set_noise(self, noise):
        self.noise = noise
        self.shader = None
        self.texture = None

    def set_offset(self, offset):
        self.offset = offset
        if self.shader is not None:
            self.shader.offset = offset
        self.texture = None

    def set_scale(self, scale):
        self.scale = scale
        if self.shader is not None:
            self.shader.scale = scale
        self.texture = None

    def get_heightmap(self, patch):
        return self

    def get_texture_offset(self, patch):
        return self.texture_offset

    def get_texture_scale(self, patch):
        return self.texture_scale

    def get_height(self, x, y):
        if self.texture_peeker is None:
            print("No peeker")
            traceback.print_stack()
            return 0.0
        try:
            color = LColor()
            #pos = LVector2(x * self.texture_scale[0], ((self.height - 1) - y) * self.texture_scale[1]) + self.texture_offset
            new_x = x * self.texture_scale[0] + self.texture_offset[0] * self.width
            #new_y = y * self.texture_scale[1] + self.texture_offset[1] * self.height
            #new_y = ((self.height - 1) - new_y)
            new_y = ((self.height - 1) - y) * self.texture_scale[1] + self.texture_offset[1] * self.height
            #print(x, y, int(new_x), int(new_y), self.texture_scale, self.texture_offset)
            self.texture_peeker.fetch_pixel(color, min(int(new_x), self.width - 1), min(int(new_y), self.height - 1))
            #self.texture_peeker.fetch_pixel(color, x, y)
            if settings.encode_float:
                height = color[0] + color[1] / 255.0 + color[2] / 65025.0 + color[3] / 16581375.0
            else:
                height = color[0]
        except AssertionError as e:
            #traceback.print_stack()
            #print(e)
            print(x, y)
            print(int(new_x), int(new_y))
            print(((self.height - 1) - y), self.texture_scale[1], ((self.height - 1) - y) * self.texture_scale[1], self.texture_offset[1] * self.height)
            height = 0.0
        #print(height, self.parent.height_scale)
        return height * self.height_scale# + self.offset

    def heightmap_ready_cb(self, texture, callback, cb_args):
        self.heightmap_ready = True
        #print("READY")
        self.texture_peeker = self.texture.peek()
#         if self.texture_peeker is None:
#             print("NOT READY !!!")
        if callback is not None:
            callback(self, *cb_args)

    def create_heightmap(self, patch, callback=None, cb_args=()):
        if self.texture is None:
            self.texture = Texture()
            self.texture.set_wrap_u(Texture.WMClamp)
            self.texture.set_wrap_v(Texture.WMClamp)
            self.texture.setMinfilter(Texture.FT_linear)
            self.texture.setMagfilter(Texture.FT_linear)
            self._make_heightmap(callback, cb_args)
        else:
            if callback is not None:
                callback(self, *cb_args)

    def _make_heightmap(self, callback, cb_args):
        if not self.tex_id in ShaderHeightmap.tex_generators:
            ShaderHeightmap.tex_generators[self.tex_id] = TexGenerator()
            if settings.encode_float:
                texture_format = Texture.F_rgba
            else:
                texture_format = Texture.F_r32
            ShaderHeightmap.tex_generators[self.tex_id].make_buffer(self.width, self.height, texture_format)
        tex_generator = ShaderHeightmap.tex_generators[self.tex_id]
        if self.shader is None:
            self.shader = NoiseShader(noise_source=self.noise,
                                      noise_target=FloatTarget(),
                                      coord = self.coord,
                                      offset = self.offset,
                                      scale = self.scale)
            self.shader.global_frequency = self.global_frequency
            self.shader.create_and_register_shader(None, None)
        tex_generator.generate(self.shader, 0, self.texture, self.heightmap_ready_cb, (callback, cb_args))
Exemple #47
0
class BinocularDrift(ShowBase):
    """
    Show binocular drifting textures forever.
    Takes in texture array and other parameters, and shows texture drifting indefinitely.
    Texture array can be grayscale or rgb, uint8 or uint16.
    
    Usage:
        BinocularDrift(texture_array, 
                        stim_angles = (0, 0), 
                        mask_angle = 0, 
                        position = (0,0),
                        velocity = 0.1,
                        band_radius = 3,
                        window_size = 512, 
                        texture_size = 512,
                        bgcolor = (0,0,0,1))
        
    Note(s): 
        angles are (left_texture_angle, right_texture_angle): >  is cw, < 0 cc2
        Velocity is in NDC, so 1.0 is the entire window width (i.e., super-fast).
        Make texture_size a power of 2: this makes the GPU happier.
        position is x,y in NDC (from [-1 1]), so (.5, .5) will be in top right quadrant of window.
        band_radius is just the half-width of the band in the middle. It can be 0.
        The texture array can be 2d (gray) or NxNx3 (rgb)
    """
    def __init__(self,
                 texture_array,
                 stim_angles=(0, 0),
                 mask_angle=0,
                 position=(0, 0),
                 velocity=0,
                 band_radius=3,
                 window_size=512,
                 texture_size=512,
                 bgcolor=(0, 0, 0, 1)):
        super().__init__()

        self.mask_position_ndc = position
        self.mask_position_uv = (ndc2uv(self.mask_position_ndc[0]),
                                 ndc2uv(self.mask_position_ndc[1]))
        self.mask_scale = np.sqrt(8)
        self.texture_array = texture_array
        self.texture_dtype = type(self.texture_array.flat[0])
        self.ndims = self.texture_array.ndim
        self.left_texture_angle = stim_angles[0]
        self.right_texture_angle = stim_angles[1]
        self.velocity = velocity
        self.mask_angle = mask_angle  #this will change fairly frequently

        #Set window title and size
        self.window_properties = WindowProperties()
        self.window_properties.setSize(window_size, window_size)
        self.window_properties.setTitle("BinocularStatic")
        ShowBaseGlobal.base.win.requestProperties(
            self.window_properties)  #base is a panda3d global

        #CREATE MASKS (right mask for left stim, and vice-versa)
        self.right_mask = 255 * np.ones(
            (texture_size, texture_size), dtype=np.uint8)
        self.right_mask[:, texture_size // 2 - band_radius:] = 0

        #CREATE TEXTURE STAGES
        #Grating texture
        self.grating_texture = Texture("Grating")  #T_unsigned_byte
        self.grating_texture.setup2dTexture(texture_size, texture_size,
                                            Texture.T_unsigned_byte,
                                            Texture.F_luminance)
        self.grating_texture.setRamImage(self.texture_array)
        self.left_texture_stage = TextureStage('grating')
        #Mask
        self.right_mask_texture = Texture("right_mask")
        self.right_mask_texture.setup2dTexture(texture_size, texture_size,
                                               Texture.T_unsigned_byte,
                                               Texture.F_luminance)
        self.right_mask_texture.setRamImage(self.right_mask)
        self.right_mask_stage = TextureStage('right_mask')
        #Multiply the texture stages together
        self.right_mask_stage.setCombineRgb(TextureStage.CMModulate,
                                            TextureStage.CSTexture,
                                            TextureStage.COSrcColor,
                                            TextureStage.CSPrevious,
                                            TextureStage.COSrcColor)

        #CREATE CARDS/SCENEGRAPH
        cm = CardMaker('stimcard')
        cm.setFrameFullscreenQuad()
        self.left_card = self.aspect2d.attachNewNode(cm.generate())

        #SET TEXTURE STAGES
        self.left_card.setTexture(self.left_texture_stage,
                                  self.grating_texture)
        self.left_card.setTexture(self.right_mask_stage,
                                  self.right_mask_texture)

        #Add texture move procedure to the task manager, if needed
        if self.velocity != 0:
            self.taskMgr.add(self.update_trs, "moveTextureTask")

        self.title = OnscreenText("x",
                                  style=1,
                                  fg=(1, 1, 1, 1),
                                  bg=(0, 0, 0, .8),
                                  pos=self.mask_position_ndc,
                                  scale=0.05)

    #Procedure to move the camera
    def update_trs(self, task):
        #Move texture in whatever direction
        new_texture_position = -task.time * self.velocity  #negative b/c texture stage
        self.left_card.setTexPos(self.left_texture_stage, new_texture_position,
                                 0, 0)
        #Transform the mask so we only see some of the texture
        self.left_card.setTexTransform(self.right_mask_stage,
                                       self.trs_transform(task.time))
        return task.cont

    def trs_transform(self, elapsed_time):
        """ trs = translate rotate scale: transform for mask stage """
        pos = 0.5 + self.mask_position_uv[0], 0.5 + self.mask_position_uv[1]
        center_shift = TransformState.make_pos2d((-pos[0], -pos[1]))
        scale = TransformState.make_scale2d(1 / self.mask_scale)
        rotate = TransformState.make_rotate2d(np.mod(elapsed_time * 40, 360))
        translate = TransformState.make_pos2d((0.5, 0.5))
        return translate.compose(rotate.compose(scale.compose(center_shift)))
Exemple #48
0
    def generateNode(self, name, DB, parentNode):
        log.debug("Setting up " + name)
        bodyEntity = sandbox.createEntity()
        component = CelestialComponent()
        if DB['type'] == 'solid':
            body = Body(name)
        elif DB['type'] == 'moon':
            body = Body(name)
            body.kind = "moon"
        elif DB['type'] == 'star':
            body = Star(name)
            body.absoluteM = DB['absolute magnitude']
            body.spectral = DB['spectral']
        elif DB['type'] == 'barycenter':
            body = BaryCenter(name)

        component.kind = TYPES[DB['type']]

        if DB['type'] != "barycenter":
            component.mass = DB['mass']
            body.radius = DB['radius']
            body.rotation = DB['rotation']

        if 'orbit' in DB:
            component.orbit = DB['orbit']
            body.period = DB['period']
            #body.setPos(self.get2DBodyPosition(component, universals.day))
            component.truePos = self.get2DBodyPosition(component, universals.day)
            if name == "Earth":
                #universals.spawn = component.truePos + LPoint3d(0, 6671, 0)
                universals.spawn = component.truePos + LPoint3d(6671, 0, 0)

        if parentNode == universals.solarSystemRoot:
            universals.defaultSOIid = bodyEntity.id
            component.soi = 0
        elif DB['type'] != 'star' or DB['type'] != 'barycenter':
            component.soi = self.getSOI(component.mass, self.bodies[0].mass, component.orbit['a'])

        body.type = DB['type']
        body.reparentTo(parentNode)
        component.nodePath = body
        self.bodies.append(component)
        bodyEntity.addComponent(component)

        if universals.runClient and DB['type'] == 'star':
            component = graphicsComponents.RenderComponent()
            #component.mesh = NodePath(name)
            #self.sphere.copyTo(component.mesh)
            #component.mesh = shapeGenerator.Sphere(body.radius, 128, name)
            component.mesh = shapeGenerator.Sphere(body.radius, 64, name)
            #component.mesh.setScale(body.radius)
            component.mesh.reparentTo(sandbox.base.render)
            sandbox.send('makePickable', [component.mesh])
            #texture = sandbox.base.loader.loadTexture('planets/' + DB['texture'])
            #texture.setMinfilter(Texture.FTLinearMipmapLinear)
            #ts1 = TextureStage('textures1')
            #ts1.setMode(TextureStage.MGlow)
            #component.mesh.setTexture(ts1, texture)
            #component.mesh.setTexture(texture, 1)

            component.light = component.mesh.attachNewNode(PointLight("sunPointLight"))
            component.light.node().setColor(Vec4(1, 1, 1, 1))
            sandbox.base.render.setLight(component.light)
            bodyEntity.addComponent(component)

            #Shader test
            componentStar = graphicsComponents.StarRender()
            componentStar.noise_texture = Texture('noise')
            componentStar.noise_texture.setup2dTexture()
            img = PNMImage(1024, 1024)
            for y in range(1024):
                for x in range(1024):
                    img.setXel(x, y, componentStar.noise.noise(x, y))
                    #print componentStar.noise.noise(x, y)
            componentStar.noise_texture.load(img)
            #componentStar.noise_texture.write('test.png')
            #component.mesh.setTexture(componentStar.noise_texture, 1)

            texture = sandbox.base.loader.loadTexture('planets/' + DB['texture'])
            ts1 = TextureStage('textures1')
            ts1.setMode(TextureStage.MGlow)
            component.mesh.setTexture(ts1, componentStar.noise_texture)
            #component.mesh.setTexture(ts1, texture)

            component.mesh.setShaderInput('time', universals.get_day_in_seconds())
            shaders = Shader.load(Shader.SLGLSL, 'vortexVertex.glsl', 'starFrag.glsl')
            component.mesh.setShader(shaders)
            sandbox.send('makePickable', [component.mesh])


        if universals.runClient and (DB['type'] == 'solid' or DB['type'] == 'moon'):
            component = graphicsComponents.RenderComponent()
            #component.mesh = shapeGenerator.Sphere(body.radius, 128, name)
            #component.mesh = shapeGenerator.Sphere(body.radius, 64, name)
            component.mesh = surface_mesh.make_planet(name=name, scale=body.radius)
            #sandbox.send('makePickable', [component.mesh])
            sandbox.send('makePickable', [component.mesh.node_path])
            #component.mesh.setScale(body.radius)
            component.mesh.reparent_to(sandbox.base.render)
            # Doing world text
            text = TextNode('node name')
            text.setText(name)
            #textNodePath = component.mesh.attachNewNode(text)
            textNodePath = component.mesh.node_path.attachNewNode(text)
            textNodePath.setScale(0.07)

            component.mesh.set_textures(DB['texture'],
                night_path=DB['night'],
                gloss_path=DB['spec'])


            component.mesh.set_ambient(1, 1, 1, 1)
            component.mesh.set_diffuse(1, 1, 1, 1)
            component.mesh.set_specular(1, 1, 1, 1)
            component.mesh.set_shininess(100)

            '''if '#' in DB['texture']:
                component.mesh.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition)
                component.mesh.setTexProjector(TextureStage.getDefault(), sandbox.base.render, component.mesh)
                component.mesh.setTexScale(TextureStage.getDefault(), 1,  1, -1)
                component.mesh.setTexHpr(TextureStage.getDefault(), 90, -18, 90)
                #self.mesh.setHpr(0, 90, 0)
                texture = loader.loadCubeMap('planets/' + DB['texture'])
            else:
                texture = sandbox.base.loader.loadTexture('planets/' + DB['texture'])
            #texture.setMinfilter(Texture.FTLinearMipmapLinear)
            component.mesh.setTexture(texture, 1)'''
            '''if "atmosphere" in DB:
                component.atmosphere = shapeGenerator.Sphere(-1, 128)
                component.atmosphere.reparentTo(render)
                component.atmosphere.setScale(body.radius * 1.025)
                outerRadius = component.atmosphere.getScale().getX()
                scale = 1 / (outerRadius - component.body.getScale().getX())
                component.atmosphere.setShaderInput("fOuterRadius", outerRadius)
                component.atmosphere.setShaderInput("fInnerRadius", component.mesh.getScale().getX())
                component.atmosphere.setShaderInput("fOuterRadius2", outerRadius * outerRadius)
                component.atmosphere.setShaderInput("fInnerRadius2",
                    component.mesh.getScale().getX()
                    * component.mesh.getScale().getX())

                component.atmosphere.setShaderInput("fKr4PI",
                    0.000055 * 4 * 3.14159)
                component.atmosphere.setShaderInput("fKm4PI",
                    0.000015 * 4 * 3.14159)

                component.atmosphere.setShaderInput("fScale", scale)
                component.atmosphere.setShaderInput("fScaleDepth", 0.25)
                component.atmosphere.setShaderInput("fScaleOverScaleDepth", scale / 0.25)

                # Currently hard coded in shader
                component.atmosphere.setShaderInput("fSamples", 10.0)
                component.atmosphere.setShaderInput("nSamples", 10)
                # These do sunsets and sky colors
                # Brightness of sun
                ESun = 15
                # Reyleight Scattering (Main sky colors)
                component.atmosphere.setShaderInput("fKrESun", 0.000055 * ESun)
                # Mie Scattering -- Haze and sun halos
                component.atmosphere.setShaderInput("fKmESun", 0.000015 * ESun)
                # Color of sun
                component.atmosphere.setShaderInput("v3InvWavelength", 1.0 / math.pow(0.650, 4),
                                                  1.0 / math.pow(0.570, 4),
                                                  1.0 / math.pow(0.465, 4))
                #component.atmosphere.setShader(Shader.load("atmo.cg"))'''
            bodyEntity.addComponent(component)
        log.info(name + " set Up")
        if 'bodies' in DB:
            for bodyName, bodyDB in DB['bodies'].items():
                self.generateNode(bodyName, bodyDB, body)
Exemple #49
0
class HeightmapPatch:
    cachable = True

    def __init__(self,
                 parent,
                 x0,
                 y0,
                 x1,
                 y1,
                 width,
                 height,
                 scale=1.0,
                 coord=TexCoord.Cylindrical,
                 face=-1,
                 border=1):
        self.parent = parent
        self.x0 = x0
        self.y0 = y0
        self.x1 = x1
        self.y1 = y1
        self.scale = scale
        self.width = width
        self.height = height
        self.coord = coord
        self.face = face
        self.border = border
        self.r_width = self.width + self.border * 2
        self.r_height = self.height + self.border * 2
        self.r_x0 = self.x0 - float(
            self.border) / self.width * (self.x1 - self.x0)
        self.r_x1 = self.x1 + float(
            self.border) / self.width * (self.x1 - self.x0)
        self.r_y0 = self.y0 - float(
            self.border) / self.height * (self.y1 - self.y0)
        self.r_y1 = self.y1 + float(
            self.border) / self.height * (self.y1 - self.y0)
        self.dx = self.r_x1 - self.r_x0
        self.dy = self.r_y1 - self.r_y0
        self.lod = None
        self.patch = None
        self.heightmap_ready = False
        self.texture = None
        self.texture_peeker = None
        self.callback = None
        self.cloned = False
        self.texture_offset = LVector2()
        self.texture_scale = LVector2(1, 1)
        self.min_height = None
        self.max_height = None
        self.mean_height = None

    @classmethod
    def create_from_patch(cls,
                          noise,
                          parent,
                          x,
                          y,
                          scale,
                          lod,
                          density,
                          coord=TexCoord.Cylindrical,
                          face=-1):
        #TODO: Should be move to Patch/Tile
        if coord == TexCoord.Cylindrical:
            r_div = 1 << lod
            s_div = 2 << lod
            x0 = float(x) / s_div
            y0 = float(y) / r_div
            x1 = float(x + 1) / s_div
            y1 = float(y + 1) / r_div
        elif coord == TexCoord.NormalizedCube or coord == TexCoord.SqrtCube:
            div = 1 << lod
            r_div = div
            s_div = div
            x0 = float(x) / div
            y0 = float(y) / div
            x1 = float(x + 1) / div
            y1 = float(y + 1) / div
        else:
            div = 1 << lod
            r_div = div
            s_div = div
            size = 1.0 / (1 << lod)
            x0 = (x) * scale
            y0 = (y) * scale
            x1 = (x + size) * scale
            y1 = (y + size) * scale
        patch = cls(noise,
                    parent,
                    x0,
                    y0,
                    x1,
                    y1,
                    width=density,
                    height=density,
                    scale=scale,
                    coord=coord,
                    face=face,
                    border=1)
        patch.patch_lod = lod
        patch.lod = lod
        patch.lod_scale_x = scale / s_div
        patch.lod_scale_y = scale / r_div
        patch.density = density
        patch.x = x
        patch.y = y
        return patch

    def copy_from(self, heightmap_patch):
        self.cloned = True
        self.lod = heightmap_patch.lod
        self.texture = heightmap_patch.texture
        self.texture_peeker = heightmap_patch.texture_peeker
        self.heightmap_ready = heightmap_patch.heightmap_ready
        self.min_height = heightmap_patch.min_height
        self.max_height = heightmap_patch.max_height
        self.mean_height = heightmap_patch.mean_height

    def calc_sub_patch(self):
        self.copy_from(self.parent_heightmap)
        delta = self.patch.lod - self.lod
        scale = 1 << delta
        if self.patch.coord != TexCoord.Flat:
            x_tex = int(self.x / scale) * scale
            y_tex = int(self.y / scale) * scale
            x_delta = float(self.x - x_tex) / scale
            y_delta = float(self.y - y_tex) / scale
        else:
            x_tex = int(self.x * scale) / scale
            y_tex = int(self.y * scale) / scale
            x_delta = float(self.x - x_tex)
            y_delta = float(self.y - y_tex)
        self.texture_offset = LVector2(x_delta, y_delta)
        self.texture_scale = LVector2(1.0 / scale, 1.0 / scale)

    def is_ready(self):
        return self.heightmap_ready

    def set_height(self, x, y, height):
        pass

    def get_height(self, x, y):
        if self.texture_peeker is None:
            print("No peeker", self.patch.str_id(), self.patch.instance_ready)
            traceback.print_stack()
            return 0.0
        new_x = x * self.texture_scale[0] + self.texture_offset[0] * self.width
        new_y = y * self.texture_scale[1] + self.texture_offset[1] * self.height
        new_x = min(new_x, self.width - 1)
        new_y = min(new_y, self.height - 1)
        height = self.parent.interpolator.get_value(self.texture_peeker, new_x,
                                                    new_y)
        #TODO: This should be done in PatchedHeightmap.get_height()
        return height * self.parent.height_scale  # + self.parent.offset

    def get_height_uv(self, u, v):
        return self.get_height(u * self.width, v * self.height)

    def load(self, patch, callback, cb_args=()):
        if self.texture is None:
            self.texture = Texture()
            self.texture.set_wrap_u(Texture.WMClamp)
            self.texture.set_wrap_v(Texture.WMClamp)
            self.parent.interpolator.configure_texture(self.texture)
            self.do_load(patch, callback, cb_args)
        else:
            if callback is not None:
                callback(self, *cb_args)

    def heightmap_ready_cb(self, texture, callback, cb_args):
        if texture is not None:
            self.texture = texture
            #print("READY", self.patch.str_id(), texture, self.texture)
            self.texture_peeker = texture.peek()
            #           if self.texture_peeker is None:
            #               print("NOT READY !!!")
            self.heightmap_ready = True
            data = self.texture.getRamImage()
            #TODO: should be completed and refactored
            signed = False
            component_type = texture.getComponentType()
            if component_type == Texture.T_float:
                buffer_type = numpy.float32
                scale = 1.0
            elif component_type == Texture.T_unsigned_byte:
                if signed:
                    buffer_type = numpy.int8
                    scale = 128.0
                else:
                    buffer_type = numpy.uint8
                    scale = 255.0
            elif component_type == Texture.T_unsigned_short:
                if signed:
                    buffer_type = numpy.int16
                    scale = 32768.0
                else:
                    buffer_type = numpy.uint16
                    scale = 65535.0
            if sys.version_info[0] < 3:
                buf = data.getData()
                np_buffer = numpy.fromstring(buf, dtype=buffer_type)
            else:
                np_buffer = numpy.frombuffer(data, buffer_type)
            np_buffer.shape = (self.texture.getYSize(),
                               self.texture.getXSize(),
                               self.texture.getNumComponents())
            self.min_height = np_buffer.min() / scale
            self.max_height = np_buffer.max() / scale
            self.mean_height = np_buffer.mean() / scale
        else:
            if self.parent_heightmap is not None:
                self.calc_sub_patch()
            else:
                print("Make default texture for heightmap")
                texture = Texture()
                texture.setup_2d_texture(1, 1, Texture.T_float, Texture.F_r32)
                texture.set_clear_color(LColor(0, 0, 0, 0))
                texture.make_ram_image()
                self.heightmap_ready_cb(texture, None, None)
        if callback is not None:
            callback(self, *cb_args)

    def do_load(self, patch, callback, cb_args):
        pass
Exemple #50
0
def check_and_create_rendering_buffers(showbase):
    if not settings.render_scene_to_buffer:
        return

    if not settings.buffer_texture:
        print("Render to buffer not supported")
        return

    print("Render scene to buffer")

    buffer_multisamples = 0
    if settings.render_scene_to_buffer and not settings.disable_multisampling and settings.use_multisampling and settings.multisamples > 0:
        buffer_multisamples = settings.multisamples

    manager = FilterManager(showbase.win, showbase.cam)
    color_buffer = Texture()
    depth_buffer = None
    aux_buffer = None
    if settings.use_inverse_z:
        render.set_attrib(DepthTestAttrib.make(DepthTestAttrib.M_greater))
        depth_buffer = Texture()
        showbase.win.set_clear_depth(0)
        float_depth = True
        depth_bits = 24
    else:
        float_depth = False
        depth_bits = 1
    if settings.render_scene_to_float:
        if settings.floating_point_buffer:
            rgba_bits = (32, 32, 32, 32)
            float_colors = True
        else:
            print(
                "Floating point buffer not available, sRBG conversion will show artifacts"
            )
            rgba_bits = (1, 1, 1, 1)
            float_colors = False
    else:
        rgba_bits = (1, 1, 1, 1)
        float_colors = False
    if settings.aux_buffer:
        aux_buffer = Texture()
    textures = {
        'color': color_buffer,
        'depth': depth_buffer,
        'aux0': aux_buffer
    }
    fbprops = FrameBufferProperties()
    fbprops.setFloatColor(float_colors)
    fbprops.setRgbaBits(*rgba_bits)
    fbprops.setSrgbColor(settings.srgb_buffer)
    fbprops.setDepthBits(depth_bits)
    fbprops.setFloatDepth(float_depth)
    if not settings.framebuffer_multisampling:
        fbprops.setMultisamples(buffer_multisamples)
    final_quad = manager.render_scene_into(textures=textures, fbprops=fbprops)
    final_quad.clear_color()
    if aux_buffer is not None:
        manager.buffers[-1].setClearValue(GraphicsOutput.RTPAuxRgba0,
                                          (0.0, 0.0, 0.0, 0.0))
    final_quad_shader = PostProcessShader(
        gamma_correction=settings.software_srgb,
        hdr=settings.use_hdr).create_shader()
    final_quad.set_shader(final_quad_shader)
    final_quad.set_shader_input("color_buffer", color_buffer)
    final_quad.set_shader_input("exposure", 2)
    return textures
Exemple #51
0
    def bld_page(self):
        self.skills = [drv[2] for drv in self.props.drivers]
        menu_gui = self.mdt.menu.gui
        menu_args = self.mdt.menu.gui.menu_args
        widgets = [
            OnscreenText(text=_('Select the driver'),
                         pos=(0, .8),
                         **menu_gui.menu_args.text_args)
        ]
        self.track_path = self.mdt.menu.track
        t_a = self.mdt.menu.gui.menu_args.text_args.copy()
        del t_a['scale']
        name = OnscreenText(_('Write your name:'),
                            pos=(-.1, .6),
                            scale=.06,
                            align=TextNode.A_right,
                            **t_a)
        self.ent = DirectEntry(scale=.08,
                               pos=(0, 1, .6),
                               entryFont=menu_args.font,
                               width=12,
                               frameColor=menu_args.btn_color,
                               initialText=self.props.player_name
                               or _('your name'))
        self.ent.onscreenText['fg'] = menu_args.text_fg
        self.drivers = []
        for row, col in product(range(2), range(4)):
            idx = (col + 1) + row * 4
            widgets += [
                ImgBtn(scale=.24,
                       pos=(-.75 + col * .5, 1, .25 - row * .5),
                       frameColor=(0, 0, 0, 0),
                       image=self.props.drivers_img[0] % idx,
                       command=self.on_click,
                       extraArgs=[idx],
                       **self.mdt.menu.gui.menu_args.imgbtn_args)
            ]
            self.drivers += [widgets[-1]]
            sign = lambda x: '\1green\1+\2' if x > 0 else ''
            psign = lambda x: '+' if x == 0 else sign(x)

            def ppcol(x):
                return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x

            pcol = lambda x: x if x == 0 else ppcol(x)

            def add_lab(txt, pos_z):
                return OnscreenText(txt + ':',
                                    pos=(-.95 + col * .5, pos_z - row * .5),
                                    scale=.046,
                                    align=TextNode.A_left,
                                    **t_a)

            def add_txt(val, pos_z):
                return OnscreenText('%s%s%%' % (psign(val), pcol(val)),
                                    pos=(-.55 + col * .5, pos_z - row * .5),
                                    scale=.052,
                                    align=TextNode.A_right,
                                    **t_a)

            lab_lst = [(_('adherence'), .04), (_('speed'), .16),
                       (_('stability'), .1)]
            widgets += map(lambda lab_def: add_lab(*lab_def), lab_lst)
            txt_lst = [(self.skills[idx - 1][1], .04),
                       (self.skills[idx - 1][0], .16),
                       (self.skills[idx - 1][2], .1)]
            widgets += map(lambda txt_def: add_txt(*txt_def), txt_lst)
        self.img = OnscreenImage(self.props.cars_img % self.mdt.car,
                                 parent=base.a2dBottomRight,
                                 pos=(-.38, 1, .38),
                                 scale=.32)
        widgets += [self.img, name, self.ent]
        map(self.add_widget, widgets)
        fpath = eng.curr_path + 'yyagl/assets/shaders/filter.vert'
        with open(fpath) as ffilter:
            vert = ffilter.read()
        shader = Shader.make(Shader.SL_GLSL, vert, frag)
        self.img.setShader(shader)
        self.img.setTransparency(True)
        self.t_s = TextureStage('ts')
        self.t_s.setMode(TextureStage.MDecal)
        empty_img = PNMImage(1, 1)
        empty_img.add_alpha()
        empty_img.alpha_fill(0)
        tex = Texture()
        tex.load(empty_img)
        self.img.setTexture(self.t_s, tex)
        ThanksPageGui.bld_page(self)
        self.update_tsk = taskMgr.add(self.update_text, 'update text')
        self.enable_buttons(False)
class ToonFPS(DirectObject):
    notify = directNotify.newCategory("ToonFPS")

    WeaponName2DamageData = {"pistol": (30.0, 10.0, 150.0, 0.3),
        "shotgun": (40.0, 15.0, 155.0, 0.5), "sniper": (40.0, 15.0, 155.0, 0.5)}

    def __init__(self, mg, weaponName = "pistol"):
        self.mg = mg
        self.weaponName = weaponName
        self.v_model_root = None
        self.v_model = None
        self.weapon = None
        self.track = None
        self.draw = None
        self.shoot = None
        self.reload = None
        self.empty = None
        self.cockBack = None
        self.cockFwd = None
        self.player_node = None

        # blach (02Aug15)
        # Drastically improved the accuracy of bullets... DRASTICALLY
        self.shooterTrav = None
        self.shooterRay = None
        self.shooterRayNode = None
        self.shooterHandler = None

        self.gui = ToonFPSGui(self)
        self.fsm = ClassicFSM('ToonFPS', [State('off', self.enterOff, self.exitOff),
                State('alive', self.enterAlive, self.exitAlive),
                State('dead', self.enterDead, self.exitDead)],
                'off', 'off')
        #self.deadFSM = ClassicFSM('dead', [State('off', self.enterOff, self.exitOff),
        #		State('])
        self.aliveFSM = ClassicFSM('alive', [State('off', self.enterOff, self.exitOff),
                State('draw', self.enterDraw, self.exitDraw, ['idle']),
                State('idle', self.enterIdle, self.exitIdle, ['shoot', 'reload']),
                State('shoot', self.enterShoot, self.exitShoot, ['idle']),
                State('reload', self.enterReload, self.exitReload, ['idle'])],
                'off', 'off')
        self.fsm.getStateNamed('alive').addChild(self.aliveFSM)
        #self.fsm.getStateNamed('dead').addChild(self.deadFSM)
        self.fsm.enterInitialState()
        self.aliveFSM.enterInitialState()
        if self.weaponName == "pistol":
            self.ammo = 14
        elif self.weaponName == "shotgun":
            self.ammo = 7
        self.hp = 125
        self.max_hp = 125
        self.firstPerson = FirstPerson()

    def movementTask(self, task):

        if (inputState.isSet('jump') or
            base.localAvatar.walkControls.isAirborne):

            if base.localAvatar.getAnimState() != "jump":

                base.localAvatar.setAnimState("jump")
                base.localAvatar.playMovementSfx(None)

                self.mg.sendUpdate("jumpingAvatar", [base.localAvatar.doId])

        return Task.cont

    def enterAlive(self):
        if not self.mg.fsm.getCurrentState().getName() in ['gameOver', 'announceGameOver', 'finalScores']:
            self.start()
            self.resetHp()
            self.resetAmmo()
            if self.mg.fsm.getCurrentState().getName() == "play":
                self.reallyStart()

    def exitAlive(self):
        self.end()
        self.v_model.reparentTo(hidden)
        if self.mg.fsm.getCurrentState().getName() != "play":
            self.reallyEnd()

    def updatePoints(self):
        self.points = self.kills - self.deaths

    def enterDead(self, killer):
        base.localAvatar.getGeomNode().show()
        self.gui.end()
        base.localAvatar.attachCamera()
        self.freezeCamSfx = base.loadSfx("phase_4/audio/sfx/freeze_cam.ogg")
        self.freezeCamImage = None
        self.freezeCamImageFile = None
        base.camera.setZ(base.camera.getZ() + 2.0)
        taskMgr.add(
            self.cameraLookAtKillerTask,
            "lookAtKiller",
            extraArgs = [killer],
            appendTask = True
        )
        taskMgr.doMethodLater(
            2.0,
            self.startZoomOnKiller,
            "startFreezeCam",
            extraArgs = [killer],
            appendTask = True
        )

    def startZoomOnKiller(self, killer, task):
        taskMgr.add(
            self.__zoomOnKillerTask,
            "zoomOnKiller",
            extraArgs = [killer],
            appendTask = True
        )
        return task.done

    def __zoomOnKillerTask(self, killer, task):
        if base.camera.getDistance(killer) <= 10.0 and self.freezeCamSfx.status() == self.freezeCamSfx.READY:
            base.playSfx(self.freezeCamSfx)
        if base.camera.getDistance(killer) < 7.0:
            self.doFreezeCam()
            return task.done
        base.camera.setY(base.camera, 60 * globalClock.getDt())
        return task.again

    def doFreezeCam(self):
        taskMgr.remove("lookAtKiller")
        self.frameBuffer = PNMImage()
        base.win.getScreenshot(self.frameBuffer)
        self.freezeCamTex = Texture()
        self.freezeCamTex.load(self.frameBuffer)
        self.freezeCamImage = OnscreenImage(image = self.freezeCamTex, parent=render2d)

    def cameraLookAtKillerTask(self, killer, task):
        try:
            base.camera.lookAt(killer, 0, 0, 3)
        except AssertionError:
            pass
        return task.cont

    def exitDead(self):
        taskMgr.remove("zoomOnKiller")
        taskMgr.remove("lookAtKiller")
        taskMgr.remove("startFreezeCam")
        del self.freezeCamSfx
        if self.freezeCamImage:
            self.freezeCamImage.destroy()
        del self.freezeCamImage
        self.frameBuffer.clear()
        self.freezeCamTex.clear()
        del self.frameBuffer
        del self.freezeCamTex
        base.localAvatar.detachCamera()
        base.localAvatar.getGeomNode().hide()
        self.gui.start()

    def load(self):
        if self.weaponName == "pistol":
            self.draw = base.loadSfx("phase_4/audio/sfx/draw_secondary.ogg")
            self.shoot = base.loadSfx("phase_4/audio/sfx/pistol_shoot.ogg")
            self.reload = base.loadSfx("phase_4/audio/sfx/pistol_worldreload.ogg")
        elif self.weaponName == "sniper":
            self.draw = base.loadSfx("phase_4/audio/sfx/draw_primary.ogg")
            self.shoot = base.loadSfx("phase_4/audio/sfx/shotgun_shoot.ogg")
            self.cockBack = base.loadSfx("phase_4/audio/sfx/shotgun_cock_back.ogg")
            self.cockFwd = base.loadSfx("phase_4/audio/sfx/shotgun_cock_forward.ogg")
        elif self.weaponName == "shotgun":
            self.draw = base.loadSfx("phase_4/audio/sfx/draw_primary.ogg")
            self.shoot = base.loadSfx("phase_4/audio/sfx/shotgun_shoot.ogg")
            self.cockBack = base.loadSfx("phase_4/audio/sfx/shotgun_cock_back.ogg")
            self.cockFwd = base.loadSfx("phase_4/audio/sfx/shotgun_cock_forward.ogg")
        self.empty = base.loadSfx("phase_4/audio/sfx/shotgun_empty.ogg")
        self.v_model_root = base.camera.attachNewNode('v_model_root')
        self.v_model = Actor('phase_4/models/minigames/v_dgm.egg', {'pidle': 'phase_4/models/minigames/v_dgm-pistol-idle.egg',
                        'pshoot': 'phase_4/models/minigames/v_dgm-pistol-shoot.egg',
                        'preload': 'phase_4/models/minigames/v_dgm-pistol-reload.egg',
                        'pdraw': 'phase_4/models/minigames/v_dgm-pistol-draw.egg',
                        'sidle': 'phase_4/models/minigames/v_dgm-shotgun-idle.egg',
                        'sshoot': 'phase_4/models/minigames/v_dgm-shotgun-shoot.egg'})
        if self.weaponName == "pistol":
            self.weapon = loader.loadModel("phase_4/models/props/water-gun.bam")
            self.weapon.reparentTo(self.v_model.exposeJoint(None, "modelRoot", "Bone.011"))
            self.weapon.setX(-0.125)
            self.weapon.setY(0.5)
            self.weapon.setScale(0.65)
        elif self.weaponName == "sniper":
            self.weapon = loader.loadModel("phase_4/models/props/sniper.egg")
            self.weapon.reparentTo(self.v_model.exposeJoint(None, "modelRoot", "Bone.029"))
            self.weapon.setScale(0.75)
            self.weapon.setPos(0.45, -1.03, -1.17)
            self.weapon.setHpr(9.46, 308.19, 75.78)
        elif self.weaponName == "shotgun":
            self.weapon = loader.loadModel("phase_4/models/props/shotgun.egg")
            self.weapon.reparentTo(self.v_model.exposeJoint(None, "modelRoot", "Bone.029"))
            self.weapon.setScale(0.75)
            self.weapon.setPos(0.45, -1.03, -1.17)
            self.weapon.setHpr(9.46, 308.19, 75.78)
        self.gui.load()

    def start(self):
        base.camLens.setNear(0.1)

        self.shooterTrav = CollisionTraverser('ToonFPS.shooterTrav')
        ray = CollisionRay()
        rayNode = CollisionNode('ToonFPS.rayNode')
        rayNode.addSolid(ray)
        rayNode.setCollideMask(BitMask32(0))
        rayNode.setFromCollideMask(CIGlobals.WallBitmask | CIGlobals.FloorBitmask)
        self.shooterRay = ray
        self.shooterRayNode = base.camera.attachNewNode(rayNode)
        self.shooterHandler = CollisionHandlerQueue()
        self.shooterTrav.addCollider(self.shooterRayNode, self.shooterHandler)

        self.firstPerson.start()
        self.v_model_root.reparentTo(base.camera)
        self.v_model.reparentTo(self.v_model_root)
        if self.weaponName == "pistol":
            self.v_model_root.setZ(-1.8)
            self.v_model_root.setY(0.3)
            self.v_model_root.setX(-0.1)
            self.v_model_root.setH(2)
        elif self.weaponName == "sniper":
            self.v_model_root.setPos(-0.42, -0.81, -1.7)
            self.v_model_root.setHpr(359, 352.87, 0.00)
        elif self.weaponName == "shotgun":
            self.v_model_root.setPos(-0.42, -0.81, -1.7)
            self.v_model_root.setHpr(359, 352.87, 0.00)
        self.gui.start()
        self.firstPerson.disableMouse()
        self.aliveFSM.request('draw')

    def reallyStart(self):
        self.firstPerson.reallyStart()
        base.localAvatar.startTrackAnimToSpeed()
        #taskMgr.add(self.movementTask, "toonBattleMovement")

    def end(self):
        if self.aliveFSM.getCurrentState().getName() != 'off':
            self.aliveFSM.request('off')
        if self.firstPerson:
            self.firstPerson.enableMouse()
            self.firstPerson.end()
        taskMgr.remove("toonBattleMovement")
        if self.mg.fsm.getCurrentState().getName() != "play":
            self.fsm.request('off')

    def reallyEnd(self):
        try:
            self.ToonFPS_reallyEnded
            return
        except:
            self.ToonFPS_reallyEnded = 1
        if self.shooterRayNode:
            self.shooterRayNode.removeNode()
            self.shooterRayNode = None
        self.shooterRay = None
        self.shooterTrav = None
        self.shooterHandler = None
        if self.firstPerson:
            self.firstPerson.reallyEnd()
        if self.v_model_root:
            self.v_model_root.reparentTo(hidden)
        if self.v_model:
            self.v_model.reparentTo(hidden)
            self.v_model.setPosHpr(0, 0, 0, 0, 0, 0)
        if self.gui:
            self.gui.end()
        base.camLens.setNear(1.0)

    def cleanup(self):
        try:
            self.ToonFPS_cleanedUp
            return
        except:
            self.ToonFPS_cleanedUp = 1
        taskMgr.remove("lookAtKiller")
        taskMgr.remove("toonBattleMovement")
        if self.firstPerson:
            self.firstPerson.cleanup()
            self.firstPerson = None
        self.draw = None
        self.shoot = None
        self.reload = None
        self.empty = None
        self.ammo = None
        try:
            self.aliveFSM.requestFinalState()
            self.fsm.requestFinalState()
        except:
            self.notify.warning('Redundant call to enter the final state.')
        self.fsm = None
        self.aliveFSM = None
        self.player_node = None
        self.min_camerap = None
        self.max_camerap = None
        self.hp = None
        self.max_hp = None
        if self.v_model:
            self.v_model.cleanup()
            self.v_model = None
        if self.weapon:
            self.weapon.removeNode()
            self.weapon = None
        if self.weapon:
            self.v_model_root.removeNode()
            self.v_model_root = None
        if self.gui:
            self.gui.cleanup()

    def damageTaken(self, amount, avId):
        if self.hp <= 0.0:
            killer = self.mg.cr.doId2do.get(avId, None)
            self.fsm.request('dead', [killer])
        self.gui.adjustHpMeter()

    def enterDraw(self):
        self.draw.play()
        if self.weaponName == "pistol":
            self.track = ActorInterval(self.v_model, 'pdraw', playRate = 1.6, name = 'drawTrack')
        elif self.weaponName == "shotgun":
            self.v_model.pose('sidle', 15)
            self.track = LerpQuatInterval(self.v_model, duration = 0.5, quat = (0, 0, 0),
                startHpr = (70, -50, 0), blendType = 'easeOut', name = 'drawTrack')
        elif self.weaponName == "sniper":
            self.v_model.pose('sidle', 15)
            self.track = LerpQuatInterval(self.v_model, duration = 0.5, quat = (0, 0, 0),
                startHpr = (70, -50, 0), blendType = 'easeOut', name = 'drawTrack')
        self.track.setDoneEvent(self.track.getName())
        self.acceptOnce(self.track.getDoneEvent(), self.aliveFSM.request, ['idle'])
        self.track.start()

    def exitDraw(self):
        #self.draw.stop()
        if self.track:
            self.ignore(self.track.getDoneEvent())
            self.track.finish()
            self.track = None

    def enterIdle(self):
        if self.weaponName == "pistol":
            self.v_model.loop('pidle')
        elif self.weaponName == "shotgun":
            self.track = Sequence(LerpQuatInterval(self.v_model, duration = 2.0, quat = (0, 1, 0), startHpr = (0, 0, 0), blendType = 'easeInOut'),
                LerpQuatInterval(self.v_model, duration = 2.0, quat = (0, 0, 0), startHpr = (0, 1, 0), blendType = 'easeInOut'))
            self.track.loop()
        elif self.weaponName == "sniper":
            self.track = Sequence(LerpQuatInterval(self.v_model, duration = 2.0, quat = (0, 1, 0), startHpr = (0, 0, 0), blendType = 'easeInOut'),
                LerpQuatInterval(self.v_model, duration = 2.0, quat = (0, 0, 0), startHpr = (0, 1, 0), blendType = 'easeInOut'))
            self.track.loop()
        self.accept('mouse1', self.requestShoot)
        if self.ammo <= 0:
            self.gui.notifyNoAmmo()
        if self.ammo < 14:
            self.accept('r', self.aliveFSM.request, ['reload'])

    def requestShoot(self):
        if self.mg.fsm.getCurrentState().getName() != "play":
            return
        if self.ammo > 0:
            self.aliveFSM.request('shoot')
        else:
            self.empty.play()

    def exitIdle(self):
        self.v_model.stop()
        if self.track:
            self.track.finish()
            self.track = None
        self.ignore('mouse1')
        self.ignore('r')

    def enterShoot(self):
        self.shoot.play()
        if self.weaponName == "pistol":
            self.track = ActorInterval(self.v_model, 'pshoot', playRate = 2, name = 'shootTrack')
        elif self.weaponName == "shotgun":
            self.track = Parallel(
                Sequence(
                    LerpQuatInterval(self.v_model, duration = 0.05, quat = (0, 3, 0), startHpr = (0, 0, 0)),
                    LerpQuatInterval(self.v_model, duration = 0.1, quat = (0, 0, 0), startHpr = (0, 3, 0))
                ),
                Sequence(
                    LerpPosInterval(self.v_model, duration = 0.05, pos = (0, -0.3, 0), startPos = (0, 0, 0)),
                    LerpPosInterval(self.v_model, duration = 0.1, pos = (0, 0, 0), startPos = (0, -0.3, 0)),
                    Wait(0.1)
                ),
            )
        elif self.weaponName == "sniper":
            self.track = Parallel(
                Sequence(
                    LerpQuatInterval(self.v_model, duration = 0.05, quat = (0, 3, 0), startHpr = (0, 0, 0)),
                    LerpQuatInterval(self.v_model, duration = 0.1, quat = (0, 0, 0), startHpr = (0, 3, 0))
                ),
                Sequence(
                    LerpPosInterval(self.v_model, duration = 0.05, pos = (0, -0.3, 0), startPos = (0, 0, 0)),
                    LerpPosInterval(self.v_model, duration = 0.1, pos = (0, 0, 0), startPos = (0, -0.3, 0)),
                    Wait(0.1)
                ),
            )
        self.track.setDoneEvent('shootTrack')
        self.acceptOnce(self.track.getDoneEvent(), self.aliveFSM.request, ['idle'])
        self.track.start()
        self.ammo -= 1
        self.gui.adjustAmmoGui()
        self.mg.makeSmokeEffect(self.weapon.find('**/joint_nozzle').getPos(render))
        self.traverse()

    def traverse(self):
        mpos = base.mouseWatcherNode.getMouse()
        self.shooterRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

        self.shooterTrav.traverse(render)

    def calcDamage(self, avatar):
        dmgData = self.WeaponName2DamageData[self.weaponName]
        maxDamage = dmgData[0]
        minDistance = dmgData[1]
        maxDistance = dmgData[2]
        factor = dmgData[3]
        distance = base.localAvatar.getDistance(avatar)
        if distance < minDistance:
            distance = minDistance
        elif distance > maxDistance:
            distance = maxDistance
        damage = maxDamage - ((distance - minDistance) * factor)
        return damage

    def exitShoot(self):
        #self.shoot.stop()
        self.ignore('shootTrack')
        if self.track:
            self.track.finish()
            self.track = None

    def enterReload(self):
        self.gui.deleteNoAmmoLabel()
        if self.weaponName == "pistol":
            self.track = Parallel(Sequence(Wait(0.3), Func(self.reload.play), Func(self.resetAmmo)),
                ActorInterval(self.v_model, 'preload', playRate = 1.5), name = 'reloadTrack')
        elif self.weaponName == "shotgun":
            self.track = Sequence(Func(self.draw.play), LerpQuatInterval(self.v_model, duration = 0.5,
                quat = (70, -50, 0), startHpr = (0, 0, 0), blendType = 'easeIn'),
                SoundInterval(self.cockBack),
                SoundInterval(self.cockFwd),
                Func(self.resetAmmo),
                Func(self.draw.play),
                LerpQuatInterval(self.v_model, duration = 0.5, quat = (0, 0, 0), startHpr = (70, -50, 0),
                    blendType = 'easeOut'), name = 'reloadTrack')
        elif self.weaponName == "sniper":
            self.track = Sequence(Func(self.draw.play), LerpQuatInterval(self.v_model, duration = 0.5,
                quat = (70, -50, 0), startHpr = (0, 0, 0), blendType = 'easeIn'),
                SoundInterval(self.cockBack),
                SoundInterval(self.cockFwd),
                Func(self.resetAmmo),
                Func(self.draw.play),
                LerpQuatInterval(self.v_model, duration = 0.5, quat = (0, 0, 0), startHpr = (70, -50, 0),
                    blendType = 'easeOut'), name = 'reloadTrack')
        self.track.setDoneEvent('reloadTrack')
        self.acceptOnce(self.track.getDoneEvent(), self.aliveFSM.request, ['idle'])
        self.track.start()

    def exitReload(self):
        #self.reload.stop()
        self.ignore('reloadTrack')
        if self.track:
            self.track.finish()
            self.track = None

    def resetAmmo(self):
        if self.weaponName == "pistol":
            self.ammo = 14
        elif self.weaponName == "shotgun":
            self.ammo = 7
        elif self.weaponName == "sniper":
            self.ammo = 7
        self.gui.resetAmmo()

    def resetHp(self):
        self.hp = self.max_hp
        self.gui.adjustHpMeter()

    def enterOff(self):
        pass

    def exitOff(self):
        pass
Exemple #53
0
    def _createMapTextureCard(self):
        mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION)
        mapImage.fill(*self._bgColor)
        fgColor = VBase4D(*self._fgColor)
        for x in xrange(self._mazeHeight):
            for y in xrange(self._mazeWidth):
                if self._mazeCollTable[y][x] == 1:
                    ax = float(x) / self._mazeWidth * MAP_RESOLUTION
                    invertedY = self._mazeHeight - 1 - y
                    ay = float(invertedY) / self._mazeHeight * MAP_RESOLUTION
                    self._drawSquare(mapImage, int(ax), int(ay), 10, fgColor)

        mapTexture = Texture('mapTexture')
        mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution,
                                self._maskResolution, 1, Texture.TUnsignedByte,
                                Texture.FRgba)
        mapTexture.setMinfilter(Texture.FTLinear)
        mapTexture.load(mapImage)
        mapTexture.setWrapU(Texture.WMClamp)
        mapTexture.setWrapV(Texture.WMClamp)
        mapImage.clear()
        del mapImage
        cm = CardMaker('map_cardMaker')
        cm.setFrame(-1.0, 1.0, -1.0, 1.0)
        map = self.attachNewNode(cm.generate())
        map.setTexture(mapTexture, 1)
        return map
Exemple #54
0
class ShaderHeightmapPatch(HeightmapPatch):
    tex_generators = {}
    cachable = False
    def __init__(self, noise, parent,
                 x0, y0, x1, y1,
                 width, height,
                 scale=1.0,
                 coord=TexCoord.Cylindrical, face=0, border=1):
        HeightmapPatch.__init__(self, parent, x0, y0, x1, y1,
                              width, height,
                              scale,
                              coord, face, border)
        self.shader = None
        self.texture = None
        self.texture_peeker = None
        self.noise = noise
        self.tex_generator = None
        self.callback = None
        self.cloned = False
        self.texture_offset = LVector2()
        self.texture_scale = LVector2(1, 1)

    def copy_from(self, heightmap_patch):
        self.cloned = True
        self.lod = heightmap_patch.lod
        self.texture = heightmap_patch.texture
        self.texture_peeker = heightmap_patch.texture_peeker
        self.heightmap_ready = heightmap_patch.heightmap_ready

    def get_height(self, x, y):
        if self.texture_peeker is None:
            print("No peeker", self.patch.str_id(), self.patch.instance_ready)
            traceback.print_stack()
            return 0.0
        try:
            color = LColor()
            #pos = LVector2(x * self.texture_scale[0], ((self.height - 1) - y) * self.texture_scale[1]) + self.texture_offset
            new_x = x * self.texture_scale[0] + self.texture_offset[0] * self.width
            #new_y = y * self.texture_scale[1] + self.texture_offset[1] * self.height
            #new_y = ((self.height - 1) - new_y)
            new_y = ((self.height - 1) - y) * self.texture_scale[1] + self.texture_offset[1] * self.height
            #print(x, y, int(new_x), int(new_y), self.texture_scale, self.texture_offset)
            self.texture_peeker.fetch_pixel(color, min(int(new_x), self.width - 1), min(int(new_y), self.height - 1))
            #self.texture_peeker.fetch_pixel(color, x, y)
            if settings.encode_float:
                height = color[0] + color[1] / 255.0 + color[2] / 65025.0 + color[3] / 16581375.0
            else:
                height = color[0]
        except AssertionError as e:
            #traceback.print_stack()
            #print(e)
            print(x, y)
            print(int(new_x), int(new_y))
            print(((self.height - 1) - y), self.texture_scale[1], ((self.height - 1) - y) * self.texture_scale[1], self.texture_offset[1] * self.height)
            height = 0.0
        #print(height, self.parent.height_scale)
        #TODO: This should be done in PatchedHeightmap.get_height()
        return height * self.parent.height_scale# + self.parent.offset

    def generate(self, callback, cb_args=()):
        if self.texture is None:
            self.texture = Texture()
            self.texture.set_wrap_u(Texture.WMClamp)
            self.texture.set_wrap_v(Texture.WMClamp)
            self.texture.setMinfilter(Texture.FT_linear)
            self.texture.setMagfilter(Texture.FT_linear)
            self._make_heightmap(callback, cb_args)
        else:
            if callback is not None:
                callback(self, *cb_args)

    def heightmap_ready_cb(self, texture, callback, cb_args):
        #print("READY", self.patch.str_id())
        self.texture_peeker = self.texture.peek()
#         if self.texture_peeker is None:
#             print("NOT READY !!!")
        self.heightmap_ready = True
        if callback is not None:
            callback(self, *cb_args)

    def _make_heightmap(self, callback, cb_args):
        if not self.width in ShaderHeightmapPatch.tex_generators:
            ShaderHeightmapPatch.tex_generators[self.width] = GeneratorPool(settings.patch_pool_size)
            if settings.encode_float:
                texture_format = Texture.F_rgba
            else:
                texture_format = Texture.F_r32
            ShaderHeightmapPatch.tex_generators[self.width].make_buffer(self.width, self.height, texture_format)
        tex_generator = ShaderHeightmapPatch.tex_generators[self.width]
        if self.shader is None:
            self.shader = NoiseShader(coord=self.coord,
                                      noise_source=self.noise,
                                      noise_target=FloatTarget(),
                                      offset=(self.x0, self.y0, 0.0),
                                      scale=(self.lod_scale_x, self.lod_scale_y, 1.0))
            self.shader.global_frequency = self.parent.global_frequency
            self.shader.create_and_register_shader(None, None)
        tex_generator.generate(self.shader, self.face, self.texture, self.heightmap_ready_cb, (callback, cb_args))