mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Added ability to set color of selection box (if needed to be different than the default red).
This commit is contained in:
parent
e4c5381877
commit
12c5c4e0f3
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user