Added ability to set color of selection box (if needed to be different than the default red).

This commit is contained in:
Justin Butler 2005-12-02 22:30:25 +00:00
parent e4c5381877
commit 12c5c4e0f3
3 changed files with 57 additions and 20 deletions

View File

@ -31,3 +31,10 @@ SKIP_BACKFACE = 2
SKIP_CAMERA = 4
SKIP_UNPICKABLE = 8
SKIP_ALL = SKIP_HIDDEN | SKIP_BACKFACE | SKIP_CAMERA | SKIP_UNPICKABLE
# bit flags for indicating how editable an object is
EDIT_TYPE_UNMOVABLE = 1
EDIT_TYPE_UNSCALABLE = 2
EDIT_TYPE_UNROTATABLE = 4
EDIT_TYPE_UNEDITABLE = EDIT_TYPE_UNMOVABLE | EDIT_TYPE_UNSCALABLE | EDIT_TYPE_UNROTATABLE

View File

@ -175,14 +175,34 @@ class DirectManipulationControl(PandaObject):
def removeManipulateObjectTask(self):
taskMgr.remove('manipulateObject')
#--------------------------------------------------------------------------
# Function: get edit types list for specified objects which indicate
# how editable the objects are
# Parameters: object, list of object to get edit types for
# Changes: none
# Returns: list of edit types
#--------------------------------------------------------------------------
def getEditTypes(self,objects):
# See if any of the selected in the don't manipulate tag list
editTypes = 0
for tag in self.unmovableTagList:
for selected in objects:
unmovableTag = selected.getTag(tag)
if (unmovableTag):
# check value of unmovableTag to see if it is
# completely uneditable or if it allows only certain
# types of editing
editTypes |= int(unmovableTag)
return editTypes
def manipulateObject(self):
# Only do this if something is selected
selectedList = direct.selected.getSelectedAsList()
# See if any of the selected in the don't manipulate tag list
for tag in self.unmovableTagList:
for selected in selectedList:
if selected.hasTag(tag):
return
# See if any of the selected are completely uneditable
editTypes = self.getEditTypes(selectedList)
if (editTypes & EDIT_TYPE_UNEDITABLE == EDIT_TYPE_UNEDITABLE):
return
self.currEditTypes = editTypes
if selectedList:
# Remove the task to keep the widget attached to the object
taskMgr.remove('followSelectedNodePath')
@ -234,11 +254,11 @@ class DirectManipulationControl(PandaObject):
# Widget takes precedence
if self.constraint:
type = self.constraint[2:]
if type == 'post':
if type == 'post' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
self.xlate1D(state)
elif type == 'disc':
elif type == 'disc' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
self.xlate2D(state)
elif type == 'ring':
elif type == 'ring' and not self.currEditTypes & EDIT_TYPE_UNROTATABLE:
self.rotate1D(state)
# No widget interaction, determine free manip mode
elif self.fFreeManip:
@ -247,17 +267,17 @@ class DirectManipulationControl(PandaObject):
self.objectHandles.transferObjectHandlesScale()
self.fScaling = 0
# Alt key switches to a scaling mode
if direct.fControl:
if direct.fControl and not self.currEditTypes & EDIT_TYPE_UNSCALABLE:
self.fScaling = 1
self.scale3D(state)
# Otherwise, manip mode depends on where you started
elif state.fMouseX and state.fMouseY:
elif state.fMouseX and state.fMouseY and not self.currEditTypes & EDIT_TYPE_UNROTATABLE:
# In the corner, spin around camera's axis
self.rotateAboutViewVector(state)
elif state.fMouseX or state.fMouseY:
elif state.fMouseX or state.fMouseY and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
# Mouse started elsewhere in the outer frame, rotate
self.rotate2D(state)
else:
elif not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
# Mouse started in central region, xlate
# Mode depends on shift key
if direct.fShift or direct.fControl:
@ -281,6 +301,7 @@ class DirectManipulationControl(PandaObject):
def removeTag(self, tag):
self.unmovableTagList.remove(tag)
### WIDGET MANIPULATION METHODS ###
def xlate1D(self, state):
# Constrained 1D Translation along widget axis
@ -962,4 +983,3 @@ class ObjectHandles(NodePath,PandaObject):
return self.hitPt

View File

@ -9,12 +9,12 @@ COA_CENTER = 1
# MRM: To do: handle broken node paths in selected and deselected dicts
class DirectNodePath(NodePath):
# A node path augmented with info, bounding box, and utility methods
def __init__(self, nodePath):
def __init__(self, nodePath, bboxColor=None):
# Initialize the superclass
NodePath.__init__(self)
self.assign(nodePath)
# Create a bounding box
self.bbox = DirectBoundingBox(self)
self.bbox = DirectBoundingBox(self, bboxColor)
center = self.bbox.getCenter()
# Create matrix to hold the offset between the nodepath
# and its center of action (COA)
@ -69,7 +69,7 @@ class SelectedNodePaths(PandaObject):
if not nodePath:
print 'Nothing selected!!'
return None
# Reset selected objects and highlight if multiSelect is false
if not fMultiSelect:
self.deselectAll()
@ -244,13 +244,13 @@ class SelectedNodePaths(PandaObject):
class DirectBoundingBox:
def __init__(self, nodePath):
def __init__(self, nodePath, bboxColor=None):
# Record the node path
self.nodePath = nodePath
# Compute bounds, min, max, etc.
self.computeTightBounds()
# Generate the bounding box
self.lines = self.createBBoxLines()
self.lines = self.createBBoxLines(bboxColor)
def recompute(self):
# Compute bounds, min, max, etc.
@ -285,11 +285,14 @@ class DirectBoundingBox:
self.min = Point3(self.center - Point3(self.radius))
self.max = Point3(self.center + Point3(self.radius))
def createBBoxLines(self):
def createBBoxLines(self, bboxColor=None):
# Create a line segments object for the bbox
lines = LineNodePath(hidden)
lines.node().setName('bboxLines')
lines.setColor(VBase4(1., 0., 0., 1.))
if (bboxColor):
lines.setColor(VBase4(*bboxColor))
else:
lines.setColor(VBase4(1., 0., 0., 1.))
lines.setThickness(0.5)
minX = self.min[0]
@ -329,6 +332,13 @@ class DirectBoundingBox:
return lines
def setBoxColorScale(self,r,g,b,a):
if (self.lines):
self.lines.reset()
self.lines = None
self.lines = self.createBBoxLines((r,g,b,a))
self.show()
def updateBBoxLines(self):
ls = self.lines.lineSegs