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_CAMERA = 4
SKIP_UNPICKABLE = 8 SKIP_UNPICKABLE = 8
SKIP_ALL = SKIP_HIDDEN | SKIP_BACKFACE | SKIP_CAMERA | SKIP_UNPICKABLE 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): def removeManipulateObjectTask(self):
taskMgr.remove('manipulateObject') 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): def manipulateObject(self):
# Only do this if something is selected # Only do this if something is selected
selectedList = direct.selected.getSelectedAsList() selectedList = direct.selected.getSelectedAsList()
# See if any of the selected in the don't manipulate tag list # See if any of the selected are completely uneditable
for tag in self.unmovableTagList: editTypes = self.getEditTypes(selectedList)
for selected in selectedList: if (editTypes & EDIT_TYPE_UNEDITABLE == EDIT_TYPE_UNEDITABLE):
if selected.hasTag(tag): return
return self.currEditTypes = editTypes
if selectedList: if selectedList:
# Remove the task to keep the widget attached to the object # Remove the task to keep the widget attached to the object
taskMgr.remove('followSelectedNodePath') taskMgr.remove('followSelectedNodePath')
@ -234,11 +254,11 @@ class DirectManipulationControl(PandaObject):
# Widget takes precedence # Widget takes precedence
if self.constraint: if self.constraint:
type = self.constraint[2:] type = self.constraint[2:]
if type == 'post': if type == 'post' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
self.xlate1D(state) self.xlate1D(state)
elif type == 'disc': elif type == 'disc' and not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
self.xlate2D(state) self.xlate2D(state)
elif type == 'ring': elif type == 'ring' and not self.currEditTypes & EDIT_TYPE_UNROTATABLE:
self.rotate1D(state) self.rotate1D(state)
# No widget interaction, determine free manip mode # No widget interaction, determine free manip mode
elif self.fFreeManip: elif self.fFreeManip:
@ -247,17 +267,17 @@ class DirectManipulationControl(PandaObject):
self.objectHandles.transferObjectHandlesScale() self.objectHandles.transferObjectHandlesScale()
self.fScaling = 0 self.fScaling = 0
# Alt key switches to a scaling mode # Alt key switches to a scaling mode
if direct.fControl: if direct.fControl and not self.currEditTypes & EDIT_TYPE_UNSCALABLE:
self.fScaling = 1 self.fScaling = 1
self.scale3D(state) self.scale3D(state)
# Otherwise, manip mode depends on where you started # 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 # In the corner, spin around camera's axis
self.rotateAboutViewVector(state) 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 # Mouse started elsewhere in the outer frame, rotate
self.rotate2D(state) self.rotate2D(state)
else: elif not self.currEditTypes & EDIT_TYPE_UNMOVABLE:
# Mouse started in central region, xlate # Mouse started in central region, xlate
# Mode depends on shift key # Mode depends on shift key
if direct.fShift or direct.fControl: if direct.fShift or direct.fControl:
@ -281,6 +301,7 @@ class DirectManipulationControl(PandaObject):
def removeTag(self, tag): def removeTag(self, tag):
self.unmovableTagList.remove(tag) self.unmovableTagList.remove(tag)
### WIDGET MANIPULATION METHODS ### ### WIDGET MANIPULATION METHODS ###
def xlate1D(self, state): def xlate1D(self, state):
# Constrained 1D Translation along widget axis # Constrained 1D Translation along widget axis
@ -962,4 +983,3 @@ class ObjectHandles(NodePath,PandaObject):
return self.hitPt return self.hitPt

View File

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