mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
Added support for multiple windows
This commit is contained in:
parent
8b77da64df
commit
0ad1e310d3
@ -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
|
||||
|
@ -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,9 +43,49 @@ 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
|
||||
self.mode = 'select'
|
||||
@ -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,10 +109,12 @@ 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):
|
||||
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,
|
||||
@ -82,6 +126,16 @@ class DirectManipulationControl(DirectObject):
|
||||
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,6 +202,111 @@ class DirectManipulationControl(DirectObject):
|
||||
skipFlags = self.defaultSkipFlags | self.optionalSkipFlags
|
||||
# Skip camera (and its children), unless control key is pressed
|
||||
skipFlags |= SKIP_CAMERA * (1 - base.getControl())
|
||||
|
||||
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
|
||||
@ -122,6 +318,7 @@ class DirectManipulationControl(DirectObject):
|
||||
base.direct.deselectAll()
|
||||
elif self.mode == 'move':
|
||||
self.manipulateObjectCleanup()
|
||||
|
||||
self.mode = None
|
||||
|
||||
def manipulateObjectCleanup(self):
|
||||
@ -161,6 +358,10 @@ class DirectManipulationControl(DirectObject):
|
||||
taskMgr.add(t, 'followSelectedNodePath')
|
||||
|
||||
def followSelectedNodePathTask(self, state):
|
||||
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
|
||||
|
||||
@ -293,12 +494,17 @@ 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 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)
|
||||
@ -362,6 +568,10 @@ class DirectManipulationControl(DirectObject):
|
||||
else:
|
||||
# Move widget to keep hit point as close to mouse as possible
|
||||
offset = self.hitPt - self.prevHit
|
||||
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):
|
||||
@ -378,6 +588,10 @@ class DirectManipulationControl(DirectObject):
|
||||
self.prevHit.assign(self.hitPt)
|
||||
else:
|
||||
offset = self.hitPt - self.prevHit
|
||||
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):
|
||||
@ -401,10 +615,22 @@ class DirectManipulationControl(DirectObject):
|
||||
if self.fWidgetTop:
|
||||
deltaAngle = -1 * deltaAngle
|
||||
if self.rotateAxis == 'x':
|
||||
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':
|
||||
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':
|
||||
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,7 +930,16 @@ class ObjectHandles(NodePath, DirectObject):
|
||||
|
||||
def toggleWidget(self):
|
||||
if self.fActive:
|
||||
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
|
||||
for widget in base.direct.manipulationControl.widgetList:
|
||||
widget.deactivate()
|
||||
else:
|
||||
self.deactivate()
|
||||
else:
|
||||
if hasattr(base.direct, "manipulationControl") and base.direct.manipulationControl.fMultiView:
|
||||
for widget in base.direct.manipulationControl.widgetList:
|
||||
widget.activate()
|
||||
widget.showWidgetIfActive()
|
||||
else:
|
||||
self.activate()
|
||||
|
||||
@ -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')
|
||||
|
@ -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)
|
||||
|
@ -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,6 +573,16 @@ class DirectSession(DirectObject):
|
||||
if not taskMgr.hasTaskNamed('resizeObjectHandles'):
|
||||
dnp = self.selected.last
|
||||
if dnp:
|
||||
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)
|
||||
@ -585,6 +602,10 @@ class DirectSession(DirectObject):
|
||||
self.selectedNPReadout.setText(
|
||||
'Selected:' + dnp.getName())
|
||||
# Show the manipulation widget
|
||||
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):
|
||||
@ -601,6 +622,10 @@ 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
|
||||
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
|
||||
@ -624,6 +649,10 @@ class DirectSession(DirectObject):
|
||||
dnp = self.selected.deselect(nodePath)
|
||||
if dnp:
|
||||
# Hide the manipulation widget
|
||||
if self.manipulationControl.fMultiView:
|
||||
for widget in self.manipulationControl.widgetList:
|
||||
widget.hideWidget()
|
||||
else:
|
||||
self.widget.hideWidget()
|
||||
self.selectedNPReadout.reparentTo(hidden)
|
||||
self.selectedNPReadout.setText(' ')
|
||||
@ -635,6 +664,10 @@ class DirectSession(DirectObject):
|
||||
def deselectAll(self):
|
||||
self.selected.deselectAll()
|
||||
# Hide the manipulation widget
|
||||
if self.manipulationControl.fMultiView:
|
||||
for widget in self.manipulationControl.widgetList:
|
||||
widget.hideWidget()
|
||||
else:
|
||||
self.widget.hideWidget()
|
||||
self.selectedNPReadout.reparentTo(hidden)
|
||||
self.selectedNPReadout.setText(' ')
|
||||
|
Loading…
x
Reference in New Issue
Block a user