示例#1
0
class CameraController(DirectObject):

    def __init__(self, base, r, theta, phi):
        DirectObject.__init__(self)
        self.base = base

        # Parameters
        self.rotateMag = 0.5
        self.moveMag = 50
        self.zoomMag = 100

        # Camera properties
        self.r = r
        self.theta = theta
        self.phi = phi
        self.target = NodePath("target")
        self.target.reparentTo(self.base.render)
        self.base.camera.reparentTo(self.target)
        self.followingObject = None

        # Controls
        self.mouseDown1 = False
        self.mouseDown2 = False
        self.mouseDown3 = False
        self.mousePrevX = 0.0
        self.mousePrevY = 0.0
        self.accept("mouse1", self.onMouse1, [True])
        self.accept("mouse1-up", self.onMouse1, [False])
        self.accept("mouse2", self.onMouse2, [True])
        self.accept("mouse2-up", self.onMouse2, [False])
        self.accept("mouse3", self.onMouse3, [True])
        self.accept("mouse3-up", self.onMouse3, [False])

        # Run task that updates camera
        self.base.taskMgr.add(self.updateCamera, "UpdateCameraTask", priority=1)

    def setTarget(self, parent):
        self.target.reparentTo(parent)

    def follow(self, obj):
        self.followingObject = obj

    def stopFollowing(self):
        self.followingObject = None

    def zoom(self, dR):
        self.r += dR
        if self.r < 0.0:
            self.r = 0.0

    def rotateTheta(self, dTheta):
        self.theta += dTheta
        if self.theta < 0.0:
            self.theta += 2 * math.pi
        if self.theta > 2 * math.pi:
            self.theta -= 2 * math.pi

    def rotatePhi(self, dPhi):
        self.phi += dPhi
        if self.phi < 0.1:
            self.phi = 0.1
        if self.phi > math.pi-0.1:
            self.phi = math.pi-0.1

    def onMouse1(self, down):
        if not self.mouseDown2 and not self.mouseDown3:
            if down and self.base.mouseWatcherNode.hasMouse():
                self.mouseDown1 = True
                self.mousePrevX = self.base.mouseWatcherNode.getMouseX()
                self.mousePrevY = self.base.mouseWatcherNode.getMouseY()
            else:
                self.mouseDown1 = False

    def onMouse2(self, down):
        if not self.mouseDown1 and not self.mouseDown3:
            if down and self.base.mouseWatcherNode.hasMouse():
                self.mouseDown2 = True
                self.mousePrevX = self.base.mouseWatcherNode.getMouseX()
                self.mousePrevY = self.base.mouseWatcherNode.getMouseY()
            else:
                self.mouseDown2 = False

    def onMouse3(self, down):
        if not self.mouseDown1 and not self.mouseDown2:
            if down and self.base.mouseWatcherNode.hasMouse():
                self.mouseDown3 = True
                self.mousePrevX = self.base.mouseWatcherNode.getMouseX()
                self.mousePrevY = self.base.mouseWatcherNode.getMouseY()
            else:
                self.mouseDown3 = False

    def updateCamera(self, task):
        if self.base.mouseWatcherNode.hasMouse():
            # Register camera controls
            mouseX = self.base.mouseWatcherNode.getMouseX()
            mouseY = self.base.mouseWatcherNode.getMouseY()
            dX = self.mousePrevX - mouseX
            dY = self.mousePrevY - mouseY

            if self.mouseDown1:
                self.rotateTheta(dX * math.pi * self.rotateMag)
                self.rotatePhi(-dY * math.pi * self.rotateMag)

            if self.mouseDown2 and self.followingObject is None:
                vecX = self.target.getRelativeVector(self.base.camera, Vec3.right())
                vecY = self.target.getRelativeVector(self.base.camera, Vec3.forward())
                vecY.setZ(0.0)
                vecY.normalize()
                offset = (vecX * dX * self.moveMag) + (vecY * dY * self.moveMag)
                self.target.setPos(self.target, offset)

            if self.followingObject is not None:
                self.target.setPos(self.followingObject.getPos())

            if self.mouseDown3:
                self.zoom(dY * self.zoomMag)

            self.mousePrevX = mouseX
            self.mousePrevY = mouseY

            # Update camera position
            position = Point3(0.0, 0.0, 0.0)
            position.setX(self.r * math.cos(self.theta) * math.sin(self.phi))
            position.setY(self.r * math.sin(self.theta) * math.sin(self.phi))
            position.setZ(self.r * math.cos(self.phi))
            self.base.camera.setPos(position)
            self.base.camera.lookAt(self.target)

        return task.cont
示例#2
0
class CameraController(DirectObject):
    def __init__(self, base, r, theta, phi):
        DirectObject.__init__(self)
        self.base = base

        # Parameters
        self.rotateMag = 0.5
        self.moveMag = 50
        self.zoomMag = 15

        # Camera properties
        self.r = r
        self.theta = theta
        self.phi = phi

        self.target = NodePath("target")
        self.target.reparentTo(self.base.render)
        self.base.camera.reparentTo(self.target)

        # Controls
        self.mouseDown1 = False
        self.mouseDown2 = False
        self.mouseDown3 = False
        self.mousePrevX = 0.0
        self.mousePrevY = 0.0

        self.updateCamera(0, 0)

    def setTarget(self, parent):
        self.target.reparentTo(parent)

    def rotateTheta(self, value):
        self._rotateTheta(value)
        self.updateCamera(self.mousePrevX, self.mousePrevY)

    def rotatePhi(self, value):
        self._rotatePhi_for_scroll(math.radians(value))
        self.updateCamera(self.mousePrevX, self.mousePrevY)

    def mouse_press(self, button, x, y):
        self.mouseDown1 = True if button == Qt.LeftButton else self.mouseDown1
        self.mouseDown2 = True if button == Qt.RightButton else self.mouseDown2
        self.mouseDown3 = True if button == Qt.MiddleButton else self.mouseDown3

        self.mousePrevX = x
        self.mousePrevY = y

        self.updateCamera(x, y)

    def mouse_release(self, button, x, y):
        self.mouseDown1 = False if button == Qt.LeftButton else self.mouseDown1
        self.mouseDown2 = False if button == Qt.RightButton else self.mouseDown2
        self.mouseDown3 = False if button == Qt.MiddleButton else self.mouseDown3

        self.mousePrevX = x
        self.mousePrevY = y

    def mouse_move(self, button, x, y):
        self.updateCamera(x, y)

    def zoom_event(self, delta):
        self.zoom(delta)
        self.updateCamera(self.mousePrevX, self.mousePrevY)

    def updateCamera(self, x, y):
        factor = 0.01
        dX = (self.mousePrevX - x) * factor
        dY = (self.mousePrevY - y) * factor

        if self.mouseDown1:
            self._rotateTheta(dX * math.pi * self.rotateMag)
            self._rotatePhi(-dY * math.pi * self.rotateMag)

        if self.mouseDown2:
            vecX = self.target.getRelativeVector(self.base.camera,
                                                 Vec3.right())
            vecY = self.target.getRelativeVector(self.base.camera,
                                                 Vec3.forward())
            vecY.setZ(0.0)
            vecY.normalize()
            offset = (vecX * dX * self.moveMag) + (vecY * dY * self.moveMag)
            self.target.setPos(self.target, offset)

        if self.mouseDown3:
            self.zoom(dY * self.zoomMag)

        self.mousePrevX = x
        self.mousePrevY = y

        # Update camera position
        position = Point3(0.0, 0.0, 0.0)
        position.setX(self.r * math.cos(self.theta) * math.sin(self.phi))
        position.setY(self.r * math.sin(self.theta) * math.sin(self.phi))
        position.setZ(self.r * math.cos(self.phi))
        self.base.camera.setPos(position)
        self.base.camera.lookAt(self.target)

    def zoom(self, delta):
        self.r += delta * 0.2
        if self.r < 0.0:
            self.r = 0.0

    def _rotateTheta(self, dTheta):
        self.theta += dTheta
        if self.theta < 0.0:
            self.theta += 2 * math.pi
        if self.theta > 2 * math.pi:
            self.theta -= 2 * math.pi

    def _rotatePhi(self, dPhi):
        self.phi += dPhi
        if self.phi < 0.1:
            self.phi = 0.1
        if self.phi > math.pi - 0.1:
            self.phi = math.pi - 0.1

    def _rotatePhi_for_scroll(self, dPhi):
        self.phi += dPhi
        if self.phi < 0.1:
            self.phi = 0.1
        if self.phi > math.pi - 0.1:
            self.phi = self.phi - math.pi
示例#3
0
class TQGraphicsNodePath:
    """ Anything that fundamentally is a only a graphics object in this engine should have these properties.

    Kwargs:
        TQGraphicsNodePath_creation_parent_node : this is assigned in the constructor, and after makeObject and the return of
        the p3d Nodepath, each TQGraphicsNodePath object has to call set_p3d_node """

    def __init__(self, **kwargs):
        """ """
        self.TQGraphicsNodePath_creation_parent_node = None
        self.p3d_nodepath = NodePath("empty")
        self.p3d_nodepath_changed_post_init_p = False
        self.p3d_parent_nodepath = NodePath("empty")

        self.node_p3d = None

        self.p3d_nodepath.reparentTo(self.p3d_parent_nodepath)

        self.apply_kwargs(**kwargs)

    def apply_kwargs(self, **kwargs):
        """ """
        if 'color' in kwargs:
            TQGraphicsNodePath.setColor(self, kwargs.get('color'))
        else:
            TQGraphicsNodePath.setColor(self, Vec4(1., 1., 1., 1.))

    def attach_to_render(self):
        """ """
        # assert self.p3d_nodepath
        # self.p3d_nodepath.reparentTo(render)
        assert self.p3d_nodepath
        self.reparentTo(engine.tq_graphics_basics.tq_render)

    def attach_to_aspect2d(self):
        """ """
        # assert self.p3d_nodepath
        # self.p3d_nodepath.reparentTo(aspect2d)
        assert self.p3d_nodepath
        self.reparentTo(engine.tq_graphics_basics.tq_aspect2d)

    def _set_p3d_nodepath_plain_post_init(p3d_nodepath):
        """ """
        self.p3d_nodepath = p3d_nodepath
        self.p3d_nodepath_changed_post_init_p = True

    @staticmethod
    def from_p3d_nodepath(p3d_nodepath, **tq_graphics_nodepath_kwargs):
        """ factory """
        go = TQGraphicsNodePath(**tq_graphics_nodepath_kwargs)
        go.set_p3d_nodepath(p3d_nodepath)
        return go

    def set_parent_node_for_nodepath_creation(
            self, TQGraphicsNodePath_creation_parent_node):
        """ when calling attachNewNode_p3d, a new node pat is generated.
        E.g.: To attach a line to render (3d world) is different than attaching
        it to aspect2d (2d GUI plane), since the aspect2d children are not directly
        affected by camera movements
        Args:
        - TQGraphicsNodePath_creation_parent_node : the NodePath to attach the TQGraphicsNodePath to
                                          (e.g. render or aspect2d in p3d)
        """

        # self.set_parent_node_for_nodepath_creation(self.TQGraphicsNodePath_creation_parent_node)
        self.TQGraphicsNodePath_creation_parent_node = TQGraphicsNodePath_creation_parent_node

    def set_p3d_nodepath(self, p3d_nodepath, remove_old_nodepath=True):
        """ """
        self.p3d_nodepath = p3d_nodepath

    def get_p3d_nodepath(self):
        """ """
        return self.p3d_nodepath

    def set_render_above_all(self, p):
        """ set render order to be such that it renders normally (false), or above all (true)
        Args:
            p: True or False to enable or disable the 'above all' rendering mode """

        try:
            if p == True:
                self.p3d_nodepath.setBin("fixed", 0)
                self.p3d_nodepath.setDepthTest(False)
                self.p3d_nodepath.setDepthWrite(False)
            else:
                self.p3d_nodepath.setBin("default", 0)
                self.p3d_nodepath.setDepthTest(True)
                self.p3d_nodepath.setDepthWrite(True)
        except NameError:       # if p3d_nodepath is not yet defined
            print("NameError in set_render_above_all()")

    def remove(self):
        """ """
        self.p3d_nodepath.removeNode()

    def setPos(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setPos(*args, **kwargs)

    def getPos(self):
        """ """
        return self.p3d_nodepath.getPos()

    def setScale(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setScale(*args, **kwargs)

    def getScale(self):
        """ """
        return self.p3d_nodepath.getScale()

    def setMat(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setMat(*args, **kwargs)

    def setMat_normal(self, mat4x4_normal_np):
        """ normal convention (numpy array), i.e. convert to forrowvecs convention for p3d setMat call """
        return self.p3d_nodepath.setMat(math_utils.to_forrowvecs(mat4x4_normal_np))


    def getMat(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.getMat(*args, **kwargs)

    def getMat_normal(self, *args, **kwargs):
        """ """
        return math_utils.from_forrowvecs(self.p3d_nodepath.getMat(*args, **kwargs))

    def setTexture(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setTexture(*args, **kwargs)

    def setColor(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setColor(*args, **kwargs)

    def setTwoSided(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setTwoSided(*args, **kwargs)

    def setRenderModeWireframe(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setRenderModeWireframe(*args, **kwargs)

    def reparentTo(self, *args, **kwargs):
        """ """
        new_args = list(args)
        new_args[0] = new_args[0].p3d_nodepath
        return self.p3d_nodepath.reparentTo(*new_args, **kwargs)

    def reparentTo_p3d(self, *args, **kwargs):
        """ input a p3d nodepath directly """
        # new_args = list(args)
        # new_args[0] = new_args[0].p3d_nodepath
        return self.p3d_nodepath.reparentTo(*args, **kwargs)

    def get_node_p3d(self):
        """ """
        # return self.p3d_nodepath.node()
        return self.node_p3d

    def set_node_p3d(self, node_p3d):
        """ not available in p3d NodePath class """
        self.node_p3d = node_p3d

    def setRenderModeFilled(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setRenderModeFilled(*args, **kwargs)

    def setLightOff(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setLightOff(*args, **kwargs)

    def show(self):
        """ """
        return self.p3d_nodepath.show()

    def hide(self):
        """ """
        return self.p3d_nodepath.hide()

    def setRenderModeThickness(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setRenderModeThickness(*args, **kwargs)

    def removeNode(self):
        """ """
        return self.p3d_nodepath.removeNode()

    def setHpr(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setHpr(*args, **kwargs)

    def showBounds(self):
        """ """
        return self.p3d_nodepath.showBounds()

    def setCollideMask(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setCollideMask(*args, **kwargs)

    def getParent_p3d(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.getParent(*args, **kwargs)

    def wrtReparentTo(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.wrtReparentTo(*args, **kwargs)

    def setBin(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setBin(*args, **kwargs)

    def setDepthTest(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setDepthTest(*args, **kwargs)

    def setDepthWrite(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setDepthWrite(*args, **kwargs)

    def get_children_p3d(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.get_children(*args, **kwargs)

    def attachNewNode_p3d(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.attachNewNode(*args, **kwargs)

    def lookAt(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.lookAt(*args, **kwargs)

    def setLight(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setLight(*args, **kwargs)

    def setAntialias(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setAntialias(*args, **kwargs)

    def getRelativeVector(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.getRelativeVector(*args, **kwargs)

    def setTransparency(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setTransparency(*args, **kwargs)

    def getHpr(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.getHpr(*args, **kwargs)

    def setHpr(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.setHpr(*args, **kwargs)

    def getTightBounds(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.getTightBounds(*args, **kwargs)

    def showTightBounds(self, *args, **kwargs):
        """ """
        return self.p3d_nodepath.showTightBounds(*args, **kwargs)