示例#1
0
 def enable(self):
     camNode = Camera('shadowCam')
     camNode.setCameraMask(CIGlobals.ShadowCameraBitmask)
     self.shadowLens = OrthographicLens()
     self.shadowLens.setFilmSize(60 * 4, 60 * 4)
     camNode.setLens(self.shadowLens)
     self.shadowCamArm = camera.attachNewNode('shadowCamArm')
     self.shadowCam = self.shadowCamArm.attachNewNode(camNode)
     self.shadowCamArm.setPos(0, 40, 0)
     self.shadowCam.setPos(0, -40, 0)
     self.shadowTex = Texture('shadow')
     self.shadowTex.setBorderColor(self.clearColor)
     self.shadowTex.setWrapU(Texture.WMBorderColor)
     self.shadowTex.setWrapV(Texture.WMBorderColor)
     self.casterState = NodePath('temp')
     self.casterState.setColorScaleOff(10)
     self.casterState.setColor(self.shadowColor, self.shadowColor,
                               self.shadowColor, 1, 10)
     self.casterState.setTextureOff(10)
     self.casterState.setLightOff(10)
     self.casterState.setFogOff(10)
     camNode.setInitialState(self.casterState.getState())
     render.hide(CIGlobals.ShadowCameraBitmask)
     self.shadowStage = TextureStage('shadow')
     self.shadowStage.setSort(1000)
     self.turnOnShadows()
示例#2
0
    def _initDepthCapture(self):

        for camera in self.cameras:

            camNode = Camera('Depth camera')
            camNode.setCameraMask(self.cameraMask)
            lens = PerspectiveLens()
            lens.setFov(self.fov)
            lens.setAspectRatio(float(self.size[0]) / float(self.size[1]))
            lens.setNear(self.zNear)
            lens.setFar(self.zFar)
            camNode.setLens(lens)
            camNode.setScene(self.scene.scene)
            cam = camera.attachNewNode(camNode)

            winprops = WindowProperties.size(self.size[0], self.size[1])
            fbprops = FrameBufferProperties.getDefault()
            fbprops = FrameBufferProperties(fbprops)
            fbprops.setRgbColor(False)
            fbprops.setRgbaBits(0, 0, 0, 0)
            fbprops.setStencilBits(0)
            fbprops.setMultisamples(0)
            fbprops.setBackBuffers(0)
            fbprops.setDepthBits(16)

            flags = GraphicsPipe.BFFbPropsOptional
            if self.mode == 'onscreen':
                flags = flags | GraphicsPipe.BFRequireWindow
            elif self.mode == 'offscreen':
                flags = flags | GraphicsPipe.BFRefuseWindow
            else:
                raise Exception('Unsupported rendering mode: %s' % (self.mode))

            buf = self.graphicsEngine.makeOutput(self.pipe, 'Depth buffer', 0,
                                                 fbprops, winprops, flags)
            if buf is None:
                raise Exception('Unable to create depth buffer')

            # Set to render at the end
            buf.setSort(10000)

            dr = buf.makeDisplayRegion()
            dr.setSort(0)
            dr.setCamera(cam)
            dr = camNode.getDisplayRegion(0)

            tex = Texture()
            tex.setFormat(Texture.FDepthComponent)
            tex.setComponentType(Texture.TFloat)
            buf.addRenderTexture(tex, GraphicsOutput.RTMCopyRam,
                                 GraphicsOutput.RTPDepth)
            # XXX: should use tex.setMatchFramebufferFormat(True)?

            agent = camera.getParent()
            self.depthBuffers[agent.getName()] = buf
            self.depthTextures[agent.getName()] = tex
示例#3
0
    def _initRgbCapture(self):

        for camera in self.cameras:

            camNode = Camera('Semantic camera')
            camNode.setCameraMask(self.cameraMask)
            lens = PerspectiveLens()
            lens.setFov(self.fov)
            lens.setAspectRatio(float(self.size[0]) / float(self.size[1]))
            lens.setNear(self.zNear)
            lens.setFar(self.zFar)
            camNode.setLens(lens)
            camNode.setScene(self.scene.scene)
            cam = camera.attachNewNode(camNode)

            winprops = WindowProperties.size(self.size[0], self.size[1])
            fbprops = FrameBufferProperties.getDefault()
            fbprops = FrameBufferProperties(fbprops)
            fbprops.setRgbaBits(8, 8, 8, 8)

            flags = GraphicsPipe.BFFbPropsOptional
            if self.mode == 'onscreen':
                flags = flags | GraphicsPipe.BFRequireWindow
            elif self.mode == 'offscreen':
                flags = flags | GraphicsPipe.BFRefuseWindow
            else:
                raise Exception('Unsupported rendering mode: %s' % (self.mode))

            buf = self.graphicsEngine.makeOutput(self.pipe,
                                                 'RGB-buffer-Semantics', 0,
                                                 fbprops, winprops, flags)
            if buf is None:
                raise Exception('Unable to create RGB buffer')

            # Set to render at the end
            buf.setSort(10000)

            dr = buf.makeDisplayRegion()
            dr.setSort(0)
            dr.setCamera(cam)
            dr = camNode.getDisplayRegion(0)

            tex = Texture()
            tex.setFormat(Texture.FRgba8)
            tex.setComponentType(Texture.TUnsignedByte)
            buf.addRenderTexture(tex, GraphicsOutput.RTMCopyRam,
                                 GraphicsOutput.RTPColor)
            # XXX: should use tex.setMatchFramebufferFormat(True)?

            self.rgbBuffers[camera.getNetTag('agent-id')] = buf
            self.rgbTextures[camera.getNetTag('agent-id')] = tex
    def makeCamera(self,
                   win,
                   sort=0,
                   scene=None,
                   displayRegion=(0, 1, 0, 1),
                   stereo=None,
                   aspectRatio=None,
                   clearDepth=0,
                   clearColor=None,
                   lens=None,
                   camName='cam',
                   mask=None,
                   useCamera=None):
        """
        Makes a new 3-d camera associated with the indicated window,
        and creates a display region in the indicated subrectangle.

        If stereo is True, then a stereo camera is created, with a
        pair of DisplayRegions.  If stereo is False, then a standard
        camera is created.  If stereo is None or omitted, a stereo
        camera is created if the window says it can render in stereo.

        If useCamera is not None, it is a NodePath to be used as the
        camera to apply to the window, rather than creating a new
        camera.
        """
        # self.camera is the parent node of all cameras: a node that
        # we can move around to move all cameras as a group.
        if self.camera == None:
            # We make it a ModelNode with the PTLocal flag, so that
            # a wayward flatten operations won't attempt to mangle the
            # camera.
            self.camera = self.render.attachNewNode(ModelNode('camera'))
            self.camera.node().setPreserveTransform(ModelNode.PTLocal)
            builtins.camera = self.camera

            self.mouse2cam.node().setNode(self.camera.node())

        if useCamera:
            # Use the existing camera node.
            cam = useCamera
            camNode = useCamera.node()
            assert (isinstance(camNode, Camera))
            lens = camNode.getLens()
            cam.reparentTo(self.camera)

        else:
            # Make a new Camera node.
            camNode = Camera(camName)
            if lens == None:
                lens = PerspectiveLens()

                if aspectRatio == None:
                    aspectRatio = self.getAspectRatio(win)
                lens.setAspectRatio(aspectRatio)

            cam = self.camera.attachNewNode(camNode)

        if lens != None:
            camNode.setLens(lens)

        if scene != None:
            camNode.setScene(scene)

        if mask != None:
            if (isinstance(mask, int)):
                mask = BitMask32(mask)
            camNode.setCameraMask(mask)

        if self.cam == None:
            self.cam = cam
            self.camNode = camNode
            self.camLens = lens

        self.camList.append(cam)

        # Now, make a DisplayRegion for the camera.
        if stereo is not None:
            if stereo:
                dr = win.makeStereoDisplayRegion(*displayRegion)
            else:
                dr = win.makeMonoDisplayRegion(*displayRegion)
        else:
            dr = win.makeDisplayRegion(*displayRegion)

        dr.setSort(sort)

        dr.disableClears()

        # By default, we do not clear 3-d display regions (the entire
        # window will be cleared, which is normally sufficient).  But
        # we will if clearDepth is specified.
        if clearDepth:
            dr.setClearDepthActive(1)

        if clearColor:
            dr.setClearColorActive(1)
            dr.setClearColor(clearColor)

        dr.setCamera(cam)

        return cam
示例#5
0
class VoxelizePass(RenderPass):

    """ This pass manages voxelizing the scene from multiple directions to generate
    a 3D voxel grid. It handles the camera setup and provides a simple interface. """

    def __init__(self):
        RenderPass.__init__(self)

    def getID(self):
        return "VoxelizePass"

    def getRequiredInputs(self):
        return {
        }

    def setVoxelGridResolution(self, voxelGridResolution):
        """ Sets the voxel grid resolution, this is the amount of voxels in every
        direction, so the voxel grid will have voxelGridResolution**3 total voxels. """
        self.voxelGridResolution = voxelGridResolution

    def setVoxelGridSize(self, voxelGridSize):
        """ Sets the size of the voxel grid in world space units. This is the
        size going from the mid of the voxel grid, so the effective voxel grid
        will have twice the size specified in voxelGridSize """
        self.voxelGridSize = voxelGridSize

    def setPhotonScaleFactor(self, factor):
        """ Sets the density of the photon grid. A number of 1 means that for
        every bright voxel 1 photon will be spawned. A number of 4 for example
        means that for ever bright voxel 4x4x4 = 64 Photons will be spawned. """
        self.photonScaleFactor = factor

    def setActive(self, active):
        """ Enables and disables this pass """
        self.target.setActive(active)

    def initVoxelStorage(self):
        """ Creates t he 3D Texture to store the voxel generation grid """
        self.voxelGenTex = Texture("VoxelsTemp")
        self.voxelGenTex.setup3dTexture(self.voxelGridResolution.x, self.voxelGridResolution.y, 
                                        self.voxelGridResolution.z, Texture.TInt, Texture.FR32i)

        # Set appropriate filter types
        self.voxelGenTex.setMinfilter(SamplerState.FTNearest)
        self.voxelGenTex.setMagfilter(Texture.FTNearest)
        self.voxelGenTex.setWrapU(Texture.WMClamp)
        self.voxelGenTex.setWrapV(Texture.WMClamp)
        self.voxelGenTex.setWrapW(Texture.WMClamp)
        self.voxelGenTex.setClearColor(Vec4(0))

        # Register texture
        MemoryMonitor.addTexture("Voxel Temp Texture", self.voxelGenTex)

    def getVoxelTex(self):
        """ Returns a handle to the generated voxel texture """
        return self.voxelGenTex

    def clearGrid(self):
        """ Clears the voxel grid """
        self.voxelGenTex.clearImage()

    def create(self):
        # Create voxelize camera
        self.voxelizeCamera = Camera("VoxelizeScene")
        self.voxelizeCamera.setCameraMask(BitMask32.bit(4))
        self.voxelizeCameraNode = Globals.render.attachNewNode(self.voxelizeCamera)
        self.voxelizeLens = OrthographicLens()
        self.voxelizeLens.setFilmSize(self.voxelGridSize.x*2, self.voxelGridSize.y*2)
        self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.x*2)
        self.voxelizeCamera.setLens(self.voxelizeLens)
        self.voxelizeCamera.setTagStateKey("VoxelizePassShader")
        Globals.render.setTag("VoxelizePassShader", "Default")

        # Create voxelize tareet
        self.target = RenderTarget("VoxelizePass")
        self.target.setSize(self.voxelGridResolution.x * self.photonScaleFactor)
        # self.target.setColorWrite(False)
        self.target.addColorTexture()
        self.target.setCreateOverlayQuad(False)
        self.target.setSource(self.voxelizeCameraNode, Globals.base.win)
        self.target.prepareSceneRender()
        self.target.setActive(False)

        self.target.getInternalRegion().setSort(-400)
        self.target.getInternalBuffer().setSort(-399)

    def voxelizeSceneFromDirection(self, gridPos, direction="x"):
        """ Voxelizes the scene from a given direction. This method handles setting 
        the camera position aswell as the near and far plane. If the pass was disabled,
        it also enables this pass.  """
        assert(direction in "x y z".split())
        self.setActive(True)

        if direction == "x":
            self.voxelizeLens.setFilmSize(self.voxelGridSize.y*2, self.voxelGridSize.z*2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.x*2)
            self.voxelizeCameraNode.setPos(gridPos - Vec3(self.voxelGridSize.x, 0, 0))
            self.voxelizeCameraNode.lookAt(gridPos)
        elif direction == "y":
            self.voxelizeLens.setFilmSize(self.voxelGridSize.x*2, self.voxelGridSize.z*2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.y*2)
            self.voxelizeCameraNode.setPos(gridPos - Vec3(0, self.voxelGridSize.y, 0))
            self.voxelizeCameraNode.lookAt(gridPos)
        elif direction == "z":
            self.voxelizeLens.setFilmSize(self.voxelGridSize.x*2, self.voxelGridSize.y*2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize.z*2)
            self.voxelizeCameraNode.setPos(gridPos + Vec3(0, 0, self.voxelGridSize.z))
            self.voxelizeCameraNode.lookAt(gridPos)

    def setShaders(self):
        """ Creates the tag state and loades the voxelizer shader """
        voxelizeShader = Shader.load(Shader.SLGLSL, 
            "Shader/GI/Voxelize.vertex",
            "Shader/GI/Voxelize.fragment")

        # Create tag state
        initialState = NodePath("VoxelizerState")
        initialState.setShader(voxelizeShader, 500)
        initialState.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullNone))
        initialState.setDepthWrite(False)
        initialState.setDepthTest(False)
        initialState.setAttrib(DepthTestAttrib.make(DepthTestAttrib.MNone))
        initialState.setShaderInput("giVoxelGenerationTex", self.voxelGenTex)

        # Apply tag state
        self.voxelizeCamera.setTagState("Default", initialState.getState())

        return [voxelizeShader]

    def getOutputs(self):
        return {
        }
示例#6
0
    def make_camera(self, output, sort=0, dr_dims=(0, 1, 0, 1),
                    aspect_ratio=None, clear_depth=False, clear_color=None,
                    lens=None, cam_name="camera0", mask=None):
        """
        Makes a new 3-d camera associated with the indicated window,
        and creates a display region in the indicated subrectangle.

        If stereo is True, then a stereo camera is created, with a
        pair of DisplayRegions.  If stereo is False, then a standard
        camera is created.  If stereo is None or omitted, a stereo
        camera is created if the window says it can render in stereo.

        If useCamera is not None, it is a NodePath to be used as the
        camera to apply to the window, rather than creating a new
        camera.

        Args:
            output (GraphicsOutput): Output object.

        Keyword Args:
            sort (int): Sort order.
            dr_dims (Iterable, 4): DisplayRegion dimensions.
            aspect_ratio (float): Aspect ratio.
            clear_depth (bool): Indicator to clear depth buffer.
            clear_color (bool): Indicator to clear color buffer.
            lens (Lens): Lens object.
            cam_name (str): Window name.
            mask (BitMask32): Bit mask that indicates which objects to render.

        Return:
            (NodePath): Camera nodepath.

        """

        # self.cameras is the parent node of all cameras: a node that
        # we can move around to move all cameras as a group.
        if self.cameras is None:
            # We make it a ModelNode with the PTLocal flag, so that a
            # wayward flatten operations won't attempt to mangle the
            # camera.
            self.cameras = self.root.attachNewNode(ModelNode("cameras"))
            self.cameras.node().setPreserveTransform(ModelNode.PTLocal)

        # Make a new Camera node.
        cam_node = Camera(cam_name)
        if lens is None:
            lens = PerspectiveLens()
            if aspect_ratio is None:
                aspect_ratio = self.get_aspect_ratio(output)
            lens.setAspectRatio(aspect_ratio)
            lens.setNear(0.1)
            lens.setFar(1000.0)
        if lens is not None:
            cam_node.setLens(lens)
        camera = self.cameras.attachNewNode(cam_node)
        # Masks out part of scene from camera
        if mask is not None:
            if (isinstance(mask, int)):
                mask = BitMask32(mask)
            cam_node.setCameraMask(mask)
        # Make a display region
        dr = output.makeDisplayRegion(*dr_dims)
        # By default, we do not clear 3-d display regions (the entire
        # window will be cleared, which is normally sufficient).  But
        # we will if clearDepth is specified.
        if clear_depth:
            dr.setClearDepthActive(1)
        if clear_color:
            dr.setClearColorActive(1)
            dr.setClearColor(clear_color)
        dr.setSort(sort)
        dr.setCamera(camera)
        dr.setActive(True)
        return camera
示例#7
0
    def __init__(self):
        # Player Model setup
        self.player = Actor("Player",
                            {"Run":"Player-Run",
                            "Sidestep":"Player-Sidestep",
                            "Idle":"Player-Idle"})
        self.player.setBlend(frameBlend = True)
        self.player.setPos(0, 0, 0)
        self.player.pose("Idle", 0)
        self.player.reparentTo(render)
        self.player.hide()

        self.footstep = base.audio3d.loadSfx('footstep.ogg')
        self.footstep.setLoop(True)
        base.audio3d.attachSoundToObject(self.footstep, self.player)

        # Create a brush to paint on the texture
        splat = PNMImage("../data/Splat.png")
        self.colorBrush = PNMBrush.makeImage(splat, 6, 6, 1)

        CamMask = BitMask32.bit(0)
        AvBufMask = BitMask32.bit(1)
        self.avbuf = None
        if base.win:
            self.avbufTex = Texture('avbuf')
            self.avbuf = base.win.makeTextureBuffer('avbuf', 256, 256, self.avbufTex, True)
            cam = Camera('avbuf')
            cam.setLens(base.camNode.getLens())
            self.avbufCam = base.cam.attachNewNode(cam)
            dr = self.avbuf.makeDisplayRegion()
            dr.setCamera(self.avbufCam)
            self.avbuf.setActive(False)
            self.avbuf.setClearColor((1, 0, 0, 1))
            cam.setCameraMask(AvBufMask)
            base.camNode.setCameraMask(CamMask)

            # avbuf renders everything it sees with the gradient texture.
            tex = loader.loadTexture('gradient.png')
            np = NodePath('np')
            np.setTexture(tex, 100)
            np.setColor((1, 1, 1, 1), 100)
            np.setColorScaleOff(100)
            np.setTransparency(TransparencyAttrib.MNone, 100)
            np.setLightOff(100)
            cam.setInitialState(np.getState())
            #render.hide(AvBufMask)

        # Setup a texture stage to paint on the player
        self.paintTs = TextureStage('paintTs')
        self.paintTs.setMode(TextureStage.MDecal)
        self.paintTs.setSort(10)
        self.paintTs.setPriority(10)

        self.tex = Texture('paint_av_%s'%id(self))

        # Setup a PNMImage that will hold the paintable texture of the player
        self.imageSizeX = 64
        self.imageSizeY = 64
        self.p = PNMImage(self.imageSizeX, self.imageSizeY, 4)
        self.p.fill(1)
        self.p.alphaFill(0)
        self.tex.load(self.p)
        self.tex.setWrapU(self.tex.WMClamp)
        self.tex.setWrapV(self.tex.WMClamp)

        # Apply the paintable texture to the avatar
        self.player.setTexture(self.paintTs, self.tex)

        # team
        self.playerTeam = ""
        # A lable that will display the players team
        self.lblTeam = DirectLabel(
            scale = 1,
            pos = (0, 0, 3),
            frameColor = (0, 0, 0, 0),
            text = "TEAM",
            text_align = TextNode.ACenter,
            text_fg = (0,0,0,1))
        self.lblTeam.reparentTo(self.player)
        self.lblTeam.setBillboardPointEye()

        # basic player values
        self.maxHits = 3
        self.currentHits = 0
        self.isOut = False

        self.TorsorControl = self.player.controlJoint(None,"modelRoot","Torsor")

        # setup the collision detection
        # wall and object collision
        self.playerSphere = CollisionSphere(0, 0, 1, 1)
        self.playerCollision = self.player.attachNewNode(CollisionNode("playerCollision%d"%id(self)))
        self.playerCollision.node().addSolid(self.playerSphere)
        base.pusher.addCollider(self.playerCollision, self.player)
        base.cTrav.addCollider(self.playerCollision, base.pusher)
        # foot (walk) collision
        self.playerFootRay = self.player.attachNewNode(CollisionNode("playerFootCollision%d"%id(self)))
        self.playerFootRay.node().addSolid(CollisionRay(0, 0, 2, 0, 0, -1))
        self.playerFootRay.node().setIntoCollideMask(0)
        self.lifter = CollisionHandlerFloor()
        self.lifter.addCollider(self.playerFootRay, self.player)
        base.cTrav.addCollider(self.playerFootRay, self.lifter)

        # Player weapon setup
        self.gunAttach = self.player.exposeJoint(None, "modelRoot", "WeaponSlot_R")
        self.color = LPoint3f(1, 1, 1)
        self.gun = Gun(id(self))
        self.gun.reparentTo(self.gunAttach)
        self.gun.hide()
        self.gun.setColor(self.color)

        self.hud = None

        # Player controls setup
        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0}
        # screen sizes
        self.winXhalf = base.win.getXSize() / 2
        self.winYhalf = base.win.getYSize() / 2
        self.mouseSpeedX = 0.1
        self.mouseSpeedY = 0.1
        # AI controllable variables
        self.AIP = 0.0
        self.AIH = 0.0

        self.movespeed = 5.0

        self.userControlled = False

        self.accept("Bulet-hit-playerCollision%d" % id(self), self.hit)
        self.accept("window-event", self.recalcAspectRatio)
class VoxelizePass(RenderPass):

    """ This pass manages voxelizing the scene from multiple directions to generate
    a 3D voxel grid. It handles the camera setup and provides a simple interface. """

    def __init__(self, pipeline):
        RenderPass.__init__(self)
        self.pipeline = pipeline

    def getID(self):
        return "VoxelizePass"

    def getRequiredInputs(self):
        return {
            # Lighting
            "renderedLightsBuffer": "Variables.renderedLightsBuffer",
            "lights": "Variables.allLights",
            "shadowAtlasPCF": "ShadowScenePass.atlasPCF",
            "shadowAtlas": "ShadowScenePass.atlas",
            "shadowSources": "Variables.allShadowSources",
            "directionToFace": "Variables.directionToFaceLookup",
            "cameraPosition": "Variables.cameraPosition",
            "mainCam": "Variables.mainCam",
            "mainRender": "Variables.mainRender",
        }

    def setVoxelGridResolution(self, voxelGridResolution):
        """ Sets the voxel grid resolution, this is the amount of voxels in every
        direction, so the voxel grid will have voxelGridResolution**3 total voxels. """
        self.voxelGridResolution = voxelGridResolution

    def setVoxelGridSize(self, voxelGridSize):
        """ Sets the size of the voxel grid in world space units. This is the
        size going from the mid of the voxel grid, so the effective voxel grid
        will have twice the size specified in voxelGridSize """
        self.voxelGridSize = voxelGridSize

    def setGridResolutionMultiplier(self, factor):
        """ Sets the density of the voxel grid. """
        self.gridResolutionMultiplier = factor

    def setActive(self, active):
        """ Enables and disables this pass """
        if hasattr(self, "target"):
            self.target.setActive(active)

    def getVoxelTex(self):
        """ Returns a handle to the generated voxel texture """
        return self.voxelGenTex

    def clearGrid(self):
        """ Clears the voxel grid """
        self.voxelGenTex.clearImage()

    def create(self):
        # Create voxelize camera
        self.voxelizeCamera = Camera("VoxelizeCamera")
        self.voxelizeCamera.setCameraMask(BitMask32.bit(4))
        self.voxelizeCameraNode = Globals.render.attachNewNode(self.voxelizeCamera)
        self.voxelizeLens = OrthographicLens()
        self.voxelizeLens.setFilmSize(self.voxelGridSize * 2, self.voxelGridSize * 2)
        self.voxelizeLens.setNearFar(0.0, self.voxelGridSize * 2)
        self.voxelizeCamera.setLens(self.voxelizeLens)
        self.voxelizeCamera.setTagStateKey("VoxelizePassShader")
        Globals.render.setTag("VoxelizePassShader", "Default")

        # Create voxelize tareet
        self.target = RenderTarget("VoxelizePass")
        self.target.setSize(self.voxelGridResolution * self.gridResolutionMultiplier)

        if self.pipeline.settings.useDebugAttachments:
            self.target.addColorTexture()
        else:
            self.target.setColorWrite(False)

        self.target.setCreateOverlayQuad(False)
        self.target.setSource(self.voxelizeCameraNode, Globals.base.win)
        self.target.prepareSceneRender()
        self.target.setActive(False)

        # self.target.getInternalRegion().setSort(-400)
        # self.target.getInternalBuffer().setSort(-399)

    def voxelizeSceneFromDirection(self, gridPos, direction="x"):
        """ Voxelizes the scene from a given direction. This method handles setting 
        the camera position aswell as the near and far plane. If the pass was disabled,
        it also enables this pass.  """
        assert direction in ["x", "y", "z"]
        self.setActive(True)

        if direction == "x":
            self.voxelizeLens.setFilmSize(self.voxelGridSize * 2, self.voxelGridSize * 2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize * 2)
            self.voxelizeCameraNode.setPos(gridPos - Vec3(self.voxelGridSize, 0, 0))
            self.voxelizeCameraNode.lookAt(gridPos)
        elif direction == "y":
            self.voxelizeLens.setFilmSize(self.voxelGridSize * 2, self.voxelGridSize * 2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize * 2)
            self.voxelizeCameraNode.setPos(gridPos - Vec3(0, self.voxelGridSize, 0))
            self.voxelizeCameraNode.lookAt(gridPos)
        elif direction == "z":
            self.voxelizeLens.setFilmSize(self.voxelGridSize * 2, self.voxelGridSize * 2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize * 2)
            self.voxelizeCameraNode.setPos(gridPos + Vec3(0, 0, self.voxelGridSize))
            self.voxelizeCameraNode.lookAt(gridPos)

    def setShaders(self):
        """ Creates the tag state and loades the voxelizer shader """
        self.registerTagState("Default", NodePath("DefaultVoxelizeState"))
        return []

    def registerTagState(self, name, state):
        """ Registers a new tag state """
        state.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullNone))
        state.setDepthWrite(False)
        state.setDepthTest(False)
        state.setAttrib(DepthTestAttrib.make(DepthTestAttrib.MNone))
        state.setShaderInput("voxelizeCam", self.voxelizeCameraNode)
        self.voxelizeCamera.setTagState(name, state.getState())

    def setShaderInput(self, *args):
        Globals.base.render.setShaderInput(*args)

    def getOutputs(self):
        return {}
示例#9
0
class Viewport(QtWidgets.QWidget, DirectObject):

    ClearColor = LEGlobals.vec3GammaToLinear(Vec4(0.361, 0.361, 0.361, 1.0))

    def __init__(self, vpType, window, doc):
        DirectObject.__init__(self)
        QtWidgets.QWidget.__init__(self, window)
        self.doc = doc
        self.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.setMouseTracking(True)

        self.qtWindow = None
        self.qtWidget = None

        self.window = window
        self.type = vpType

        self.spec = VIEWPORT_SPECS[self.type]

        self.lens = None
        self.camNode = None
        self.camera = None
        self.cam = None
        self.win = None
        self.displayRegion = None
        self.mouseWatcher = None
        self.mouseWatcherNp = None
        self.buttonThrower = None
        self.clickRay = None
        self.clickNode = None
        self.clickNp = None
        self.clickQueue = None
        self.tickTask = None
        self.zoom = 1.0
        self.gizmo = None
        self.inputDevice = None
        self.mouseAndKeyboard = None
        self.lastRenderTime = 0.0
        self.enabled = False
        self.needsUpdate = True

        # 2D stuff copied from ShowBase :(
        self.camera2d = None
        self.cam2d = None
        self.render2d = None
        self.aspect2d = None
        self.a2dBackground = None
        self.a2dTop = None
        self.a2dBottom = None
        self.a2dLeft = None
        self.a2dRight = None
        self.a2dTopCenter = None
        self.a2dTopCenterNs = None
        self.a2dBottomCenter = None
        self.a2dBottomCenterNs = None
        self.a2dRightCenter = None
        self.a2dRightCenterNs = None
        self.a2dTopLeft = None
        self.a2dTopLeftNs = None
        self.a2dTopRight = None
        self.a2dTopRightNs = None
        self.a2dBottomLeft = None
        self.a2dBottomLeftNs = None
        self.a2dBottomRight = None
        self.a2dBottomRightNs = None
        self.__oldAspectRatio = None

        self.gridRoot = self.doc.render.attachNewNode("gridRoot")
        self.gridRoot.setLightOff(1)
        #self.gridRoot.setBSPMaterial("phase_14/materials/unlit.mat")
        #self.gridRoot.setDepthWrite(False)
        self.gridRoot.setBin("background", 0)
        self.gridRoot.hide(~self.getViewportMask())

        self.grid = None

    def updateView(self, now=False):
        if now:
            self.renderView()
        else:
            self.needsUpdate = True

    def getGizmoAxes(self):
        raise NotImplementedError

    def getMouseRay(self, collRay=False):
        ray = CollisionRay()
        ray.setFromLens(self.camNode, self.getMouse())
        if collRay:
            return ray
        else:
            return Ray(ray.getOrigin(), ray.getDirection())

    def hasMouse(self):
        return self.mouseWatcher.hasMouse()

    def getMouse(self):
        if self.mouseWatcher.hasMouse():
            return self.mouseWatcher.getMouse()
        return Point2(0, 0)

    def is3D(self):
        return self.type == VIEWPORT_3D

    def is2D(self):
        return self.type != VIEWPORT_3D

    def makeGrid(self):
        raise NotImplementedError

    def getViewportMask(self):
        return BitMask32.bit(self.type)

    def getViewportFullMask(self):
        return self.getViewportMask()

    def makeLens(self):
        raise NotImplementedError

    def getGridAxes(self):
        raise NotImplementedError

    def expand(self, point):
        return point

    def initialize(self):
        self.lens = self.makeLens()
        self.camera = self.doc.render.attachNewNode(
            ModelNode("viewportCameraParent"))
        self.camNode = Camera("viewportCamera")
        self.camNode.setLens(self.lens)
        self.camNode.setCameraMask(self.getViewportMask())
        self.cam = self.camera.attachNewNode(self.camNode)

        winprops = WindowProperties.getDefault()
        winprops.setParentWindow(int(self.winId()))
        winprops.setForeground(False)
        winprops.setUndecorated(True)

        gsg = self.doc.gsg

        output = base.graphicsEngine.makeOutput(
            base.pipe, "viewportOutput", 0, FrameBufferProperties.getDefault(),
            winprops,
            (GraphicsPipe.BFFbPropsOptional | GraphicsPipe.BFRequireWindow),
            gsg)

        self.qtWindow = QtGui.QWindow.fromWinId(
            output.getWindowHandle().getIntHandle())
        self.qtWidget = QtWidgets.QWidget.createWindowContainer(
            self.qtWindow, self, QtCore.Qt.WindowDoesNotAcceptFocus
            | QtCore.Qt.WindowTransparentForInput
            | QtCore.Qt.WindowStaysOnBottomHint
            | QtCore.Qt.BypassWindowManagerHint | QtCore.Qt.SubWindow)  #,
        #(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowDoesNotAcceptFocus
        #| QtCore.Qt.WindowTransparentForInput | QtCore.Qt.BypassWindowManagerHint
        #| QtCore.Qt.SubWindow | QtCore.Qt.WindowStaysOnBottomHint))
        self.qtWidget.setFocusPolicy(QtCore.Qt.NoFocus)

        self.inputDevice = output.getInputDevice(0)

        assert output is not None, "Unable to create viewport output!"

        dr = output.makeDisplayRegion()
        dr.disableClears()
        dr.setCamera(self.cam)
        self.displayRegion = dr

        output.disableClears()
        output.setClearColor(Viewport.ClearColor)
        output.setClearColorActive(True)
        output.setClearDepthActive(True)
        output.setActive(True)

        self.win = output

        # keep track of the mouse in this viewport
        mak = MouseAndKeyboard(self.win, 0, "mouse")
        mouse = base.dataRoot.attachNewNode(mak)
        self.mouseAndKeyboard = mouse
        self.mouseWatcher = MouseWatcher()
        self.mouseWatcher.setDisplayRegion(self.displayRegion)
        mw = mouse.attachNewNode(self.mouseWatcher)
        self.mouseWatcherNp = mw

        # listen for keyboard and mouse events in this viewport
        bt = ButtonThrower("kbEvents")
        bt.setButtonDownEvent("btndown")
        bt.setButtonUpEvent("btnup")
        mods = ModifierButtons()
        mods.addButton(KeyboardButton.shift())
        mods.addButton(KeyboardButton.control())
        mods.addButton(KeyboardButton.alt())
        mods.addButton(KeyboardButton.meta())
        bt.setModifierButtons(mods)
        self.buttonThrower = mouse.attachNewNode(bt)

        # collision objects for clicking on objects from this viewport
        self.clickRay = CollisionRay()
        self.clickNode = CollisionNode("viewportClickRay")
        self.clickNode.addSolid(self.clickRay)
        self.clickNp = NodePath(self.clickNode)
        self.clickQueue = CollisionHandlerQueue()

        self.setupRender2d()
        self.setupCamera2d()

        self.gizmo = ViewportGizmo(self)

        self.doc.viewportMgr.addViewport(self)

        self.makeGrid()

    def cleanup(self):
        self.grid.cleanup()
        self.grid = None
        self.gridRoot.removeNode()
        self.gridRoot = None

        self.lens = None
        self.camNode = None
        self.cam.removeNode()
        self.cam = None
        self.camera.removeNode()
        self.camera = None
        self.spec = None
        self.doc = None
        self.type = None
        self.window = None
        self.zoom = None
        self.gizmo.cleanup()
        self.gizmo = None
        self.clickNp.removeNode()
        self.clickNp = None
        self.clickQueue.clearEntries()
        self.clickQueue = None
        self.clickNode = None
        self.clickRay = None
        self.buttonThrower.removeNode()
        self.buttonThrower = None
        self.inputDevice = None
        self.mouseWatcherNp.removeNode()
        self.mouseWatcherNp = None
        self.mouseWatcher = None
        self.mouseAndKeyboard.removeNode()
        self.mouseAndKeyboard = None
        self.win.removeAllDisplayRegions()
        self.displayRegion = None
        base.graphicsEngine.removeWindow(self.win)
        self.win = None

        self.camera2d.removeNode()
        self.camera2d = None
        self.cam2d = None

        self.render2d.removeNode()
        self.render2d = None

        self.a2dBackground = None
        self.a2dTop = None
        self.a2dBottom = None
        self.a2dLeft = None
        self.a2dRight = None
        self.aspect2d = None
        self.a2dTopCenter = None
        self.a2dTopCenterNs = None
        self.a2dBottomCenter = None
        self.a2dBottomCenterNs = None
        self.a2dLeftCenter = None
        self.a2dLeftCenterNs = None
        self.a2dRightCenter = None
        self.a2dRightCenterNs = None

        self.a2dTopLeft = None
        self.a2dTopLeftNs = None
        self.a2dTopRight = None
        self.a2dTopRightNs = None
        self.a2dBottomLeft = None
        self.a2dBottomLeftNs = None
        self.a2dBottomRight = None
        self.a2dBottomRightNs = None
        self.__oldAspectRatio = None

        self.qtWindow.deleteLater()
        self.qtWidget.deleteLater()
        self.qtWindow = None
        self.qtWidget = None

        self.deleteLater()

    def keyPressEvent(self, event):
        button = LEUtils.keyboardButtonFromQtKey(event.key())
        if button:
            self.inputDevice.buttonDown(button)

    def keyReleaseEvent(self, event):
        button = LEUtils.keyboardButtonFromQtKey(event.key())
        if button:
            self.inputDevice.buttonUp(button)

    def enterEvent(self, event):
        # Give ourselves focus.
        self.setFocus()
        QtWidgets.QWidget.enterEvent(self, event)

    def mouseMoveEvent(self, event):
        self.inputDevice.setPointerInWindow(event.pos().x(), event.pos().y())
        QtWidgets.QWidget.mouseMoveEvent(self, event)

    def leaveEvent(self, event):
        self.clearFocus()
        self.inputDevice.setPointerOutOfWindow()
        self.inputDevice.focusLost()
        QtWidgets.QWidget.leaveEvent(self, event)

    def mousePressEvent(self, event):
        btn = event.button()
        if btn == QtCore.Qt.LeftButton:
            self.inputDevice.buttonDown(MouseButton.one())
        elif btn == QtCore.Qt.MiddleButton:
            self.inputDevice.buttonDown(MouseButton.two())
        elif btn == QtCore.Qt.RightButton:
            self.inputDevice.buttonDown(MouseButton.three())
        QtWidgets.QWidget.mousePressEvent(self, event)

    def mouseReleaseEvent(self, event):
        btn = event.button()
        if btn == QtCore.Qt.LeftButton:
            self.inputDevice.buttonUp(MouseButton.one())
        elif btn == QtCore.Qt.MiddleButton:
            self.inputDevice.buttonUp(MouseButton.two())
        elif btn == QtCore.Qt.RightButton:
            self.inputDevice.buttonUp(MouseButton.three())
        QtWidgets.QWidget.mouseReleaseEvent(self, event)

    def wheelEvent(self, event):
        ang = event.angleDelta().y()
        if ang > 0:
            self.inputDevice.buttonDown(MouseButton.wheelUp())
            self.inputDevice.buttonUp(MouseButton.wheelUp())
        else:
            self.inputDevice.buttonDown(MouseButton.wheelDown())
            self.inputDevice.buttonUp(MouseButton.wheelDown())
        QtWidgets.QWidget.wheelEvent(self, event)

    def getAspectRatio(self):
        return self.win.getXSize() / self.win.getYSize()

    def setupRender2d(self):
        ## This is the root of the 2-D scene graph.
        self.render2d = NodePath("viewport-render2d")

        # Set up some overrides to turn off certain properties which
        # we probably won't need for 2-d objects.

        # It's probably important to turn off the depth test, since
        # many 2-d objects will be drawn over each other without
        # regard to depth position.

        # We used to avoid clearing the depth buffer before drawing
        # render2d, but nowadays we clear it anyway, since we
        # occasionally want to put 3-d geometry under render2d, and
        # it's simplest (and seems to be easier on graphics drivers)
        # if the 2-d scene has been cleared first.

        self.render2d.setDepthTest(0)
        self.render2d.setDepthWrite(0)
        self.render2d.setMaterialOff(1)
        self.render2d.setTwoSided(1)

        self.aspect2d = self.render2d.attachNewNode("viewport-aspect2d")

        aspectRatio = self.getAspectRatio()
        self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0)

        self.a2dBackground = self.aspect2d.attachNewNode("a2dBackground")

        ## The Z position of the top border of the aspect2d screen.
        self.a2dTop = 1.0
        ## The Z position of the bottom border of the aspect2d screen.
        self.a2dBottom = -1.0
        ## The X position of the left border of the aspect2d screen.
        self.a2dLeft = -aspectRatio
        ## The X position of the right border of the aspect2d screen.
        self.a2dRight = aspectRatio

        self.a2dTopCenter = self.aspect2d.attachNewNode("a2dTopCenter")
        self.a2dTopCenterNs = self.aspect2d.attachNewNode("a2dTopCenterNS")
        self.a2dBottomCenter = self.aspect2d.attachNewNode("a2dBottomCenter")
        self.a2dBottomCenterNs = self.aspect2d.attachNewNode(
            "a2dBottomCenterNS")
        self.a2dLeftCenter = self.aspect2d.attachNewNode("a2dLeftCenter")
        self.a2dLeftCenterNs = self.aspect2d.attachNewNode("a2dLeftCenterNS")
        self.a2dRightCenter = self.aspect2d.attachNewNode("a2dRightCenter")
        self.a2dRightCenterNs = self.aspect2d.attachNewNode("a2dRightCenterNS")

        self.a2dTopLeft = self.aspect2d.attachNewNode("a2dTopLeft")
        self.a2dTopLeftNs = self.aspect2d.attachNewNode("a2dTopLeftNS")
        self.a2dTopRight = self.aspect2d.attachNewNode("a2dTopRight")
        self.a2dTopRightNs = self.aspect2d.attachNewNode("a2dTopRightNS")
        self.a2dBottomLeft = self.aspect2d.attachNewNode("a2dBottomLeft")
        self.a2dBottomLeftNs = self.aspect2d.attachNewNode("a2dBottomLeftNS")
        self.a2dBottomRight = self.aspect2d.attachNewNode("a2dBottomRight")
        self.a2dBottomRightNs = self.aspect2d.attachNewNode("a2dBottomRightNS")

        # Put the nodes in their places
        self.a2dTopCenter.setPos(0, 0, self.a2dTop)
        self.a2dTopCenterNs.setPos(0, 0, self.a2dTop)
        self.a2dBottomCenter.setPos(0, 0, self.a2dBottom)
        self.a2dBottomCenterNs.setPos(0, 0, self.a2dBottom)
        self.a2dLeftCenter.setPos(self.a2dLeft, 0, 0)
        self.a2dLeftCenterNs.setPos(self.a2dLeft, 0, 0)
        self.a2dRightCenter.setPos(self.a2dRight, 0, 0)
        self.a2dRightCenterNs.setPos(self.a2dRight, 0, 0)

        self.a2dTopLeft.setPos(self.a2dLeft, 0, self.a2dTop)
        self.a2dTopLeftNs.setPos(self.a2dLeft, 0, self.a2dTop)
        self.a2dTopRight.setPos(self.a2dRight, 0, self.a2dTop)
        self.a2dTopRightNs.setPos(self.a2dRight, 0, self.a2dTop)
        self.a2dBottomLeft.setPos(self.a2dLeft, 0, self.a2dBottom)
        self.a2dBottomLeftNs.setPos(self.a2dLeft, 0, self.a2dBottom)
        self.a2dBottomRight.setPos(self.a2dRight, 0, self.a2dBottom)
        self.a2dBottomRightNs.setPos(self.a2dRight, 0, self.a2dBottom)

    def setupCamera2d(self,
                      sort=10,
                      displayRegion=(0, 1, 0, 1),
                      coords=(-1, 1, -1, 1)):
        dr = self.win.makeMonoDisplayRegion(*displayRegion)
        dr.setSort(10)

        # Enable clearing of the depth buffer on this new display
        # region (see the comment in setupRender2d, above).
        dr.setClearDepthActive(1)

        # Make any texture reloads on the gui come up immediately.
        dr.setIncompleteRender(False)

        left, right, bottom, top = coords

        # Now make a new Camera node.
        cam2dNode = Camera('cam2d')

        lens = OrthographicLens()
        lens.setFilmSize(right - left, top - bottom)
        lens.setFilmOffset((right + left) * 0.5, (top + bottom) * 0.5)
        lens.setNearFar(-1000, 1000)
        cam2dNode.setLens(lens)

        # self.camera2d is the analog of self.camera, although it's
        # not as clear how useful it is.
        self.camera2d = self.render2d.attachNewNode('camera2d')

        camera2d = self.camera2d.attachNewNode(cam2dNode)
        dr.setCamera(camera2d)

        self.cam2d = camera2d

        return camera2d

    def mouse1Up(self):
        pass

    def mouse1Down(self):
        pass

    def mouse2Up(self):
        pass

    def mouse2Down(self):
        pass

    def mouse3Up(self):
        pass

    def mouse3Down(self):
        pass

    def mouseEnter(self):
        self.updateView()

    def mouseExit(self):
        pass

    def mouseMove(self):
        pass

    def wheelUp(self):
        pass

    def wheelDown(self):
        pass

    def shouldRender(self):
        if not self.enabled:
            return False

        now = globalClock.getRealTime()
        if self.lastRenderTime != 0:
            elapsed = now - self.lastRenderTime
            if elapsed <= 0:
                return False

            frameRate = 1 / elapsed
            if frameRate > 100.0:
                # Never render faster than 100Hz
                return False

        return self.needsUpdate

    def renderView(self):
        self.lastRenderTime = globalClock.getRealTime()
        self.needsUpdate = False
        #self.win.setActive(1)
        base.requestRender()

    def tick(self):
        if self.shouldRender():
            self.renderView()
        else:
            pass
            #self.win.setActive(0)

    def getViewportName(self):
        return self.spec.name

    def getViewportCenterPixels(self):
        return LPoint2i(self.win.getXSize() // 2, self.win.getYSize() // 2)

    def centerCursor(self, cursor):
        center = self.getViewportCenterPixels()
        cursor.setPos(
            self.mapToGlobal(QtCore.QPoint(self.width() / 2,
                                           self.height() / 2)))
        self.inputDevice.setPointerInWindow(center.x, center.y)

    def viewportToWorld(self, viewport, vec=False):
        front = Point3()
        back = Point3()
        self.lens.extrude(viewport, front, back)
        world = (front + back) / 2

        worldMat = self.cam.getMat(render)
        if vec:
            world = worldMat.xformVec(world)
        else:
            world = worldMat.xformPoint(world)

        return world

    def worldToViewport(self, world):
        # move into local camera space
        invMat = Mat4(self.cam.getMat(render))
        invMat.invertInPlace()

        local = invMat.xformPoint(world)

        point = Point2()
        self.lens.project(local, point)

        return point

    def zeroUnusedCoordinate(self, vec):
        pass

    def click(self, mask, queue=None, traverser=None, root=None):
        if not self.mouseWatcher.hasMouse():
            return None

        if not queue:
            queue = self.clickQueue

        self.clickRay.setFromLens(self.camNode, self.mouseWatcher.getMouse())
        self.clickNode.setFromCollideMask(mask)
        self.clickNode.setIntoCollideMask(BitMask32.allOff())
        self.clickNp.reparentTo(self.cam)
        queue.clearEntries()
        if not traverser:
            base.clickTraverse(self.clickNp, queue)
        else:
            if not root:
                root = self.doc.render
            traverser.addCollider(self.clickNp, queue)
            traverser.traverse(root)
            traverser.removeCollider(self.clickNp)
        queue.sortEntries()
        self.clickNp.reparentTo(NodePath())

        return queue.getEntries()

    def fixRatio(self, size=None):
        if not self.lens:
            return

        if size is None:
            aspectRatio = self.win.getXSize() / self.win.getYSize()
        else:
            if size.y > 0:
                aspectRatio = size.x / size.y
            else:
                aspectRatio = 1.0

        if self.is2D():
            zoomFactor = (1.0 / self.zoom) * 100.0
            self.lens.setFilmSize(zoomFactor * aspectRatio, zoomFactor)
        else:
            self.lens.setAspectRatio(aspectRatio)

        if aspectRatio != self.__oldAspectRatio:
            self.__oldAspectRatio = aspectRatio
            # Fix up some anything that depends on the aspectRatio
            if aspectRatio < 1:
                # If the window is TALL, lets expand the top and bottom
                self.aspect2d.setScale(1.0, aspectRatio, aspectRatio)
                self.a2dTop = 1.0 / aspectRatio
                self.a2dBottom = -1.0 / aspectRatio
                self.a2dLeft = -1
                self.a2dRight = 1.0
            else:
                # If the window is WIDE, lets expand the left and right
                self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0)
                self.a2dTop = 1.0
                self.a2dBottom = -1.0
                self.a2dLeft = -aspectRatio
                self.a2dRight = aspectRatio

            # Reposition the aspect2d marker nodes
            self.a2dTopCenter.setPos(0, 0, self.a2dTop)
            self.a2dTopCenterNs.setPos(0, 0, self.a2dTop)
            self.a2dBottomCenter.setPos(0, 0, self.a2dBottom)
            self.a2dBottomCenterNs.setPos(0, 0, self.a2dBottom)
            self.a2dLeftCenter.setPos(self.a2dLeft, 0, 0)
            self.a2dLeftCenterNs.setPos(self.a2dLeft, 0, 0)
            self.a2dRightCenter.setPos(self.a2dRight, 0, 0)
            self.a2dRightCenterNs.setPos(self.a2dRight, 0, 0)

            self.a2dTopLeft.setPos(self.a2dLeft, 0, self.a2dTop)
            self.a2dTopLeftNs.setPos(self.a2dLeft, 0, self.a2dTop)
            self.a2dTopRight.setPos(self.a2dRight, 0, self.a2dTop)
            self.a2dTopRightNs.setPos(self.a2dRight, 0, self.a2dTop)
            self.a2dBottomLeft.setPos(self.a2dLeft, 0, self.a2dBottom)
            self.a2dBottomLeftNs.setPos(self.a2dLeft, 0, self.a2dBottom)
            self.a2dBottomRight.setPos(self.a2dRight, 0, self.a2dBottom)
            self.a2dBottomRightNs.setPos(self.a2dRight, 0, self.a2dBottom)

    def resizeEvent(self, event):
        if not self.win:
            return

        newsize = LVector2i(event.size().width(), event.size().height())
        self.qtWidget.resize(newsize[0], newsize[1])
        self.qtWidget.move(0, 0)

        #props = WindowProperties()
        #props.setSize(newsize)
        #props.setOrigin(0, 0)
        #self.win.requestProperties(props)

        self.fixRatio(newsize)

        self.onResize(newsize)

        self.updateView()

    def onResize(self, newsize):
        pass

    def draw(self):
        pass

    def enable(self):
        # Render to the viewport
        self.win.setActive(True)
        self.enabled = True

    def disable(self):
        # Don't render to the viewport
        self.win.setActive(False)
        self.enabled = False
示例#10
0
    def create(self):
        # Create the atlas target
        self.target = RenderTarget("ShadowAtlas")
        self.target.setSize(self.size)
        self.target.addDepthTexture()
        self.target.setDepthBits(32)
        self.target.setColorWrite(False)
        self.target.setCreateOverlayQuad(False)
        # self.target.setActive(False)
        self.target.setSource(
            NodePath(Camera("tmp")), Globals.base.win)

        self.target.prepareSceneRender()
        self.target.setClearDepth(False)


        # Set the appropriate filter modes
        dTex = self.target.getDepthTexture()
        dTex.setWrapU(SamplerState.WMClamp)
        dTex.setWrapV(SamplerState.WMClamp)

        # Remove the default postprocess quad
        # self.target.getQuad().node().removeAllChildren()
        # self.target.getInternalRegion().setSort(-200)
        self.target.getInternalRegion().disableClears()
        self.target.getInternalBuffer().disableClears()
        # self.target.getInternalBuffer().setSort(-300)


        # Create default initial state
        initialState = NodePath("InitialState")
        initialState.setAttrib(ColorWriteAttrib.make(ColorWriteAttrib.COff))

        # Create a camera for each update
        self.shadowCameras = []
        for i in xrange(self.maxRegions):
            shadowCam = Camera("ShadowComputeCamera")
            shadowCam.setTagStateKey("ShadowPassShader")
            shadowCam.setInitialState(initialState.getState())
            shadowCam.setCameraMask(BitMask32.bit(3))
            shadowCamNode = self.shadowScene.attachNewNode(shadowCam)
            self.shadowCameras.append(shadowCamNode)

        # Create regions
        self.renderRegions = []
        buff = self.target.getInternalBuffer()
        
        for i in xrange(self.maxRegions):
            dr = buff.makeDisplayRegion()
            dr.setSort(1000)
            dr.setClearDepthActive(True)
            dr.setClearDepth(1.0)
            # dr.setClearColorActive(False)
            # dr.setClearColor(Vec4(1,1,1,1))
            dr.setCamera(self.shadowCameras[i])
            dr.setActive(False)
            self.renderRegions.append(dr)

        self.pcfSampleState = SamplerState()
        self.pcfSampleState.setMinfilter(SamplerState.FTShadow)
        self.pcfSampleState.setMagfilter(SamplerState.FTShadow)
        self.pcfSampleState.setWrapU(SamplerState.WMClamp)
        self.pcfSampleState.setWrapV(SamplerState.WMClamp)
示例#11
0
class VoxelizePass(RenderPass):
    """ This pass manages voxelizing the scene from multiple directions to generate
    a 3D voxel grid. It handles the camera setup and provides a simple interface. """
    def __init__(self, pipeline):
        RenderPass.__init__(self)
        self.pipeline = pipeline

    def getID(self):
        return "VoxelizePass"

    def getRequiredInputs(self):
        return {

            # Lighting
            "renderedLightsBuffer": "Variables.renderedLightsBuffer",
            "lights": "Variables.allLights",
            "shadowAtlasPCF": "ShadowScenePass.atlasPCF",
            "shadowAtlas": "ShadowScenePass.atlas",
            "shadowSources": "Variables.allShadowSources",
            "directionToFace": "Variables.directionToFaceLookup",
            "cameraPosition": "Variables.cameraPosition",
            "mainCam": "Variables.mainCam",
            "mainRender": "Variables.mainRender",
        }

    def setVoxelGridResolution(self, voxelGridResolution):
        """ Sets the voxel grid resolution, this is the amount of voxels in every
        direction, so the voxel grid will have voxelGridResolution**3 total voxels. """
        self.voxelGridResolution = voxelGridResolution

    def setVoxelGridSize(self, voxelGridSize):
        """ Sets the size of the voxel grid in world space units. This is the
        size going from the mid of the voxel grid, so the effective voxel grid
        will have twice the size specified in voxelGridSize """
        self.voxelGridSize = voxelGridSize

    def setGridResolutionMultiplier(self, factor):
        """ Sets the density of the voxel grid. """
        self.gridResolutionMultiplier = factor

    def setActive(self, active):
        """ Enables and disables this pass """
        if hasattr(self, "target"):
            self.target.setActive(active)

    def getVoxelTex(self):
        """ Returns a handle to the generated voxel texture """
        return self.voxelGenTex

    def clearGrid(self):
        """ Clears the voxel grid """
        self.voxelGenTex.clearImage()

    def create(self):
        # Create voxelize camera
        self.voxelizeCamera = Camera("VoxelizeCamera")
        self.voxelizeCamera.setCameraMask(BitMask32.bit(4))
        self.voxelizeCameraNode = Globals.render.attachNewNode(
            self.voxelizeCamera)
        self.voxelizeLens = OrthographicLens()
        self.voxelizeLens.setFilmSize(self.voxelGridSize * 2,
                                      self.voxelGridSize * 2)
        self.voxelizeLens.setNearFar(0.0, self.voxelGridSize * 2)
        self.voxelizeCamera.setLens(self.voxelizeLens)
        self.voxelizeCamera.setTagStateKey("VoxelizePassShader")
        Globals.render.setTag("VoxelizePassShader", "Default")

        # Create voxelize tareet
        self.target = RenderTarget("VoxelizePass")
        self.target.setSize(self.voxelGridResolution *
                            self.gridResolutionMultiplier)

        if self.pipeline.settings.useDebugAttachments:
            self.target.addColorTexture()
        else:
            self.target.setColorWrite(False)

        self.target.setCreateOverlayQuad(False)
        self.target.setSource(self.voxelizeCameraNode, Globals.base.win)
        self.target.prepareSceneRender()
        self.target.setActive(False)

        # self.target.getInternalRegion().setSort(-400)
        # self.target.getInternalBuffer().setSort(-399)

    def voxelizeSceneFromDirection(self, gridPos, direction="x"):
        """ Voxelizes the scene from a given direction. This method handles setting 
        the camera position aswell as the near and far plane. If the pass was disabled,
        it also enables this pass.  """
        assert (direction in ["x", "y", "z"])
        self.setActive(True)

        if direction == "x":
            self.voxelizeLens.setFilmSize(self.voxelGridSize * 2,
                                          self.voxelGridSize * 2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize * 2)
            self.voxelizeCameraNode.setPos(gridPos -
                                           Vec3(self.voxelGridSize, 0, 0))
            self.voxelizeCameraNode.lookAt(gridPos)
        elif direction == "y":
            self.voxelizeLens.setFilmSize(self.voxelGridSize * 2,
                                          self.voxelGridSize * 2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize * 2)
            self.voxelizeCameraNode.setPos(gridPos -
                                           Vec3(0, self.voxelGridSize, 0))
            self.voxelizeCameraNode.lookAt(gridPos)
        elif direction == "z":
            self.voxelizeLens.setFilmSize(self.voxelGridSize * 2,
                                          self.voxelGridSize * 2)
            self.voxelizeLens.setNearFar(0.0, self.voxelGridSize * 2)
            self.voxelizeCameraNode.setPos(gridPos +
                                           Vec3(0, 0, self.voxelGridSize))
            self.voxelizeCameraNode.lookAt(gridPos)

    def setShaders(self):
        """ Creates the tag state and loades the voxelizer shader """
        self.registerTagState("Default", NodePath("DefaultVoxelizeState"))
        return []

    def registerTagState(self, name, state):
        """ Registers a new tag state """
        state.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullNone))
        state.setDepthWrite(False)
        state.setDepthTest(False)
        state.setAttrib(DepthTestAttrib.make(DepthTestAttrib.MNone))
        state.setShaderInput("voxelizeCam", self.voxelizeCameraNode)
        self.voxelizeCamera.setTagState(name, state.getState())

    def setShaderInput(self, *args):
        Globals.base.render.setShaderInput(*args)

    def getOutputs(self):
        return {}