mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Polished multiview camera control
This commit is contained in:
parent
7f6b94eba1
commit
f9f5eeb85e
@ -19,7 +19,6 @@ class ActionMgr:
|
|||||||
self.undoList.append(action)
|
self.undoList.append(action)
|
||||||
if len(self.redoList) > 0:
|
if len(self.redoList) > 0:
|
||||||
self.redoList.pop()
|
self.redoList.pop()
|
||||||
print 'current undoList', self.undoList
|
|
||||||
|
|
||||||
def undo(self):
|
def undo(self):
|
||||||
if len(self.undoList) < 1:
|
if len(self.undoList) < 1:
|
||||||
@ -28,7 +27,6 @@ class ActionMgr:
|
|||||||
action = self.undoList.pop()
|
action = self.undoList.pop()
|
||||||
self.redoList.append(action)
|
self.redoList.append(action)
|
||||||
action.undo()
|
action.undo()
|
||||||
print 'current redoList', self.redoList
|
|
||||||
|
|
||||||
def redo(self):
|
def redo(self):
|
||||||
if len(self.redoList) < 1:
|
if len(self.redoList) < 1:
|
||||||
@ -37,7 +35,6 @@ class ActionMgr:
|
|||||||
action = self.redoList.pop()
|
action = self.redoList.pop()
|
||||||
self.undoList.append(action)
|
self.undoList.append(action)
|
||||||
action.redo()
|
action.redo()
|
||||||
print 'current undoList', self.undoList
|
|
||||||
|
|
||||||
class ActionBase(Functor):
|
class ActionBase(Functor):
|
||||||
""" Base class for user actions """
|
""" Base class for user actions """
|
||||||
|
@ -37,6 +37,7 @@ class LevelEditorBase(DirectObject):
|
|||||||
fTk = 0
|
fTk = 0
|
||||||
fWx = 0
|
fWx = 0
|
||||||
base.startDirect(fWantTk = fTk, fWantWx = fWx)
|
base.startDirect(fWantTk = fTk, fWantWx = fWx)
|
||||||
|
|
||||||
base.closeWindow(base.win)
|
base.closeWindow(base.win)
|
||||||
base.win = base.winList[3]
|
base.win = base.winList[3]
|
||||||
|
|
||||||
@ -101,6 +102,7 @@ class LevelEditorBase(DirectObject):
|
|||||||
base.direct.ignore('DIRECT-delete')
|
base.direct.ignore('DIRECT-delete')
|
||||||
base.direct.ignore('DIRECT-select')
|
base.direct.ignore('DIRECT-select')
|
||||||
base.direct.ignore('DIRECT-preDeselectAll')
|
base.direct.ignore('DIRECT-preDeselectAll')
|
||||||
|
base.direct.fIgnoreDirectOnlyKeyMap = 1
|
||||||
|
|
||||||
# [gjeon] do not use the old way of finding current DR
|
# [gjeon] do not use the old way of finding current DR
|
||||||
base.direct.drList.tryToGetCurrentDr = False
|
base.direct.drList.tryToGetCurrentDr = False
|
||||||
@ -221,7 +223,20 @@ class LevelEditorBase(DirectObject):
|
|||||||
base.direct.deselectAll()
|
base.direct.deselectAll()
|
||||||
self.objectMgr.reset()
|
self.objectMgr.reset()
|
||||||
self.actionMgr.reset()
|
self.actionMgr.reset()
|
||||||
|
self.ui.perspView.camera.setPos(-19, -19, 19)
|
||||||
|
self.ui.leftView.camera.setPos(600, 0, 0)
|
||||||
|
self.ui.frontView.camera.setPos(0, -600, 0)
|
||||||
|
self.ui.topView.camera.setPos(0, 0, 600)
|
||||||
|
self.resetOrthoCam(self.ui.topView)
|
||||||
|
self.resetOrthoCam(self.ui.frontView)
|
||||||
|
self.resetOrthoCam(self.ui.leftView)
|
||||||
|
|
||||||
|
def resetOrthoCam(self, view):
|
||||||
|
base.direct.drList[base.camList.index(NodePath(view.camNode))].orthoFactor = 0.1
|
||||||
|
x = view.ClientSize.GetWidth() * 0.1
|
||||||
|
y = view.ClientSize.GetHeight() * 0.1
|
||||||
|
view.camLens.setFilmSize(x, y)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
if self.currentFile:
|
if self.currentFile:
|
||||||
self.fileMgr.saveToFile(self.currentFile)
|
self.fileMgr.saveToFile(self.currentFile)
|
||||||
|
@ -34,25 +34,27 @@ class PandaTextDropTarget(wx.TextDropTarget):
|
|||||||
# create ray from the camera to detect 3d position
|
# create ray from the camera to detect 3d position
|
||||||
iRay = SelectionRay(self.view.camera)
|
iRay = SelectionRay(self.view.camera)
|
||||||
iRay.collider.setFromLens(self.view.camNode, mx, my)
|
iRay.collider.setFromLens(self.view.camNode, mx, my)
|
||||||
iRay.collideWithGeom()
|
iRay.collideWithBitMask(1)
|
||||||
iRay.ct.traverse(self.view.grid)
|
iRay.ct.traverse(self.view.collPlane)
|
||||||
entry = iRay.getEntry(0)
|
|
||||||
hitPt = entry.getSurfacePoint(entry.getFromNodePath())
|
|
||||||
|
|
||||||
# create a temp nodePath to get the position
|
if iRay.getNumEntries() > 0:
|
||||||
np = hidden.attachNewNode('temp')
|
entry = iRay.getEntry(0)
|
||||||
np.setPos(self.view.camera, hitPt)
|
hitPt = entry.getSurfacePoint(entry.getFromNodePath())
|
||||||
|
|
||||||
# update temp nodePath's HPR and scale with newobj's
|
# create a temp nodePath to get the position
|
||||||
np.setHpr(newobj.getHpr())
|
np = NodePath('temp')
|
||||||
np.setScale(newobj.getScale())
|
np.setPos(self.view.camera, hitPt)
|
||||||
|
|
||||||
# transform newobj to cursor position
|
# update temp nodePath's HPR and scale with newobj's
|
||||||
obj = self.editor.objectMgr.findObjectByNodePath(newobj)
|
np.setHpr(newobj.getHpr())
|
||||||
action = ActionTransformObj(self.editor, obj[OG.OBJ_UID], Mat4(np.getMat()))
|
np.setScale(newobj.getScale())
|
||||||
self.editor.actionMgr.push(action)
|
|
||||||
np.remove()
|
# transform newobj to cursor position
|
||||||
action()
|
obj = self.editor.objectMgr.findObjectByNodePath(newobj)
|
||||||
|
action = ActionTransformObj(self.editor, obj[OG.OBJ_UID], Mat4(np.getMat()))
|
||||||
|
self.editor.actionMgr.push(action)
|
||||||
|
np.remove()
|
||||||
|
action()
|
||||||
del iRay
|
del iRay
|
||||||
|
|
||||||
class LevelEditorUI(WxAppShell):
|
class LevelEditorUI(WxAppShell):
|
||||||
@ -292,14 +294,14 @@ class GridSizeUI(wx.Dialog):
|
|||||||
|
|
||||||
wx.StaticBox(panel, -1, 'Grid Size', (5, 5), (235, 80))
|
wx.StaticBox(panel, -1, 'Grid Size', (5, 5), (235, 80))
|
||||||
|
|
||||||
self.gridSizeSlider = WxSlider(panel, -1, float(gridSize), 10.0, 1000.0,
|
self.gridSizeSlider = WxSlider(panel, -1, float(gridSize), 10.0, 100000.0,
|
||||||
pos = (10, 25), size=(220, -1),
|
pos = (10, 25), size=(220, -1),
|
||||||
style=wx.SL_HORIZONTAL | wx.SL_LABELS)
|
style=wx.SL_HORIZONTAL | wx.SL_LABELS, textSize=(80,20))
|
||||||
self.gridSizeSlider.Enable()
|
self.gridSizeSlider.Enable()
|
||||||
|
|
||||||
wx.StaticBox(panel, -1, 'Grid Space', (5, 90), (235, 80))
|
wx.StaticBox(panel, -1, 'Grid Space', (5, 90), (235, 80))
|
||||||
|
|
||||||
self.gridSpacingSlider = WxSlider(panel, -1, float(gridSpacing), 0.01, 20.0,
|
self.gridSpacingSlider = WxSlider(panel, -1, float(gridSpacing), 0.01, 2000.0,
|
||||||
pos = (10, 115), size=(220, -1),
|
pos = (10, 115), size=(220, -1),
|
||||||
style=wx.SL_HORIZONTAL | wx.SL_LABELS)
|
style=wx.SL_HORIZONTAL | wx.SL_LABELS)
|
||||||
self.gridSpacingSlider.Enable()
|
self.gridSpacingSlider.Enable()
|
||||||
|
@ -90,13 +90,13 @@ class MayaConverter(wx.Dialog):
|
|||||||
|
|
||||||
if self.isAnim:
|
if self.isAnim:
|
||||||
if self.obj:
|
if self.obj:
|
||||||
command = 'maya2egg -a chan %s -o %s.anim.egg'%(mayaFile, mayaFile)
|
command = 'maya2egg -uo ft -a chan %s -o %s.anim.egg'%(mayaFile, mayaFile)
|
||||||
self.process = Process(self, command, lambda p0=None, p1=mayaFile: self.onProcessEnded(p0, p1))
|
self.process = Process(self, command, lambda p0=None, p1=mayaFile: self.onProcessEnded(p0, p1))
|
||||||
else:
|
else:
|
||||||
command = 'maya2egg -a model %s -o %s.model.egg'%(mayaFile, mayaFile)
|
command = 'maya2egg -uo ft -a model %s -o %s.model.egg'%(mayaFile, mayaFile)
|
||||||
self.process = Process(self, command, lambda p0=None, p1=mayaFile: self.onModelProcessEnded(p0, p1))
|
self.process = Process(self, command, lambda p0=None, p1=mayaFile: self.onModelProcessEnded(p0, p1))
|
||||||
else:
|
else:
|
||||||
command = 'maya2egg %s -o %s.egg'%(mayaFile, mayaFile)
|
command = 'maya2egg -uo ft %s -o %s.egg'%(mayaFile, mayaFile)
|
||||||
self.process = Process(self, command, lambda p0=None, p1=mayaFile: self.onProcessEnded(p0, p1))
|
self.process = Process(self, command, lambda p0=None, p1=mayaFile: self.onProcessEnded(p0, p1))
|
||||||
|
|
||||||
self.timer = wx.Timer(self, -1)
|
self.timer = wx.Timer(self, -1)
|
||||||
@ -113,7 +113,7 @@ class MayaConverter(wx.Dialog):
|
|||||||
for i in self.process.Poll():
|
for i in self.process.Poll():
|
||||||
self.output.AppendText(i)
|
self.output.AppendText(i)
|
||||||
self.process = None
|
self.process = None
|
||||||
command = 'maya2egg -a chan %s -o %s.anim.egg'%(mayaFile, mayaFile)
|
command = 'maya2egg -uo ft -a chan %s -o %s.anim.egg'%(mayaFile, mayaFile)
|
||||||
self.process = Process(self, command, lambda p0 = None, p1=mayaFile: self.onProcessEnded(p0, p1))
|
self.process = Process(self, command, lambda p0 = None, p1=mayaFile: self.onProcessEnded(p0, p1))
|
||||||
|
|
||||||
def onProcessEnded(self, evt, mayaFile):
|
def onProcessEnded(self, evt, mayaFile):
|
||||||
|
@ -292,7 +292,6 @@ class ObjectMgr:
|
|||||||
def setObjectTransform(self, uid, xformMat):
|
def setObjectTransform(self, uid, xformMat):
|
||||||
obj = self.findObjectById(uid)
|
obj = self.findObjectById(uid)
|
||||||
if obj:
|
if obj:
|
||||||
print obj[OG.OBJ_NP], xformMat
|
|
||||||
obj[OG.OBJ_NP].setMat(xformMat)
|
obj[OG.OBJ_NP].setMat(xformMat)
|
||||||
|
|
||||||
def updateObjectColor(self, r, g, b, a, np=None):
|
def updateObjectColor(self, r, g, b, a, np=None):
|
||||||
@ -601,6 +600,5 @@ class ObjectMgr:
|
|||||||
duplicatedNPs.append(newObjNP)
|
duplicatedNPs.append(newObjNP)
|
||||||
|
|
||||||
base.direct.deselectAllCB()
|
base.direct.deselectAllCB()
|
||||||
print duplicatedNPs
|
|
||||||
for newNodePath in duplicatedNPs:
|
for newNodePath in duplicatedNPs:
|
||||||
base.direct.select(newNodePath, fMultiSelect = 1, fUndo=0)
|
base.direct.select(newNodePath, fMultiSelect = 1, fUndo=0)
|
||||||
|
@ -11,7 +11,7 @@ from direct.showbase.DirectObject import DirectObject
|
|||||||
from direct.directtools.DirectGrid import DirectGrid
|
from direct.directtools.DirectGrid import DirectGrid
|
||||||
from direct.showbase.ShowBase import WindowControls
|
from direct.showbase.ShowBase import WindowControls
|
||||||
from direct.directtools.DirectGlobals import *
|
from direct.directtools.DirectGlobals import *
|
||||||
from pandac.PandaModules import WindowProperties, OrthographicLens, Point3
|
from pandac.PandaModules import WindowProperties, OrthographicLens, Point3, Plane, CollisionPlane, CollisionNode, NodePath
|
||||||
import wx
|
import wx
|
||||||
|
|
||||||
HORIZONTAL = wx.SPLIT_HORIZONTAL
|
HORIZONTAL = wx.SPLIT_HORIZONTAL
|
||||||
@ -65,6 +65,7 @@ class Viewport(wx.Panel, DirectObject):
|
|||||||
self.camLookAt = None
|
self.camLookAt = None
|
||||||
self.initialized = False
|
self.initialized = False
|
||||||
self.grid = None
|
self.grid = None
|
||||||
|
self.collPlane = None
|
||||||
#self.Bind(wx.EVT_RIGHT_DOWN, self.onRightDown)
|
#self.Bind(wx.EVT_RIGHT_DOWN, self.onRightDown)
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
@ -104,7 +105,8 @@ class Viewport(wx.Panel, DirectObject):
|
|||||||
cam=self.camera,
|
cam=self.camera,
|
||||||
camNode = self.camNode,
|
camNode = self.camNode,
|
||||||
cam2d=None,
|
cam2d=None,
|
||||||
mouseKeyboard =mk)
|
mouseKeyboard =mk,
|
||||||
|
grid = self.grid)
|
||||||
base.setupWindowControls(winCtrl)
|
base.setupWindowControls(winCtrl)
|
||||||
|
|
||||||
self.initialized = True
|
self.initialized = True
|
||||||
@ -114,7 +116,13 @@ class Viewport(wx.Panel, DirectObject):
|
|||||||
|
|
||||||
self.camLens = self.camNode.getLens()
|
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.Bind(wx.EVT_SIZE, self.onSize)
|
||||||
|
|
||||||
## self.accept("wheel_down", self.zoomOut)
|
## self.accept("wheel_down", self.zoomOut)
|
||||||
## self.accept("wheel_up", self.zoomIn)
|
## self.accept("wheel_up", self.zoomIn)
|
||||||
## self.accept("page_down", self.zoomOut)
|
## self.accept("page_down", self.zoomOut)
|
||||||
@ -186,13 +194,25 @@ class Viewport(wx.Panel, DirectObject):
|
|||||||
v.grid = DirectGrid(parent=render)
|
v.grid = DirectGrid(parent=render)
|
||||||
if name == 'left':
|
if name == 'left':
|
||||||
v.grid.setHpr(0, 0, 90)
|
v.grid.setHpr(0, 0, 90)
|
||||||
|
collPlane = CollisionNode('LeftGridCol')
|
||||||
|
collPlane.addSolid(CollisionPlane(Plane(1, 0, 0, 0)))
|
||||||
|
v.collPlane = NodePath(collPlane)
|
||||||
|
v.collPlane.wrtReparentTo(v.grid)
|
||||||
#v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_leftViewGridBack")
|
#v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_leftViewGridBack")
|
||||||
LE_showInOneCam(v.grid, name)
|
LE_showInOneCam(v.grid, name)
|
||||||
elif name == 'front':
|
elif name == 'front':
|
||||||
v.grid.setHpr(90, 0, 90)
|
v.grid.setHpr(90, 0, 90)
|
||||||
|
collPlane = CollisionNode('FrontGridCol')
|
||||||
|
collPlane.addSolid(CollisionPlane(Plane(0, -1, 0, 0)))
|
||||||
|
v.collPlane = NodePath(collPlane)
|
||||||
|
v.collPlane.wrtReparentTo(v.grid)
|
||||||
#v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_frontViewGridBack")
|
#v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_frontViewGridBack")
|
||||||
LE_showInOneCam(v.grid, name)
|
LE_showInOneCam(v.grid, name)
|
||||||
else:
|
else:
|
||||||
|
collPlane = CollisionNode('TopGridCol')
|
||||||
|
collPlane.addSolid(CollisionPlane(Plane(0, 0, 1, 0)))
|
||||||
|
v.collPlane = NodePath(collPlane)
|
||||||
|
v.collPlane.reparentTo(v.grid)
|
||||||
#v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_topViewGridBack")
|
#v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_topViewGridBack")
|
||||||
LE_showInOneCam(v.grid, name)
|
LE_showInOneCam(v.grid, name)
|
||||||
return v
|
return v
|
||||||
@ -200,20 +220,24 @@ class Viewport(wx.Panel, DirectObject):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def makePerspective(parent):
|
def makePerspective(parent):
|
||||||
v = Viewport('persp', parent)
|
v = Viewport('persp', parent)
|
||||||
v.camPos = Point3(-30, -30, 30)
|
v.camPos = Point3(-19, -19, 19)
|
||||||
v.camLookAt = Point3(0, 0, 0)
|
v.camLookAt = Point3(0, 0, 0)
|
||||||
|
|
||||||
v.grid = DirectGrid(parent=render)
|
v.grid = DirectGrid(parent=render)
|
||||||
|
collPlane = CollisionNode('PerspGridCol')
|
||||||
|
collPlane.addSolid(CollisionPlane(Plane(0, 0, 1, 0)))
|
||||||
|
v.collPlane = NodePath(collPlane)
|
||||||
|
v.collPlane.reparentTo(v.grid)
|
||||||
#v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_perspViewGridBack")
|
#v.grid.gridBack.findAllMatches("**/+GeomNode")[0].setName("_perspViewGridBack")
|
||||||
LE_showInOneCam(v.grid, 'persp')
|
LE_showInOneCam(v.grid, 'persp')
|
||||||
return v
|
return v
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def makeLeft(parent): return Viewport.makeOrthographic(parent, 'left', Point3(100, 0, 0))
|
def makeLeft(parent): return Viewport.makeOrthographic(parent, 'left', Point3(600, 0, 0))
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def makeFront(parent): return Viewport.makeOrthographic(parent, 'front', Point3(0, -100, 0))
|
def makeFront(parent): return Viewport.makeOrthographic(parent, 'front', Point3(0, -600, 0))
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def makeTop(parent): return Viewport.makeOrthographic(parent, 'top', Point3(0, 0, 100))
|
def makeTop(parent): return Viewport.makeOrthographic(parent, 'top', Point3(0, 0, 600))
|
||||||
|
|
||||||
class ViewportMenu(wx.Menu):
|
class ViewportMenu(wx.Menu):
|
||||||
"""Represents a menu that appears when right-clicking a viewport."""
|
"""Represents a menu that appears when right-clicking a viewport."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user