Added support for multiple windows

This commit is contained in:
Gyedo Jeon 2009-08-28 06:41:07 +00:00
parent 8b77da64df
commit 0ad1e310d3
4 changed files with 428 additions and 90 deletions

View File

@ -30,7 +30,8 @@ SKIP_HIDDEN = 1
SKIP_BACKFACE = 2
SKIP_CAMERA = 4
SKIP_UNPICKABLE = 8
SKIP_ALL = SKIP_HIDDEN | SKIP_BACKFACE | SKIP_CAMERA | SKIP_UNPICKABLE
SKIP_WIDGET = 16
SKIP_ALL = SKIP_HIDDEN | SKIP_BACKFACE | SKIP_CAMERA | SKIP_UNPICKABLE | SKIP_WIDGET
# bit flags for indicating how editable an object is
EDIT_TYPE_UNMOVABLE = 1

View File

@ -30,10 +30,12 @@ class DirectManipulationControl(DirectObject):
['DIRECT-mouse1', self.manipulationStart],
['DIRECT-mouse1Up', self.manipulationStop],
['tab', self.toggleObjectHandlesMode],
['.', self.objectHandles.multiplyScalingFactorBy, 2.0],
['>', self.objectHandles.multiplyScalingFactorBy, 2.0],
[',', self.objectHandles.multiplyScalingFactorBy, 0.5],
['<', self.objectHandles.multiplyScalingFactorBy, 0.5],
## ['.', self.objectHandles.multiplyScalingFactorBy, 2.0],
## ['>', self.objectHandles.multiplyScalingFactorBy, 2.0],
## [',', self.objectHandles.multiplyScalingFactorBy, 0.5],
## ['<', self.objectHandles.multiplyScalingFactorBy, 0.5],
['DIRECT-widgetScaleUp', self.scaleWidget, 2.0],
['DIRECT-widgetScaleDown', self.scaleWidget, 0.5],
['shift-f', self.objectHandles.growToFit],
['i', self.plantSelectedNodePath],
]
@ -41,8 +43,48 @@ class DirectManipulationControl(DirectObject):
self.optionalSkipFlags = 0
self.unmovableTagList = []
# [gjeon] to enable selection while other manipulation is disabled
# [gjeon] flag to enable selection while other manipulation is disabled
self.fAllowSelectionOnly = 0
# [gjeon] flag to enable marquee selection feature
self.fAllowMarquee = 0
self.marquee = None
# [gjeon] for new LE's multi-view support
self.fMultiView = 0
def scaleWidget(self, factor):
if hasattr(base.direct, 'widget'):
base.direct.widget.multiplyScalingFactorBy(factor)
else:
self.objectHandles.multiplyScalingFactorBy(factor)
def supportMultiView(self):
if self.fMultiView:
return
self.objectHandles.hide(BitMask32.bit(0))
self.objectHandles.hide(BitMask32.bit(1))
self.objectHandles.hide(BitMask32.bit(2))
self.topViewWidget = ObjectHandles('topViewWidget')
self.frontViewWidget = ObjectHandles('frontViewWidget')
self.leftViewWidget = ObjectHandles('leftViewWidget')
self.widgetList = [self.topViewWidget, self.frontViewWidget, self.leftViewWidget, self.objectHandles]
self.topViewWidget.hide(BitMask32.bit(1))
self.topViewWidget.hide(BitMask32.bit(2))
self.topViewWidget.hide(BitMask32.bit(3))
self.frontViewWidget.hide(BitMask32.bit(0))
self.frontViewWidget.hide(BitMask32.bit(2))
self.frontViewWidget.hide(BitMask32.bit(3))
self.leftViewWidget.hide(BitMask32.bit(0))
self.leftViewWidget.hide(BitMask32.bit(1))
self.leftViewWidget.hide(BitMask32.bit(3))
self.fMultiView = 1
def manipulationStart(self, modifiers):
# Start out in select mode
@ -55,7 +97,7 @@ class DirectManipulationControl(DirectObject):
return
# Check for a widget hit point
entry = base.direct.iRay.pickWidget()
entry = base.direct.iRay.pickWidget(skipFlags = SKIP_WIDGET)
# Did we hit a widget?
if entry:
# Yes!
@ -67,21 +109,33 @@ class DirectManipulationControl(DirectObject):
# Nope, off the widget, no constraint
self.constraint = None
# [gjeon] to prohibit unwanted object movement while direct window doesn't have focus
if base.direct.cameraControl.useMayaCamControls and not base.direct.gotControl(modifiers):
if base.direct.cameraControl.useMayaCamControls and not base.direct.gotControl(modifiers) \
and not self.fAllowMarquee:
return
if not base.direct.gotAlt(modifiers):
# Check to see if we are moving the object
# We are moving the object if we either wait long enough
taskMgr.doMethodLater(MANIPULATION_MOVE_DELAY,
self.switchToMoveMode,
'manip-move-wait')
# Or we move far enough
self.moveDir = None
watchMouseTask = Task.Task(self.watchMouseTask)
watchMouseTask.initX = base.direct.dr.mouseX
watchMouseTask.initY = base.direct.dr.mouseY
taskMgr.add(watchMouseTask, 'manip-watch-mouse')
if entry:
# Check to see if we are moving the object
# We are moving the object if we either wait long enough
taskMgr.doMethodLater(MANIPULATION_MOVE_DELAY,
self.switchToMoveMode,
'manip-move-wait')
# Or we move far enough
self.moveDir = None
watchMouseTask = Task.Task(self.watchMouseTask)
watchMouseTask.initX = base.direct.dr.mouseX
watchMouseTask.initY = base.direct.dr.mouseY
taskMgr.add(watchMouseTask, 'manip-watch-mouse')
else:
if base.direct.fControl:
self.mode = 'move'
self.manipulateObject()
elif not base.direct.fAlt and self.fAllowMarquee:
self.moveDir = None
watchMarqueeTask = Task.Task(self.watchMarqueeTask)
watchMarqueeTask.initX = base.direct.dr.mouseX
watchMarqueeTask.initY = base.direct.dr.mouseY
taskMgr.add(watchMarqueeTask, 'manip-marquee-mouse')
def switchToMoveMode(self, state):
taskMgr.remove('manip-watch-mouse')
@ -99,10 +153,47 @@ class DirectManipulationControl(DirectObject):
else:
return Task.cont
def watchMarqueeTask(self, state):
taskMgr.remove('manip-watch-mouse')
taskMgr.remove('manip-move-wait')
self.mode = 'select'
self.drawMarquee(state.initX, state.initY)
return Task.cont
def drawMarquee(self, startX, startY):
if self.marquee:
self.marquee.remove()
self.marquee = None
if base.direct.cameraControl.useMayaCamControls and base.direct.fAlt:
return
endX = base.direct.dr.mouseX
endY = base.direct.dr.mouseY
if (((abs (endX - startX)) < 0.01) and
((abs (endY - startY)) < 0.01)):
return
self.marquee = LineNodePath(render2d, 'marquee', 0.5, VBase4(.8, .6, .6, 1))
self.marqueeInfo = (startX, startY, endX, endY)
self.marquee.drawLines([
[(startX, 0, startY), (startX, 0, endY)],
[(startX, 0, endY), (endX, 0, endY)],
[(endX, 0, endY), (endX, 0, startY)],
[(endX, 0, startY), (startX, 0, startY)]])
self.marquee.create()
if self.fMultiView:
for i in range(4):
if i != base.camList.index(NodePath(base.direct.camNode)):
self.marquee.hide(BitMask32.bit(i))
def manipulationStop(self):
taskMgr.remove('manipulateObject')
taskMgr.remove('manip-move-wait')
taskMgr.remove('manip-watch-mouse')
taskMgr.remove('manip-marquee-mouse')
# depending on flag.....
if self.mode == 'select':
# Check for object under mouse
@ -111,17 +202,123 @@ class DirectManipulationControl(DirectObject):
skipFlags = self.defaultSkipFlags | self.optionalSkipFlags
# Skip camera (and its children), unless control key is pressed
skipFlags |= SKIP_CAMERA * (1 - base.getControl())
entry = base.direct.iRay.pickGeom(skipFlags = skipFlags)
if entry:
# Record hit point information
self.hitPt.assign(entry.getSurfacePoint(entry.getFromNodePath()))
self.hitPtDist = Vec3(self.hitPt).length()
# Select it
base.direct.select(entry.getIntoNodePath(), base.direct.fShift)
else:
if self.marquee:
self.marquee.remove()
self.marquee = None
base.direct.deselectAll()
startX = self.marqueeInfo[0]
startY = self.marqueeInfo[1]
endX = self.marqueeInfo[2]
endY = self.marqueeInfo[3]
fll = Point3(0, 0, 0)
flr = Point3(0, 0, 0)
fur = Point3(0, 0, 0)
ful = Point3(0, 0, 0)
nll = Point3(0, 0, 0)
nlr = Point3(0, 0, 0)
nur = Point3(0, 0, 0)
nul = Point3(0, 0, 0)
lens = base.direct.cam.node().getLens()
lens.extrude((startX, startY), nul, ful)
lens.extrude((endX, startY), nur, fur)
lens.extrude((endX, endY), nlr, flr)
lens.extrude((startX, endY), nll, fll)
marqueeFrustum = BoundingHexahedron(fll, flr, fur, ful, nll, nlr, nur, nul);
marqueeFrustum.xform(base.direct.cam.getNetTransform().getMat())
base.marqueeFrustum = marqueeFrustum
def findTaggedNodePath(nodePath):
# Select tagged object if present
for tag in base.direct.selected.tagList:
if nodePath.hasNetTag(tag):
nodePath = nodePath.findNetTag(tag)
return nodePath
return None
selectionList = []
for geom in render.findAllMatches("**/+GeomNode"):
if (skipFlags & SKIP_HIDDEN) and geom.isHidden():
# Skip if hidden node
continue
## elif (skipFlags & SKIP_BACKFACE) and base.direct.iRay.isEntryBackfacing():
## # Skip, if backfacing poly
## pass
elif ((skipFlags & SKIP_CAMERA) and
(camera in geom.getAncestors())):
# Skip if parented to a camera.
continue
# Can pick unpickable, use the first visible node
elif ((skipFlags & SKIP_UNPICKABLE) and
(geom.getName() in base.direct.iRay.unpickable)):
# Skip if in unpickable list
continue
nodePath = findTaggedNodePath(geom)
if nodePath in selectionList:
continue
bb = geom.getBounds()
bbc = bb.makeCopy()
bbc.xform(geom.getParent().getNetTransform().getMat())
boundingSphereTest = marqueeFrustum.contains(bbc)
if boundingSphereTest > 1:
if boundingSphereTest == 7:
print "boundingSphere is all in, selecting ", geom
if nodePath not in selectionList:
selectionList.append(nodePath)
else:
tMat = Mat4(geom.getMat())
geom.clearMat()
# Get bounds
min = Point3(0)
max = Point3(0)
geom.calcTightBounds(min, max)
# Restore transform
geom.setMat(tMat)
fll = Point3(min[0], max[1], min[2])
flr = Point3(max[0], max[1], min[2])
fur = max
ful = Point3(min[0], max[1], max[2])
nll = min
nlr = Point3(max[0], min[1], min[2])
nur = Point3(max[0], min[1], max[2])
nul = Point3(min[0], min[1], max[2])
tbb = BoundingHexahedron(fll, flr, fur, ful, nll, nlr, nur, nul)
tbb.xform(geom.getNetTransform().getMat())
tightBoundTest = marqueeFrustum.contains(tbb)
if tightBoundTest > 1:
if nodePath not in selectionList:
selectionList.append(nodePath)
for nodePath in selectionList:
base.direct.select(nodePath, 1)
else:
entry = base.direct.iRay.pickGeom(skipFlags = skipFlags)
if entry:
# Record hit point information
self.hitPt.assign(entry.getSurfacePoint(entry.getFromNodePath()))
self.hitPtDist = Vec3(self.hitPt).length()
# Select it
base.direct.select(entry.getIntoNodePath(), base.direct.fShift)
else:
base.direct.deselectAll()
elif self.mode == 'move':
self.manipulateObjectCleanup()
self.mode = None
def manipulateObjectCleanup(self):
@ -161,7 +358,11 @@ class DirectManipulationControl(DirectObject):
taskMgr.add(t, 'followSelectedNodePath')
def followSelectedNodePathTask(self, state):
base.direct.widget.setPosHpr(state.base, state.pos, state.hpr)
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
for widget in base.direct.manipulationControl.widgetList:
widget.setPosHpr(state.base, state.pos, state.hpr)
else:
base.direct.widget.setPosHpr(state.base, state.pos, state.hpr)
return Task.cont
def enableManipulation(self):
@ -293,17 +494,22 @@ class DirectManipulationControl(DirectObject):
# Widget takes precedence
if self.constraint:
type = self.constraint[2:]
if type == 'post' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
# [gjeon] to enable non-uniform scaling
if base.direct.fControl and not self.currEditTypes & EDIT_TYPE_UNSCALABLE:
if base.direct.fControl and not self.currEditTypes & EDIT_TYPE_UNSCALABLE:
if type == 'post':
# [gjeon] non-uniform scaling
self.fScaling = 1
self.scale1D(state)
else:
# [gjeon] uniform scaling
self.fScaling = 1
self.scale3D(state)
else:
if type == 'post' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
self.xlate1D(state)
elif type == 'disc' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
self.xlate2D(state)
elif type == 'ring' and not self.currEditTypes & EDIT_TYPE_UNROTATABLE:
self.rotate1D(state)
elif type == 'disc' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
self.xlate2D(state)
elif type == 'ring' and not self.currEditTypes & EDIT_TYPE_UNROTATABLE:
self.rotate1D(state)
# No widget interaction, determine free manip mode
elif self.fFreeManip:
# If we've been scaling and changed modes, reset object handles
@ -362,7 +568,11 @@ class DirectManipulationControl(DirectObject):
else:
# Move widget to keep hit point as close to mouse as possible
offset = self.hitPt - self.prevHit
base.direct.widget.setPos(base.direct.widget, offset)
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
for widget in base.direct.manipulationControl.widgetList:
widget.setPos(widget, offset)
else:
base.direct.widget.setPos(base.direct.widget, offset)
def xlate2D(self, state):
# Constrained 2D (planar) translation
@ -378,7 +588,11 @@ class DirectManipulationControl(DirectObject):
self.prevHit.assign(self.hitPt)
else:
offset = self.hitPt - self.prevHit
base.direct.widget.setPos(base.direct.widget, offset)
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
for widget in base.direct.manipulationControl.widgetList:
widget.setPos(widget, offset)
else:
base.direct.widget.setPos(base.direct.widget, offset)
def rotate1D(self, state):
# Constrained 1D rotation about the widget's main axis (X, Y, or Z)
@ -401,11 +615,23 @@ class DirectManipulationControl(DirectObject):
if self.fWidgetTop:
deltaAngle = -1 * deltaAngle
if self.rotateAxis == 'x':
base.direct.widget.setP(base.direct.widget, deltaAngle)
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
for widget in base.direct.manipulationControl.widgetList:
widget.setP(widget, deltaAngle)
else:
base.direct.widget.setP(base.direct.widget, deltaAngle)
elif self.rotateAxis == 'y':
base.direct.widget.setR(base.direct.widget, deltaAngle)
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
for widget in base.direct.manipulationControl.widgetList:
widget.setR(widget, deltaAngle)
else:
base.direct.widget.setR(base.direct.widget, deltaAngle)
elif self.rotateAxis == 'z':
base.direct.widget.setH(base.direct.widget, deltaAngle)
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
for widget in base.direct.manipulationControl.widgetList:
widget.setH(widget, deltaAngle)
else:
base.direct.widget.setH(base.direct.widget, deltaAngle)
# Record crank angle for next time around
self.lastCrankAngle = newAngle
@ -611,13 +837,13 @@ class DirectManipulationControl(DirectObject):
[base.direct.selected.getSelectedAsList()])
class ObjectHandles(NodePath, DirectObject):
def __init__(self):
def __init__(self, name='objectHandles'):
# Initialize the superclass
NodePath.__init__(self)
# Load up object handles model and assign it to self
self.assign(loader.loadModel('models/misc/objectHandles'))
self.setName('objectHandles')
self.setName(name)
self.scalingNode = self.getChild(0)
self.scalingNode.setName('ohScalingNode')
self.ohScalingFactor = 1.0
@ -668,6 +894,24 @@ class ObjectHandles(NodePath, DirectObject):
self.createGuideLines()
self.hideGuides()
# tag with name so they can skipped during iRay selection
self.xPostCollision.setTag('WidgetName',name)
self.yPostCollision.setTag('WidgetName',name)
self.zPostCollision.setTag('WidgetName',name)
self.xRingCollision.setTag('WidgetName',name)
self.yRingCollision.setTag('WidgetName',name)
self.zRingCollision.setTag('WidgetName',name)
self.xDiscCollision.setTag('WidgetName',name)
self.yDiscCollision.setTag('WidgetName',name)
self.zDiscCollision.setTag('WidgetName',name)
# name disc geoms so they can be added to unpickables
self.xDisc.find("**/+GeomNode").setName('x-disc-geom')
self.yDisc.find("**/+GeomNode").setName('y-disc-geom')
self.zDisc.find("**/+GeomNode").setName('z-disc-geom')
# Start with widget handles hidden
self.fActive = 1
self.toggleWidget()
@ -686,10 +930,19 @@ class ObjectHandles(NodePath, DirectObject):
def toggleWidget(self):
if self.fActive:
self.deactivate()
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
for widget in base.direct.manipulationControl.widgetList:
widget.deactivate()
else:
self.deactivate()
else:
self.activate()
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
for widget in base.direct.manipulationControl.widgetList:
widget.activate()
widget.showWidgetIfActive()
else:
self.activate()
def activate(self):
self.scalingNode.reparentTo(self)
self.fActive = 1
@ -697,7 +950,7 @@ class ObjectHandles(NodePath, DirectObject):
def deactivate(self):
self.scalingNode.reparentTo(hidden)
self.fActive = 0
def showWidgetIfActive(self):
if self.fActive:
self.reparentTo(base.direct.group)
@ -707,7 +960,7 @@ class ObjectHandles(NodePath, DirectObject):
def hideWidget(self):
self.reparentTo(hidden)
def enableHandles(self, handles):
if type(handles) == types.ListType:
for handle in handles:
@ -886,15 +1139,30 @@ class ObjectHandles(NodePath, DirectObject):
lines = LineNodePath(self.xPost)
lines.setColor(VBase4(1, 0, 0, 1))
lines.setThickness(5)
lines.moveTo(0, 0, 0)
lines.drawTo(1.5, 0, 0)
lines.create()
lines = LineNodePath(self.xPost)
lines.setColor(VBase4(1, 0, 0, 1))
lines.setThickness(1.5)
lines.moveTo(0, 0, 0)
#lines.moveTo(0, 0, 0)
#lines.drawTo(1.5, 0, 0)
lines.moveTo(1.5, 0, 0)
#lines.create()
#lines = LineNodePath(self.xPost)
#lines.setColor(VBase4(1, 0, 0, 1))
#lines.setThickness(1.5)
#lines.moveTo(0, 0, 0)
lines.drawTo(-1.5, 0, 0)
arrowInfo0 = 1.3
arrowInfo1 = 0.1
#lines.setThickness(5)
lines.moveTo(1.5, 0, 0)
lines.drawTo(arrowInfo0, arrowInfo1, arrowInfo1)
lines.moveTo(1.5, 0, 0)
lines.drawTo(arrowInfo0, arrowInfo1, -1 * arrowInfo1)
lines.moveTo(1.5, 0, 0)
lines.drawTo(arrowInfo0, -1 * arrowInfo1, arrowInfo1)
lines.moveTo(1.5, 0, 0)
lines.drawTo(arrowInfo0, -1 * arrowInfo1, -1 * arrowInfo1)
lines.create()
lines.setName('x-post-line')
# X ring
self.xRing = self.xRingGroup.attachNewNode('x-ring-visible')
@ -907,21 +1175,34 @@ class ObjectHandles(NodePath, DirectObject):
math.cos(deg2Rad(ang)),
math.sin(deg2Rad(ang)))
lines.create()
lines.setName('x-ring-line')
# Y post
self.yPost = self.yPostGroup.attachNewNode('y-post-visible')
lines = LineNodePath(self.yPost)
lines.setColor(VBase4(0, 1, 0, 1))
lines.setThickness(5)
lines.moveTo(0, 0, 0)
lines.drawTo(0, 1.5, 0)
lines.create()
lines = LineNodePath(self.yPost)
lines.setColor(VBase4(0, 1, 0, 1))
lines.setThickness(1.5)
lines.moveTo(0, 0, 0)
#lines.moveTo(0, 0, 0)
#lines.drawTo(0, 1.5, 0)
lines.moveTo(0, 1.5, 0)
#lines.create()
#lines = LineNodePath(self.yPost)
#lines.setColor(VBase4(0, 1, 0, 1))
#lines.setThickness(1.5)
#lines.moveTo(0, 0, 0)
lines.drawTo(0, -1.5, 0)
#lines.setThickness(5)
lines.moveTo(0, 1.5, 0)
lines.drawTo(arrowInfo1, arrowInfo0, arrowInfo1)
lines.moveTo(0, 1.5, 0)
lines.drawTo(arrowInfo1, arrowInfo0, -1 * arrowInfo1)
lines.moveTo(0, 1.5, 0)
lines.drawTo(-1 * arrowInfo1, arrowInfo0, arrowInfo1)
lines.moveTo(0, 1.5, 0)
lines.drawTo(-1 * arrowInfo1, arrowInfo0, -1 * arrowInfo1)
lines.create()
lines.setName('y-post-line')
# Y ring
self.yRing = self.yRingGroup.attachNewNode('y-ring-visible')
@ -934,21 +1215,35 @@ class ObjectHandles(NodePath, DirectObject):
0,
math.sin(deg2Rad(ang)))
lines.create()
lines.setName('y-ring-line')
# Z post
self.zPost = self.zPostGroup.attachNewNode('z-post-visible')
lines = LineNodePath(self.zPost)
lines.setColor(VBase4(0, 0, 1, 1))
lines.setThickness(5)
lines.moveTo(0, 0, 0)
lines.drawTo(0, 0, 1.5)
lines.create()
lines = LineNodePath(self.zPost)
lines.setColor(VBase4(0, 0, 1, 1))
lines.setThickness(1.5)
lines.moveTo(0, 0, 0)
#lines.moveTo(0, 0, 0)
#lines.drawTo(0, 0, 1.5)
lines.moveTo(0, 0, 1.5)
#lines.create()
#lines = LineNodePath(self.zPost)
#lines.setColor(VBase4(0, 0, 1, 1))
#lines.setThickness(1.5)
#lines.moveTo(0, 0, 0)
lines.drawTo(0, 0, -1.5)
#lines.setThickness(5)
lines.moveTo(0, 0, 1.5)
lines.drawTo(arrowInfo1, arrowInfo1, arrowInfo0)
lines.moveTo(0, 0, 1.5)
lines.drawTo(arrowInfo1, -1 * arrowInfo1, arrowInfo0)
lines.moveTo(0, 0, 1.5)
lines.drawTo(-1 * arrowInfo1, arrowInfo1, arrowInfo0)
lines.moveTo(0, 0, 1.5)
lines.drawTo(-1 * arrowInfo1, -1 * arrowInfo1, arrowInfo0)
lines.create()
lines.setName('z-post-line')
# Z ring
self.zRing = self.zRingGroup.attachNewNode('z-ring-visible')
@ -961,6 +1256,7 @@ class ObjectHandles(NodePath, DirectObject):
math.sin(deg2Rad(ang)),
0)
lines.create()
lines.setName('z-ring-line')
def createGuideLines(self):
self.guideLines = self.attachNewNode('guideLines')

View File

@ -560,6 +560,14 @@ class SelectionQueue(CollisionHandlerQueue):
(nodePath.getName() in self.unpickable)):
# Skip if in unpickable list
pass
elif ((skipFlags & SKIP_WIDGET) and
(nodePath.getTag('WidgetName') != base.direct.widget.getName())):
# Skip if this widget part is not belong to current widget
pass
elif ((skipFlags & SKIP_WIDGET) and base.direct.fControl and
(nodePath.getName()[2:] == 'ring')):
# Skip when ununiformly scale in ortho view
pass
else:
self.setCurrentIndex(i)
self.setCurrentEntry(entry)

View File

@ -156,6 +156,7 @@ class DirectSession(DirectObject):
['SGE_Fit', self.fitOnNodePath],
['SGE_Delete', self.removeNodePath],
['SGE_Set Name', self.getAndSetName],
['DIRECT-delete', self.removeAllSelected],
]
if base.wantTk:
@ -175,18 +176,22 @@ class DirectSession(DirectObject):
keyList.extend(map(chr, range(48, 58)))
keyList.extend(["`", "-", "=", "[", "]", ";", "'", ",", ".", "/", "\\"])
def addCtrl(a):
return "control-%s"%a
def addShift(a):
return "shift-%s"%a
self.keyList = keyList[:]
self.keyList.extend(map(addShift, keyList))
self.keyList.extend(['escape', 'delete', 'page_up', 'page_down'])
self.keyEvents = keyList[:]
self.keyEvents.extend(map(addCtrl, keyList))
self.keyEvents.extend(map(addShift, keyList))
self.keyEvents.extend(['escape', 'delete', 'page_up', 'page_down'])
self.keyEvents = ['escape', 'delete', 'page_up', 'page_down',
'[', '{', ']', '}',
'shift-a', 'b', 'control-f',
'l', 'shift-l', 'o', 'p', 'r',
'shift-r', 's', 't', 'v', 'w']
## self.keyEvents = ['escape', 'delete', 'page_up', 'page_down',
## '[', '{', ']', '}',
## 'shift-a', 'b', 'control-f',
## 'l', 'shift-l', 'o', 'p', 'r',
## 'shift-r', 's', 't', 'v', 'w']
self.mouseEvents = ['mouse1', 'mouse1-up',
'shift-mouse1', 'shift-mouse1-up',
'control-mouse1', 'control-mouse1-up',
@ -225,6 +230,9 @@ class DirectSession(DirectObject):
'+': 'DIRECT-zoomInCam',
'_': 'DIRECT-zoomOutCam',
'-': 'DIRECT-zoomOutCam',
'delete': 'DIRECT-delete',
'.': 'DIRECT-widgetScaleUp',
',': 'DIRECT-widgetScaleDown',
}
self.passThroughKeys = ['v','b','l','p', 'r', 'shift-r', 's', 't','shift-a', 'w']
@ -404,9 +412,6 @@ class DirectSession(DirectObject):
for event in self.keyEvents:
self.accept(event, self.inputHandler, [event])
for event in self.keyList:
self.accept(event, self.inputHandler, [event])
def enableMouseEvents(self):
for event in self.mouseEvents:
self.accept(event, self.inputHandler, [event])
@ -441,6 +446,8 @@ class DirectSession(DirectObject):
base.direct.iRay = base.direct.dr.iRay
base.mouseWatcher = winCtrl.mouseWatcher
base.mouseWatcherNode = winCtrl.mouseWatcher.node()
if base.direct.manipulationControl.fMultiView:
base.direct.widget = base.direct.manipulationControl.widgetList[base.camList.index(NodePath(winCtrl.camNode))]
break
# Deal with keyboard and mouse input
@ -491,8 +498,8 @@ class DirectSession(DirectObject):
self.downAncestry()
elif input == 'escape':
self.deselectAll()
elif input == 'delete':
self.removeAllSelected()
## elif input == 'delete':
## self.removeAllSelected()
elif input == 'v':
self.toggleWidgetVis()
elif input == 'b':
@ -566,9 +573,19 @@ class DirectSession(DirectObject):
if not taskMgr.hasTaskNamed('resizeObjectHandles'):
dnp = self.selected.last
if dnp:
nodeCamDist = Vec3(dnp.getPos(direct.camera)).length()
sf = 0.075 * nodeCamDist * math.tan(deg2Rad(direct.drList.getCurrentDr().fovV))
self.widget.setDirectScalingFactor(sf)
if self.manipulationControl.fMultiView:
for i in range(3):
sf = 30.0 * direct.drList[i].orthoFactor
self.manipulationControl.widgetList[i].setDirectScalingFactor(sf)
nodeCamDist = Vec3(dnp.getPos(base.camList[3])).length()
sf = 0.075 * nodeCamDist * math.tan(deg2Rad(direct.drList[3].fovV))
self.manipulationControl.widgetList[3].setDirectScalingFactor(sf)
else:
nodeCamDist = Vec3(dnp.getPos(direct.camera)).length()
sf = 0.075 * nodeCamDist * math.tan(deg2Rad(direct.drList.getCurrentDr().fovV))
self.widget.setDirectScalingFactor(sf)
return Task.cont
def select(self, nodePath, fMultiSelect = 0,
@ -585,7 +602,11 @@ class DirectSession(DirectObject):
self.selectedNPReadout.setText(
'Selected:' + dnp.getName())
# Show the manipulation widget
self.widget.showWidget()
if self.manipulationControl.fMultiView:
for widget in self.manipulationControl.widgetList:
widget.showWidget()
else:
self.widget.showWidget()
editTypes = self.manipulationControl.getEditTypes([dnp])
if (editTypes & EDIT_TYPE_UNEDITABLE == EDIT_TYPE_UNEDITABLE):
self.manipulationControl.disableWidgetMove()
@ -601,8 +622,12 @@ class DirectSession(DirectObject):
# This uses the additional scaling factor used to grow and
# shrink the widget
if not self.fScaleWidgetByCam: # [gjeon] for not scaling widget by distance from camera
self.widget.setScalingFactor(dnp.getRadius())
if self.manipulationControl.fMultiView:
for widget in self.manipulationControl.widgetList:
widget.setScalingFactor(dnp.getRadius())
else:
self.widget.setScalingFactor(dnp.getRadius())
# Spawn task to have object handles follow the selected object
taskMgr.remove('followSelectedNodePath')
t = Task.Task(self.followSelectedNodePathTask)
@ -624,7 +649,11 @@ class DirectSession(DirectObject):
dnp = self.selected.deselect(nodePath)
if dnp:
# Hide the manipulation widget
self.widget.hideWidget()
if self.manipulationControl.fMultiView:
for widget in self.manipulationControl.widgetList:
widget.hideWidget()
else:
self.widget.hideWidget()
self.selectedNPReadout.reparentTo(hidden)
self.selectedNPReadout.setText(' ')
taskMgr.remove('followSelectedNodePath')
@ -635,7 +664,11 @@ class DirectSession(DirectObject):
def deselectAll(self):
self.selected.deselectAll()
# Hide the manipulation widget
self.widget.hideWidget()
if self.manipulationControl.fMultiView:
for widget in self.manipulationControl.widgetList:
widget.hideWidget()
else:
self.widget.hideWidget()
self.selectedNPReadout.reparentTo(hidden)
self.selectedNPReadout.setText(' ')
taskMgr.remove('followSelectedNodePath')