| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- """
- Contains classes useful for 3D viewports.
- Originally written by pro-rsoft,
- Modified by gjeon.
- Modified by Summer 2010 Carnegie Mellon University ETC PandaLE team: fixed a bug in Viewport.Close
- """
- __all__ = ["Viewport", "ViewportManager"]
- from direct.showbase.DirectObject import DirectObject
- from direct.directtools.DirectGrid import DirectGrid
- from direct.showbase.ShowBase import WindowControls
- from direct.directtools.DirectGlobals import *
- from WxPandaWindow import WxPandaWindow
- from panda3d.core import OrthographicLens, Point3, Plane, CollisionPlane, CollisionNode, NodePath
- import wx
- HORIZONTAL = wx.SPLIT_HORIZONTAL
- VERTICAL = wx.SPLIT_VERTICAL
- CREATENEW = 99
- VPLEFT = 10
- VPFRONT = 11
- VPTOP = 12
- VPPERSPECTIVE = 13
- class ViewportManager:
- """Manages the global viewport stuff."""
- viewports = []
- gsg = None
- @staticmethod
- def initializeAll(*args, **kwargs):
- """Calls initialize() on all the viewports."""
- for v in ViewportManager.viewports:
- v.initialize(*args, **kwargs)
- @staticmethod
- def updateAll(*args, **kwargs):
- """Calls Update() on all the viewports."""
- for v in ViewportManager.viewports:
- v.Update(*args, **kwargs)
- @staticmethod
- def layoutAll(*args, **kwargs):
- """Calls Layout() on all the viewports."""
- for v in ViewportManager.viewports:
- v.Layout(*args, **kwargs)
- class Viewport(WxPandaWindow, DirectObject):
- """Class representing a 3D Viewport."""
- CREATENEW = CREATENEW
- VPLEFT = VPLEFT
- VPFRONT = VPFRONT
- VPTOP = VPTOP
- VPPERSPECTIVE = VPPERSPECTIVE
- def __init__(self, name, *args, **kwargs):
- self.name = name
- DirectObject.__init__(self)
- kwargs['gsg'] = ViewportManager.gsg
- WxPandaWindow.__init__(self, *args, **kwargs)
- ViewportManager.viewports.append(self)
- if ViewportManager.gsg == None:
- ViewportManager.gsg = self.win.getGsg()
- self.camera = None
- self.lens = None
- self.camPos = None
- self.camLookAt = None
- self.initialized = False
- self.grid = None
- self.collPlane = None
- def initialize(self):
- self.Update()
- if self.win:
- self.cam2d = base.makeCamera2d(self.win)
- self.cam2d.node().setCameraMask(LE_CAM_MASKS[self.name])
- self.cam = base.camList[-1]
- self.camera = render.attachNewNode(self.name)
- #self.camera.setName(self.name)
- #self.camera.reparentTo(render)
- self.cam.reparentTo(self.camera)
- self.camNode = self.cam.node()
- self.camNode.setCameraMask(LE_CAM_MASKS[self.name])
- self.bt = base.setupMouse(self.win, True)
- self.bt.node().setPrefix('_le_%s_'%self.name[:3])
- mw = self.bt.getParent()
- mk = mw.getParent()
- winCtrl = WindowControls(
- self.win, mouseWatcher=mw,
- cam=self.camera,
- camNode = self.camNode,
- cam2d=None,
- mouseKeyboard =mk,
- grid = self.grid)
- base.setupWindowControls(winCtrl)
- self.initialized = True
- if self.lens != None: self.cam.node().setLens(self.lens)
- if self.camPos != None: self.camera.setPos(self.camPos)
- if self.camLookAt != None: self.camera.lookAt(self.camLookAt)
- self.camLens = self.camNode.getLens()
- if self.name in ['top', 'front', 'left']:
- x = self.ClientSize.GetWidth() * 0.1
- y = self.ClientSize.GetHeight() * 0.1
- self.camLens.setFilmSize(x, y)
- self.Bind(wx.EVT_SIZE, self.onSize)
- ## self.accept("wheel_down", self.zoomOut)
- ## self.accept("wheel_up", self.zoomIn)
- ## self.accept("page_down", self.zoomOut)
- ## self.accept("page_down-repeat", self.zoomOut)
- ## self.accept("page_up", self.zoomIn)
- ## self.accept("page_up-repeat", self.zoomIn)
- #self.accept("mouse3", self.onRightDown)
- def Close(self):
- """Closes the viewport."""
- if self.initialized:
- wx.Window.Close(self)
- #base.closeWindow(self.win)
- ViewportManager.viewports.remove(self)
- def onSize(self, evt):
- """Invoked when the viewport is resized."""
- WxPandaWindow.onSize(self, evt)
- if self.win != None:
- newWidth = self.ClientSize.GetWidth()
- newHeight = self.ClientSize.GetHeight()
- if hasattr(base, "direct") and base.direct:
- for dr in base.direct.drList:
- if dr.camNode == self.camNode:
- dr.updateFilmSize(newWidth, newHeight)
- break
- def onRightDown(self, evt = None):
- """Invoked when the viewport is right-clicked."""
- if evt == None:
- mpos = wx.GetMouseState()
- mpos = self.ScreenToClient((mpos.x, mpos.y))
- else:
- mpos = evt.GetPosition()
- self.Update()
- #self.PopupMenu(self.menu, mpos)
- #self.menu.Destroy()
- def zoomOut(self):
- self.camera.setY(self.camera, -MOUSE_ZOO_SPEED)
- def zoomIn(self):
- self.camera.setY(self.camera, MOUSE_ZOOM_SPEED)
- @staticmethod
- def make(parent, vpType = None):
- """Safe constructor that also takes CREATENEW, VPLEFT, VPTOP, etc."""
- if vpType == None or vpType == CREATENEW:
- return Viewport(parent)
- if isinstance(vpType, Viewport): return vpType
- if vpType == VPLEFT: return Viewport.makeLeft(parent)
- if vpType == VPFRONT: return Viewport.makeFront(parent)
- if vpType == VPTOP: return Viewport.makeTop(parent)
- if vpType == VPPERSPECTIVE: return Viewport.makePerspective(parent)
- raise TypeError("Unknown viewport type: %s" % vpType)
- @staticmethod
- def makeOrthographic(parent, name, campos):
- v = Viewport(name, parent)
- v.lens = OrthographicLens()
- v.lens.setFilmSize(30)
- v.camPos = campos
- v.camLookAt = Point3(0, 0, 0)
- v.grid = DirectGrid(parent=render)
- if name == 'left':
- v.grid.setHpr(0, 0, 90)
- collPlane = CollisionNode('LeftGridCol')
- collPlane.addSolid(CollisionPlane(Plane(1, 0, 0, 0)))
- collPlane.setIntoCollideMask(BitMask32.bit(21))
- v.collPlane = NodePath(collPlane)
- v.collPlane.wrtReparentTo(v.grid)
- #v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_leftViewGridBack")
- LE_showInOneCam(v.grid, name)
- elif name == 'front':
- v.grid.setHpr(90, 0, 90)
- collPlane = CollisionNode('FrontGridCol')
- collPlane.addSolid(CollisionPlane(Plane(0, -1, 0, 0)))
- collPlane.setIntoCollideMask(BitMask32.bit(21))
- v.collPlane = NodePath(collPlane)
- v.collPlane.wrtReparentTo(v.grid)
- #v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_frontViewGridBack")
- LE_showInOneCam(v.grid, name)
- else:
- collPlane = CollisionNode('TopGridCol')
- collPlane.addSolid(CollisionPlane(Plane(0, 0, 1, 0)))
- collPlane.setIntoCollideMask(BitMask32.bit(21))
- v.collPlane = NodePath(collPlane)
- v.collPlane.reparentTo(v.grid)
- #v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_topViewGridBack")
- LE_showInOneCam(v.grid, name)
- return v
- @staticmethod
- def makePerspective(parent):
- v = Viewport('persp', parent)
- v.camPos = Point3(-19, -19, 19)
- v.camLookAt = Point3(0, 0, 0)
- v.grid = DirectGrid(parent=render)
- collPlane = CollisionNode('PerspGridCol')
- collPlane.addSolid(CollisionPlane(Plane(0, 0, 1, 0)))
- #oldBitmask = collPlane.getIntoCollideMask()
- #collPlane.setIntoCollideMask(BitMask32.bit(21)|oldBitmask)
- collPlane.setIntoCollideMask(BitMask32.bit(21))
- v.collPlane = NodePath(collPlane)
- v.collPlane.reparentTo(v.grid)
- collPlane2 = CollisionNode('PerspGridCol2')
- collPlane2.addSolid(CollisionPlane(Plane(0, 0, -1, 0)))
- #oldBitmask = collPlane2.getIntoCollideMask()
- #collPlane2.setIntoCollideMask(BitMask32.bit(21)|oldBitmask)
- collPlane2.setIntoCollideMask(BitMask32.bit(21))
- v.collPlane2 = NodePath(collPlane2)
- v.collPlane2.reparentTo(v.grid)
- #v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_perspViewGridBack")
- LE_showInOneCam(v.grid, 'persp')
- return v
- @staticmethod
- def makeLeft(parent): return Viewport.makeOrthographic(parent, 'left', Point3(600, 0, 0))
- @staticmethod
- def makeFront(parent): return Viewport.makeOrthographic(parent, 'front', Point3(0, -600, 0))
- @staticmethod
- def makeTop(parent): return Viewport.makeOrthographic(parent, 'top', Point3(0, 0, 600))
|